From: Mathieu Baudier Date: Mon, 4 Dec 2023 15:56:40 +0000 (+0100) Subject: Adapt to changes in Argeo TP X-Git-Tag: v2.3.24~15 X-Git-Url: https://git.argeo.org/?p=lgpl%2Fargeo-commons.git;a=commitdiff_plain;h=d17531647e0649199b3adf961be7fe81b34a4fd6 Adapt to changes in Argeo TP --- diff --git a/Makefile-rcp.mk b/Makefile-rcp.mk index 2cadd3ae7..1fb93728c 100644 --- a/Makefile-rcp.mk +++ b/Makefile-rcp.mk @@ -13,7 +13,7 @@ DEP_CATEGORIES = \ org.argeo.cms \ swt/org.argeo.cms \ org.argeo.tp \ -org.argeo.tp.jetty \ +org.argeo.tp.httpd \ osgi/equinox/org.argeo.tp.eclipse \ osgi/api/org.argeo.tp.osgi \ swt/rcp/org.argeo.tp.swt \ diff --git a/org.argeo.cms.ee/src/org/argeo/cms/integration/CmsExceptionsChain.java b/org.argeo.cms.ee/src/org/argeo/cms/integration/CmsExceptionsChain.java deleted file mode 100644 index 672722946..000000000 --- a/org.argeo.cms.ee/src/org/argeo/cms/integration/CmsExceptionsChain.java +++ /dev/null @@ -1,80 +0,0 @@ -package org.argeo.cms.integration; - -import java.io.IOException; -import java.io.Writer; - -import javax.servlet.http.HttpServletResponse; - -import org.argeo.api.cms.CmsLog; -import org.argeo.cms.util.ExceptionsChain; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; - -/** Serialisable wrapper of a {@link Throwable}. */ -public class CmsExceptionsChain extends ExceptionsChain { - public final static CmsLog log = CmsLog.getLog(CmsExceptionsChain.class); - - public CmsExceptionsChain() { - super(); - } - - public CmsExceptionsChain(Throwable exception) { - super(exception); - if (log.isDebugEnabled()) - log.error("Exception chain", exception); - } - - public String toJsonString(ObjectMapper objectMapper) { - try { - return objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(this); - } catch (JsonProcessingException e) { - throw new IllegalStateException("Cannot write system exceptions " + toString(), e); - } - } - - public void writeAsJson(ObjectMapper objectMapper, Writer writer) { - try { - JsonGenerator jg = objectMapper.writerWithDefaultPrettyPrinter().getFactory().createGenerator(writer); - jg.writeObject(this); - } catch (IOException e) { - throw new IllegalStateException("Cannot write system exceptions " + toString(), e); - } - } - - public void writeAsJson(ObjectMapper objectMapper, HttpServletResponse resp) { - try { - resp.setContentType("application/json"); - resp.setStatus(500); - writeAsJson(objectMapper, resp.getWriter()); - } catch (IOException e) { - throw new IllegalStateException("Cannot write system exceptions " + toString(), e); - } - } - -// public static void main(String[] args) throws Exception { -// try { -// try { -// try { -// testDeeper(); -// } catch (Exception e) { -// throw new Exception("Less deep exception", e); -// } -// } catch (Exception e) { -// throw new RuntimeException("Top exception", e); -// } -// } catch (Exception e) { -// CmsExceptionsChain systemErrors = new CmsExceptionsChain(e); -// ObjectMapper objectMapper = new ObjectMapper(); -// System.out.println(objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(systemErrors)); -// System.out.println(objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(e)); -// e.printStackTrace(); -// } -// } -// -// static void testDeeper() throws Exception { -// throw new IllegalStateException("Deep exception"); -// } - -} diff --git a/org.argeo.cms.ee/src/org/argeo/cms/integration/CmsLoginServlet.java b/org.argeo.cms.ee/src/org/argeo/cms/integration/CmsLoginServlet.java deleted file mode 100644 index 29a3137bb..000000000 --- a/org.argeo.cms.ee/src/org/argeo/cms/integration/CmsLoginServlet.java +++ /dev/null @@ -1,112 +0,0 @@ -package org.argeo.cms.integration; - -import java.io.IOException; -import java.util.Locale; -import java.util.Set; - -import javax.security.auth.Subject; -import javax.security.auth.callback.Callback; -import javax.security.auth.callback.NameCallback; -import javax.security.auth.callback.PasswordCallback; -import javax.security.auth.callback.UnsupportedCallbackException; -import javax.security.auth.login.LoginContext; -import javax.security.auth.login.LoginException; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.argeo.api.cms.CmsAuth; -import org.argeo.api.cms.CmsSessionId; -import org.argeo.cms.auth.RemoteAuthCallback; -import org.argeo.cms.auth.RemoteAuthCallbackHandler; -import org.argeo.cms.servlet.ServletHttpRequest; -import org.argeo.cms.servlet.ServletHttpResponse; -import org.osgi.service.useradmin.Authorization; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.ObjectMapper; - -/** Externally authenticate an http session. */ -public class CmsLoginServlet extends HttpServlet { - public final static String PARAM_USERNAME = "username"; - public final static String PARAM_PASSWORD = "password"; - - private static final long serialVersionUID = 2478080654328751539L; - private ObjectMapper objectMapper = new ObjectMapper(); - - @Override - protected void doGet(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - doPost(request, response); - } - - @Override - protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - LoginContext lc = null; - String username = req.getParameter(PARAM_USERNAME); - String password = req.getParameter(PARAM_PASSWORD); - ServletHttpRequest request = new ServletHttpRequest(req); - ServletHttpResponse response = new ServletHttpResponse(resp); - try { - lc = new LoginContext(CmsAuth.LOGIN_CONTEXT_USER, new RemoteAuthCallbackHandler(request, response) { - public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { - for (Callback callback : callbacks) { - if (callback instanceof NameCallback && username != null) - ((NameCallback) callback).setName(username); - else if (callback instanceof PasswordCallback && password != null) - ((PasswordCallback) callback).setPassword(password.toCharArray()); - else if (callback instanceof RemoteAuthCallback) { - ((RemoteAuthCallback) callback).setRequest(request); - ((RemoteAuthCallback) callback).setResponse(response); - } - } - } - }); - lc.login(); - - Subject subject = lc.getSubject(); - CmsSessionId cmsSessionId = extractFrom(subject.getPrivateCredentials(CmsSessionId.class)); - if (cmsSessionId == null) { - resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED); - return; - } - Authorization authorization = extractFrom(subject.getPrivateCredentials(Authorization.class)); - Locale locale = extractFrom(subject.getPublicCredentials(Locale.class)); - - CmsSessionDescriptor cmsSessionDescriptor = new CmsSessionDescriptor(authorization.getName(), - cmsSessionId.getUuid().toString(), authorization.getRoles(), authorization.toString(), - locale != null ? locale.toString() : null); - - resp.setContentType("application/json"); - JsonGenerator jg = objectMapper.getFactory().createGenerator(resp.getWriter()); - jg.writeObject(cmsSessionDescriptor); - - String redirectTo = redirectTo(req); - if (redirectTo != null) - resp.sendRedirect(redirectTo); - } catch (LoginException e) { - resp.setStatus(HttpServletResponse.SC_UNAUTHORIZED); - return; - } - } - - protected T extractFrom(Set creds) { - if (creds.size() > 0) - return creds.iterator().next(); - else - return null; - } - - /** - * To be overridden in order to return a richer {@link CmsSessionDescriptor} to - * be serialized. - */ - protected CmsSessionDescriptor enrichJson(CmsSessionDescriptor cmsSessionDescriptor) { - return cmsSessionDescriptor; - } - - protected String redirectTo(HttpServletRequest request) { - return null; - } -} diff --git a/org.argeo.cms.ee/src/org/argeo/cms/integration/CmsLogoutServlet.java b/org.argeo.cms.ee/src/org/argeo/cms/integration/CmsLogoutServlet.java deleted file mode 100644 index d18637d3f..000000000 --- a/org.argeo.cms.ee/src/org/argeo/cms/integration/CmsLogoutServlet.java +++ /dev/null @@ -1,79 +0,0 @@ -package org.argeo.cms.integration; - -import java.io.IOException; -import java.util.Set; - -import javax.security.auth.Subject; -import javax.security.auth.callback.Callback; -import javax.security.auth.callback.UnsupportedCallbackException; -import javax.security.auth.login.LoginContext; -import javax.security.auth.login.LoginException; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.argeo.api.cms.CmsAuth; -import org.argeo.api.cms.CmsSessionId; -import org.argeo.cms.CurrentUser; -import org.argeo.cms.auth.RemoteAuthCallback; -import org.argeo.cms.auth.RemoteAuthCallbackHandler; -import org.argeo.cms.servlet.ServletHttpRequest; -import org.argeo.cms.servlet.ServletHttpResponse; - -/** Externally authenticate an http session. */ -public class CmsLogoutServlet extends HttpServlet { - private static final long serialVersionUID = 2478080654328751539L; - - @Override - protected void doGet(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - doPost(request, response); - } - - @Override - protected void doPost(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - ServletHttpRequest httpRequest = new ServletHttpRequest(request); - ServletHttpResponse httpResponse = new ServletHttpResponse(response); - LoginContext lc = null; - try { - lc = new LoginContext(CmsAuth.LOGIN_CONTEXT_USER, - new RemoteAuthCallbackHandler(httpRequest, httpResponse) { - public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { - for (Callback callback : callbacks) { - if (callback instanceof RemoteAuthCallback) { - ((RemoteAuthCallback) callback).setRequest(httpRequest); - ((RemoteAuthCallback) callback).setResponse(httpResponse); - } - } - } - }); - lc.login(); - - Subject subject = lc.getSubject(); - CmsSessionId cmsSessionId = extractFrom(subject.getPrivateCredentials(CmsSessionId.class)); - if (cmsSessionId != null) {// logged in - CurrentUser.logoutCmsSession(subject); - } - - } catch (LoginException e) { - // ignore - } - - String redirectTo = redirectTo(request); - if (redirectTo != null) - response.sendRedirect(redirectTo); - } - - protected T extractFrom(Set creds) { - if (creds.size() > 0) - return creds.iterator().next(); - else - return null; - } - - protected String redirectTo(HttpServletRequest request) { - return null; - } -} diff --git a/org.argeo.cms.ee/src/org/argeo/cms/integration/CmsPrivateServletContext.java b/org.argeo.cms.ee/src/org/argeo/cms/integration/CmsPrivateServletContext.java deleted file mode 100644 index 09f17ae02..000000000 --- a/org.argeo.cms.ee/src/org/argeo/cms/integration/CmsPrivateServletContext.java +++ /dev/null @@ -1,80 +0,0 @@ -package org.argeo.cms.integration; - -import java.io.IOException; -import java.security.AccessControlContext; -import java.util.Map; - -import javax.security.auth.login.LoginContext; -import javax.security.auth.login.LoginException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.argeo.api.cms.CmsAuth; -import org.argeo.cms.auth.RemoteAuthCallbackHandler; -import org.argeo.cms.auth.RemoteAuthUtils; -import org.argeo.cms.servlet.ServletHttpRequest; -import org.argeo.cms.servlet.ServletHttpResponse; -import org.osgi.service.http.context.ServletContextHelper; - -/** Manages security access to servlets. */ -public class CmsPrivateServletContext extends ServletContextHelper { - public final static String LOGIN_PAGE = "argeo.cms.integration.loginPage"; - public final static String LOGIN_SERVLET = "argeo.cms.integration.loginServlet"; - private String loginPage; - private String loginServlet; - - public void init(Map properties) { - loginPage = properties.get(LOGIN_PAGE); - loginServlet = properties.get(LOGIN_SERVLET); - } - - /** - * Add the {@link AccessControlContext} as a request attribute, or redirect to - * the login page. - */ - @Override - public boolean handleSecurity(final HttpServletRequest req, HttpServletResponse resp) throws IOException { - LoginContext lc = null; - ServletHttpRequest request = new ServletHttpRequest(req); - ServletHttpResponse response = new ServletHttpResponse(resp); - - String pathInfo = req.getPathInfo(); - String servletPath = req.getServletPath(); - if ((pathInfo != null && (servletPath + pathInfo).equals(loginPage)) || servletPath.contentEquals(loginServlet)) - return true; - try { - lc = CmsAuth.USER.newLoginContext(new RemoteAuthCallbackHandler(request, response)); - lc.login(); - } catch (LoginException e) { - lc = processUnauthorized(req, resp); - if (lc == null) - return false; - } -// Subject.doAs(lc.getSubject(), new PrivilegedAction() { -// -// @Override -// public Void run() { -// // TODO also set login context in order to log out ? -// RemoteAuthUtils.configureRequestSecurity(request); -// return null; -// } -// -// }); - - return true; - } - -// @Override -// public void finishSecurity(HttpServletRequest req, HttpServletResponse resp) { -// RemoteAuthUtils.clearRequestSecurity(new ServletHttpRequest(req)); -// } - - protected LoginContext processUnauthorized(HttpServletRequest request, HttpServletResponse response) { - try { - response.sendRedirect(loginPage); - } catch (IOException e) { - throw new RuntimeException("Cannot redirect to login page", e); - } - return null; - } -} diff --git a/org.argeo.cms.ee/src/org/argeo/cms/integration/CmsSessionDescriptor.java b/org.argeo.cms.ee/src/org/argeo/cms/integration/CmsSessionDescriptor.java deleted file mode 100644 index 30de616a2..000000000 --- a/org.argeo.cms.ee/src/org/argeo/cms/integration/CmsSessionDescriptor.java +++ /dev/null @@ -1,96 +0,0 @@ -package org.argeo.cms.integration; - -import java.io.Serializable; -import java.util.Arrays; -import java.util.Collections; -import java.util.Set; -import java.util.TreeSet; - -import org.argeo.api.cms.CmsSession; -import org.osgi.service.useradmin.Authorization; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; - -/** A serializable descriptor of an internal {@link CmsSession}. */ -@JsonIgnoreProperties(ignoreUnknown = true) -public class CmsSessionDescriptor implements Serializable, Authorization { - private static final long serialVersionUID = 8592162323372641462L; - - private String name; - private String cmsSessionId; - private String displayName; - private String locale; - private Set roles; - - public CmsSessionDescriptor() { - } - - public CmsSessionDescriptor(String name, String cmsSessionId, String[] roles, String displayName, String locale) { - this.name = name; - this.displayName = displayName; - this.cmsSessionId = cmsSessionId; - this.locale = locale; - this.roles = Collections.unmodifiableSortedSet(new TreeSet<>(Arrays.asList(roles))); - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getDisplayName() { - return displayName; - } - - public void setDisplayName(String displayName) { - this.displayName = displayName; - } - - public String getCmsSessionId() { - return cmsSessionId; - } - - public void setCmsSessionId(String cmsSessionId) { - this.cmsSessionId = cmsSessionId; - } - - public Boolean isAnonymous() { - return name == null; - } - - public String getLocale() { - return locale; - } - - public void setLocale(String locale) { - this.locale = locale; - } - - @Override - public boolean hasRole(String name) { - return roles.contains(name); - } - - @Override - public String[] getRoles() { - return roles.toArray(new String[roles.size()]); - } - - public void setRoles(String[] roles) { - this.roles = Collections.unmodifiableSortedSet(new TreeSet<>(Arrays.asList(roles))); - } - - @Override - public int hashCode() { - return cmsSessionId != null ? cmsSessionId.hashCode() : super.hashCode(); - } - - @Override - public String toString() { - return displayName != null ? displayName : name != null ? name : super.toString(); - } - -} diff --git a/org.argeo.cms.ee/src/org/argeo/cms/integration/CmsTokenServlet.java b/org.argeo.cms.ee/src/org/argeo/cms/integration/CmsTokenServlet.java deleted file mode 100644 index c355ecd8d..000000000 --- a/org.argeo.cms.ee/src/org/argeo/cms/integration/CmsTokenServlet.java +++ /dev/null @@ -1,117 +0,0 @@ -package org.argeo.cms.integration; - -import java.io.IOException; -import java.time.ZonedDateTime; -import java.util.Set; -import java.util.UUID; - -import javax.security.auth.Subject; -import javax.security.auth.callback.Callback; -import javax.security.auth.callback.UnsupportedCallbackException; -import javax.security.auth.login.LoginContext; -import javax.security.auth.login.LoginException; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.argeo.api.acr.ldap.NamingUtils; -import org.argeo.api.cms.CmsAuth; -import org.argeo.api.cms.directory.CmsUserManager; -import org.argeo.cms.auth.RemoteAuthCallback; -import org.argeo.cms.auth.RemoteAuthCallbackHandler; -import org.argeo.cms.servlet.ServletHttpRequest; -import org.argeo.cms.servlet.ServletHttpResponse; -import org.osgi.service.useradmin.Authorization; - -import com.fasterxml.jackson.core.JsonGenerator; -import com.fasterxml.jackson.databind.ObjectMapper; - -/** Provides access to tokens. */ -public class CmsTokenServlet extends HttpServlet { - private static final long serialVersionUID = 302918711430864140L; - - public final static String PARAM_EXPIRY_DATE = "expiryDate"; - public final static String PARAM_TOKEN = "token"; - - private final static int DEFAULT_HOURS = 24; - - private CmsUserManager userManager; - private ObjectMapper objectMapper = new ObjectMapper(); - - @Override - protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - ServletHttpRequest request = new ServletHttpRequest(req); - ServletHttpResponse response = new ServletHttpResponse(resp); - LoginContext lc = null; - try { - lc = new LoginContext(CmsAuth.LOGIN_CONTEXT_USER, new RemoteAuthCallbackHandler(request, response) { - public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { - for (Callback callback : callbacks) { - if (callback instanceof RemoteAuthCallback) { - ((RemoteAuthCallback) callback).setRequest(request); - ((RemoteAuthCallback) callback).setResponse(response); - } - } - } - }); - lc.login(); - } catch (LoginException e) { - // ignore - } - - try { - Subject subject = lc.getSubject(); - Authorization authorization = extractFrom(subject.getPrivateCredentials(Authorization.class)); - String token = UUID.randomUUID().toString(); - String expiryDateStr = req.getParameter(PARAM_EXPIRY_DATE); - ZonedDateTime expiryDate; - if (expiryDateStr != null) { - expiryDate = NamingUtils.ldapDateToZonedDateTime(expiryDateStr); - } else { - expiryDate = ZonedDateTime.now().plusHours(DEFAULT_HOURS); - expiryDateStr = NamingUtils.instantToLdapDate(expiryDate); - } - userManager.addAuthToken(authorization.getName(), token, expiryDate); - - TokenDescriptor tokenDescriptor = new TokenDescriptor(); - tokenDescriptor.setUsername(authorization.getName()); - tokenDescriptor.setToken(token); - tokenDescriptor.setExpiryDate(expiryDateStr); -// tokenDescriptor.setRoles(Collections.unmodifiableSortedSet(new TreeSet<>(Arrays.asList(roles)))); - - resp.setContentType("application/json"); - JsonGenerator jg = objectMapper.getFactory().createGenerator(resp.getWriter()); - jg.writeObject(tokenDescriptor); - } catch (Exception e) { - new CmsExceptionsChain(e).writeAsJson(objectMapper, resp); - } - } - - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - // temporarily wrap POST for ease of testing - doPost(req, resp); - } - - @Override - protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - try { - String token = req.getParameter(PARAM_TOKEN); - userManager.expireAuthToken(token); - } catch (Exception e) { - new CmsExceptionsChain(e).writeAsJson(objectMapper, resp); - } - } - - protected T extractFrom(Set creds) { - if (creds.size() > 0) - return creds.iterator().next(); - else - return null; - } - - public void setUserManager(CmsUserManager userManager) { - this.userManager = userManager; - } -} diff --git a/org.argeo.cms.ee/src/org/argeo/cms/integration/TokenDescriptor.java b/org.argeo.cms.ee/src/org/argeo/cms/integration/TokenDescriptor.java deleted file mode 100644 index 1541b4f29..000000000 --- a/org.argeo.cms.ee/src/org/argeo/cms/integration/TokenDescriptor.java +++ /dev/null @@ -1,49 +0,0 @@ -package org.argeo.cms.integration; - -import java.io.Serializable; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; - -/** A serializable descriptor of a token. */ -@JsonIgnoreProperties(ignoreUnknown = true) -public class TokenDescriptor implements Serializable { - private static final long serialVersionUID = -6607393871416803324L; - - private String token; - private String username; - private String expiryDate; -// private Set roles; - - public String getToken() { - return token; - } - - public void setToken(String token) { - this.token = token; - } - - public String getUsername() { - return username; - } - - public void setUsername(String username) { - this.username = username; - } - -// public Set getRoles() { -// return roles; -// } -// -// public void setRoles(Set roles) { -// this.roles = roles; -// } - - public String getExpiryDate() { - return expiryDate; - } - - public void setExpiryDate(String expiryDate) { - this.expiryDate = expiryDate; - } - -} diff --git a/org.argeo.cms.ee/src/org/argeo/cms/integration/package-info.java b/org.argeo.cms.ee/src/org/argeo/cms/integration/package-info.java deleted file mode 100644 index 1405737ee..000000000 --- a/org.argeo.cms.ee/src/org/argeo/cms/integration/package-info.java +++ /dev/null @@ -1,2 +0,0 @@ -/** Argeo CMS integration (JSON, web services). */ -package org.argeo.cms.integration; \ No newline at end of file diff --git a/org.argeo.cms.ee/src/org/argeo/cms/websocket/server/EventEndpoint.java b/org.argeo.cms.ee/src/org/argeo/cms/websocket/server/EventEndpoint.java index defc59efc..c0dc97754 100644 --- a/org.argeo.cms.ee/src/org/argeo/cms/websocket/server/EventEndpoint.java +++ b/org.argeo.cms.ee/src/org/argeo/cms/websocket/server/EventEndpoint.java @@ -21,7 +21,7 @@ import org.osgi.framework.FrameworkUtil; @ServerEndpoint(value = "/cms/status/event/{topic}", configurator = CmsWebSocketConfigurator.class) public class EventEndpoint implements CmsEventSubscriber { private final static CmsLog log = CmsLog.getLog(EventEndpoint.class); - private BundleContext bc = FrameworkUtil.getBundle(TestEndpoint.class).getBundleContext(); + private BundleContext bc = FrameworkUtil.getBundle(EventEndpoint.class).getBundleContext(); private RemoteEndpoint.Basic remote; private CmsEventBus cmsEventBus; diff --git a/org.argeo.cms.ee/src/org/argeo/cms/websocket/server/StatusHandler.java b/org.argeo.cms.ee/src/org/argeo/cms/websocket/server/StatusHandler.java index a8466fee2..b385bf84d 100644 --- a/org.argeo.cms.ee/src/org/argeo/cms/websocket/server/StatusHandler.java +++ b/org.argeo.cms.ee/src/org/argeo/cms/websocket/server/StatusHandler.java @@ -22,7 +22,6 @@ public class StatusHandler implements WebsocketEndpoints, HttpHandler { Set> res = new HashSet<>(); res.add(PingEndpoint.class); res.add(EventEndpoint.class); - res.add(TestEndpoint.class); return res; } diff --git a/org.argeo.cms.ee/src/org/argeo/cms/websocket/server/TestEndpoint.java b/org.argeo.cms.ee/src/org/argeo/cms/websocket/server/TestEndpoint.java deleted file mode 100644 index f0c7fca3a..000000000 --- a/org.argeo.cms.ee/src/org/argeo/cms/websocket/server/TestEndpoint.java +++ /dev/null @@ -1,183 +0,0 @@ -package org.argeo.cms.websocket.server; - -import java.util.Hashtable; -import java.util.List; -import java.util.Map; - -import javax.security.auth.Subject; -import javax.websocket.CloseReason; -import javax.websocket.EndpointConfig; -import javax.websocket.OnClose; -import javax.websocket.OnError; -import javax.websocket.OnMessage; -import javax.websocket.OnOpen; -import javax.websocket.RemoteEndpoint; -import javax.websocket.Session; -import javax.websocket.server.PathParam; -import javax.websocket.server.ServerEndpoint; - -import org.argeo.api.acr.ldap.NamingUtils; -import org.argeo.api.cms.CmsLog; -import org.argeo.cms.integration.CmsExceptionsChain; -import org.osgi.framework.BundleContext; -import org.osgi.framework.FrameworkUtil; -import org.osgi.framework.ServiceRegistration; -import org.osgi.service.event.Event; -import org.osgi.service.event.EventConstants; -import org.osgi.service.event.EventHandler; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonMappingException; -import com.fasterxml.jackson.databind.ObjectMapper; - -/** Provides WebSocket access. */ -@ServerEndpoint(value = "/cms/status/test/{topic}", configurator = CmsWebSocketConfigurator.class) -public class TestEndpoint implements EventHandler { - private final static CmsLog log = CmsLog.getLog(TestEndpoint.class); - - final static String TOPICS_BASE = "/test"; - final static String INPUT = "input"; - final static String TOPIC = "topic"; - final static String VIEW_UID = "viewUid"; - final static String COMPUTATION_UID = "computationUid"; - final static String MESSAGES = "messages"; - final static String ERRORS = "errors"; - - final static String EXCEPTION = "exception"; - final static String MESSAGE = "message"; - - private BundleContext bc = FrameworkUtil.getBundle(TestEndpoint.class).getBundleContext(); - - private String wsSessionId; - private RemoteEndpoint.Basic remote; - private ServiceRegistration eventHandlerSr; - - // json - private ObjectMapper objectMapper = new ObjectMapper(); - - private WebSocketView view; - - @OnOpen - public void onOpen(Session session, EndpointConfig endpointConfig) { - Map> parameters = NamingUtils.queryToMap(session.getRequestURI()); - String path = NamingUtils.getQueryValue(parameters, "path"); - log.debug("WS Path: " + path); - - wsSessionId = session.getId(); - - // 24h timeout - session.setMaxIdleTimeout(1000 * 60 * 60 * 24); - - Map userProperties = session.getUserProperties(); - Subject subject = null; -// AccessControlContext accessControlContext = (AccessControlContext) userProperties -// .get(ServletContextHelper.REMOTE_USER); -// Subject subject = Subject.getSubject(accessControlContext); -// // Deal with authentication failure -// if (subject == null) { -// try { -// CloseReason.CloseCode closeCode = new CloseReason.CloseCode() { -// -// @Override -// public int getCode() { -// return 4001; -// } -// }; -// session.close(new CloseReason(closeCode, "Unauthorized")); -// if (log.isTraceEnabled()) -// log.trace("Unauthorized web socket " + wsSessionId + ". Closing with code " + closeCode.getCode() -// + "."); -// return; -// } catch (IOException e) { -// // silent -// } -// return;// ignore -// } - - if (log.isDebugEnabled()) - log.debug("WS#" + wsSessionId + " open for: " + subject); - remote = session.getBasicRemote(); - view = new WebSocketView(subject); - - // OSGi events - String[] topics = new String[] { TOPICS_BASE + "/*" }; - Hashtable ht = new Hashtable<>(); - ht.put(EventConstants.EVENT_TOPIC, topics); - ht.put(EventConstants.EVENT_FILTER, "(" + VIEW_UID + "=" + view.getUid() + ")"); - eventHandlerSr = bc.registerService(EventHandler.class, this, ht); - - if (log.isDebugEnabled()) - log.debug("New view " + view.getUid() + " opened, via web socket."); - } - - @OnMessage - public void onWebSocketText(@PathParam("topic") String topic, Session session, String message) - throws JsonMappingException, JsonProcessingException { - try { - if (log.isTraceEnabled()) - log.trace("WS#" + view.getUid() + " received:\n" + message + "\n"); -// JsonNode jsonNode = objectMapper.readTree(message); -// String topic = jsonNode.get(TOPIC).textValue(); - - final String computationUid = null; -// if (MY_TOPIC.equals(topic)) { -// view.checkRole(SPECIFIC_ROLE); -// computationUid= process(); -// } - remote.sendText("ACK " + topic); - } catch (Exception e) { - log.error("Error when receiving web socket message", e); - sendSystemErrorMessage(e); - } - } - - @OnClose - public void onWebSocketClose(CloseReason reason) { - if (eventHandlerSr != null) - eventHandlerSr.unregister(); - if (view != null && log.isDebugEnabled()) - log.debug("WS#" + view.getUid() + " closed: " + reason); - } - - @OnError - public void onWebSocketError(Throwable cause) { - if (view != null) { - log.error("WS#" + view.getUid() + " ERROR", cause); - } else { - if (log.isTraceEnabled()) - log.error("Error in web socket session " + wsSessionId, cause); - } - } - - @Override - public void handleEvent(Event event) { - try { - Object uid = event.getProperty(COMPUTATION_UID); - Exception exception = (Exception) event.getProperty(EXCEPTION); - if (exception != null) { - CmsExceptionsChain systemErrors = new CmsExceptionsChain(exception); - String sent = systemErrors.toJsonString(objectMapper); - remote.sendText(sent); - return; - } - String topic = event.getTopic(); - if (log.isTraceEnabled()) - log.trace("WS#" + view.getUid() + " " + topic + ": notify event " + topic + "#" + uid + ", " + event); - } catch (Exception e) { - log.error("Error when handling event for WebSocket", e); - sendSystemErrorMessage(e); - } - - } - - /** Sends an error message in JSON format. */ - protected void sendSystemErrorMessage(Exception e) { - CmsExceptionsChain systemErrors = new CmsExceptionsChain(e); - try { - if (remote != null) - remote.sendText(systemErrors.toJsonString(objectMapper)); - } catch (Exception e1) { - log.error("Cannot send WebSocket system error messages " + systemErrors, e1); - } - } -} diff --git a/org.argeo.cms.ux/src/org/argeo/cms/media/SvgToPng.java b/org.argeo.cms.ux/src/org/argeo/cms/media/SvgToPng.java deleted file mode 100644 index 852cb5221..000000000 --- a/org.argeo.cms.ux/src/org/argeo/cms/media/SvgToPng.java +++ /dev/null @@ -1,64 +0,0 @@ -package org.argeo.cms.media; - -import java.io.IOException; -import java.io.OutputStream; -import java.io.Reader; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; - -import org.apache.batik.transcoder.TranscoderException; -import org.apache.batik.transcoder.TranscoderInput; -import org.apache.batik.transcoder.TranscoderOutput; -import org.apache.batik.transcoder.image.ImageTranscoder; -import org.apache.batik.transcoder.image.PNGTranscoder; - -public class SvgToPng { - - public void convertSvgDir(Path sourceDir, Path targetDir, int width) { - System.out.println("##\n## " + width + "px - " + sourceDir + "\n##"); - try { - if (targetDir == null) - targetDir = sourceDir.getParent().resolve(Integer.toString(width)); - Files.createDirectories(targetDir); - - PNGTranscoder transcoder = new PNGTranscoder(); - // transcoder.addTranscodingHint(ImageTranscoder.KEY_BACKGROUND_COLOR, - // Color.WHITE); - transcoder.addTranscodingHint(PNGTranscoder.KEY_WIDTH, (float) width); - transcoder.addTranscodingHint(PNGTranscoder.KEY_HEIGHT, (float) width); - - for (Path source : Files.newDirectoryStream(sourceDir, "*.svg")) { - // FIXME extract base name - String baseName = null; // = FilenameUtils.getBaseName(source.toString()); - Path target = targetDir.resolve(baseName + ".png"); - convertSvgFile(transcoder, source, target); - } - } catch (IOException | TranscoderException e) { - throw new IllegalStateException("Cannot convert from " + sourceDir + " to " + targetDir, e); - } - - } - - protected void convertSvgFile(ImageTranscoder transcoder, Path source, Path target) - throws IOException, TranscoderException { - try (Reader reader = Files.newBufferedReader(source); OutputStream out = Files.newOutputStream(target);) { - TranscoderInput input = new TranscoderInput(reader); -// BufferedImage image = transcoder.createImage(32, 32); - TranscoderOutput output = new TranscoderOutput(out); - transcoder.transcode(input, output); - System.out.println(source.getFileName() + " -> " + target); - } - } - - public static void main(String[] args) throws Exception { - - Path path = Paths.get(args[0]); - - SvgToPng svgToPng = new SvgToPng(); - svgToPng.convertSvgDir(path, null, 16); - svgToPng.convertSvgDir(path, null, 32); - svgToPng.convertSvgDir(path, null, 64); - svgToPng.convertSvgDir(path, null, 96); - } -} diff --git a/osgi/equinox/org.argeo.cms.lib.equinox/src/org/argeo/cms/servlet/internal/jetty/JettyConfig.java b/osgi/equinox/org.argeo.cms.lib.equinox/src/org/argeo/cms/servlet/internal/jetty/JettyConfig.java index 2cd600152..71236ee1d 100644 --- a/osgi/equinox/org.argeo.cms.lib.equinox/src/org/argeo/cms/servlet/internal/jetty/JettyConfig.java +++ b/osgi/equinox/org.argeo.cms.lib.equinox/src/org/argeo/cms/servlet/internal/jetty/JettyConfig.java @@ -6,8 +6,6 @@ import java.util.Hashtable; import java.util.Map; import java.util.concurrent.ForkJoinPool; -import javax.websocket.DeploymentException; -import javax.websocket.server.ServerContainer; import javax.websocket.server.ServerEndpointConfig; import org.argeo.api.cms.CmsConstants; @@ -16,13 +14,10 @@ import org.argeo.api.cms.CmsState; import org.argeo.cms.CmsDeployProperty; import org.argeo.cms.util.LangUtils; import org.argeo.cms.websocket.server.CmsWebSocketConfigurator; -import org.argeo.cms.websocket.server.TestEndpoint; import org.eclipse.equinox.http.jetty.JettyConfigurator; import org.osgi.framework.BundleContext; import org.osgi.framework.Constants; import org.osgi.framework.FrameworkUtil; -import org.osgi.framework.ServiceReference; -import org.osgi.util.tracker.ServiceTracker; public class JettyConfig { private final static CmsLog log = CmsLog.getLog(JettyConfig.class); @@ -44,29 +39,29 @@ public class JettyConfig { startServer(properties); }); - ServiceTracker serverSt = new ServiceTracker( - bc, ServerContainer.class, null) { - - @Override - public ServerContainer addingService(ServiceReference reference) { - ServerContainer serverContainer = super.addingService(reference); - - BundleContext bc = reference.getBundle().getBundleContext(); - ServiceReference srConfigurator = bc - .getServiceReference(ServerEndpointConfig.Configurator.class); - ServerEndpointConfig.Configurator endpointConfigurator = bc.getService(srConfigurator); - ServerEndpointConfig config = ServerEndpointConfig.Builder - .create(TestEndpoint.class, "/ws/test/events/").configurator(endpointConfigurator).build(); - try { - serverContainer.addEndpoint(config); - } catch (DeploymentException e) { - throw new IllegalStateException("Cannot initalise the WebSocket server runtime.", e); - } - return serverContainer; - } - - }; - serverSt.open(); +// ServiceTracker serverSt = new ServiceTracker( +// bc, ServerContainer.class, null) { +// +// @Override +// public ServerContainer addingService(ServiceReference reference) { +// ServerContainer serverContainer = super.addingService(reference); +// +// BundleContext bc = reference.getBundle().getBundleContext(); +// ServiceReference srConfigurator = bc +// .getServiceReference(ServerEndpointConfig.Configurator.class); +// ServerEndpointConfig.Configurator endpointConfigurator = bc.getService(srConfigurator); +// ServerEndpointConfig config = ServerEndpointConfig.Builder +// .create(TestEndpoint.class, "/ws/test/events/").configurator(endpointConfigurator).build(); +// try { +// serverContainer.addEndpoint(config); +// } catch (DeploymentException e) { +// throw new IllegalStateException("Cannot initalise the WebSocket server runtime.", e); +// } +// return serverContainer; +// } +// +// }; +// serverSt.open(); // check initialisation // ServiceTracker httpSt = new ServiceTracker(bc, HttpService.class, null) { diff --git a/swt/org.argeo.cms.swt/src/org/argeo/cms/swt/osgi/BundleSvgTheme.java b/swt/org.argeo.cms.swt/src/org/argeo/cms/swt/osgi/BundleSvgTheme.java deleted file mode 100644 index 74de83e09..000000000 --- a/swt/org.argeo.cms.swt/src/org/argeo/cms/swt/osgi/BundleSvgTheme.java +++ /dev/null @@ -1,130 +0,0 @@ -package org.argeo.cms.swt.osgi; - -import java.awt.Color; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.lang.System.Logger; -import java.lang.System.Logger.Level; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; - -import org.apache.batik.transcoder.TranscoderException; -import org.apache.batik.transcoder.TranscoderInput; -import org.apache.batik.transcoder.TranscoderOutput; -import org.apache.batik.transcoder.image.ImageTranscoder; -import org.apache.batik.transcoder.image.PNGTranscoder; -import org.eclipse.swt.graphics.Image; -import org.eclipse.swt.graphics.ImageData; -import org.eclipse.swt.widgets.Display; -import org.osgi.framework.BundleContext; - -/** Theme which can dynamically create icons from SVG data. */ -public class BundleSvgTheme extends BundleCmsSwtTheme { - private final static Logger logger = System.getLogger(BundleSvgTheme.class.getName()); - - private Map> imageDataCache = Collections.synchronizedMap(new HashMap<>()); - - private Map transcoders = Collections.synchronizedMap(new HashMap<>()); - - private final static String IMAGE_CACHE_KEY = BundleSvgTheme.class.getName() + ".imageCache"; - - @Override - public Image getIcon(String name, Integer preferredSize) { - String path = "icons/types/svg/" + name + ".svg"; - return createImageFromSvg(path, preferredSize); - } - - @SuppressWarnings("unchecked") - protected Image createImageFromSvg(String path, Integer preferredSize) { - Display display = Display.getCurrent(); - Objects.requireNonNull(display, "Not a user interface thread"); - - Map> imageCache = (Map>) display - .getData(IMAGE_CACHE_KEY); - if (imageCache == null) - display.setData(IMAGE_CACHE_KEY, new HashMap>()); - imageCache = (Map>) display.getData(IMAGE_CACHE_KEY); - - Image image = null; - if (imageCache.containsKey(path)) { - image = imageCache.get(path).get(preferredSize); - } - if (image != null) - return image; - ImageData imageData = loadFromSvg(path, preferredSize); - image = new Image(display, imageData); - if (!imageCache.containsKey(path)) - imageCache.put(path, Collections.synchronizedMap(new HashMap<>())); - imageCache.get(path).put(preferredSize, image); - return image; - } - - protected ImageData loadFromSvg(String path, int size) { - ImageData imageData = null; - if (imageDataCache.containsKey(path)) - imageData = imageDataCache.get(path).get(size); - if (imageData != null) - return imageData; - - ImageTranscoder transcoder = null; - synchronized (this) { - transcoder = transcoders.get(size); - if (transcoder == null) { - transcoder = new PNGTranscoder(); - transcoder.addTranscodingHint(PNGTranscoder.KEY_WIDTH, (float) size); - transcoder.addTranscodingHint(PNGTranscoder.KEY_HEIGHT, (float) size); - transcoder.addTranscodingHint(PNGTranscoder.KEY_BACKGROUND_COLOR, new Color(255, 255, 255, 0)); - transcoders.put(size, transcoder); - } - } - try (InputStream in = getResourceAsStream(path); ByteArrayOutputStream out = new ByteArrayOutputStream();) { - if (in == null) - throw new IllegalArgumentException(path + " not found"); - TranscoderInput input = new TranscoderInput(in); - TranscoderOutput output = new TranscoderOutput(out); - transcoder.transcode(input, output); - try (InputStream imageIn = new ByteArrayInputStream(out.toByteArray())) { - imageData = new ImageData(imageIn); - } - logger.log(Level.DEBUG, () -> "Generated " + size + "x" + size + " PNG icon from " + path); - } catch (IOException | TranscoderException e) { - throw new RuntimeException("Cannot transcode SVG " + path, e); - } - - // cache it - if (!imageDataCache.containsKey(path)) - imageDataCache.put(path, Collections.synchronizedMap(new HashMap<>())); - imageDataCache.get(path).put(size, imageData); - - return imageData; - } - - @Override - public void init(BundleContext bundleContext, Map properties) { - super.init(bundleContext, properties); - - // preload all icons -// paths: for (String p : getImagesPaths()) { -// if (!p.endsWith(".svg")) -// continue paths; -// createImageFromSvg(p, getDefaultIconSize()); -// } - } - -// @Override -// public void destroy(BundleContext bundleContext, Map properties) { -// Display display = Display.getDefault(); -// if (display != null) -// for (String path : imageCache.keySet()) { -// for (Image image : imageCache.get(path).values()) { -// display.syncExec(() -> image.dispose()); -// } -// } -// super.destroy(bundleContext, properties); -// } - -} diff --git a/swt/rap/org.argeo.swt.specific.rap/src/org/argeo/eclipse/ui/specific/UiContext.java b/swt/rap/org.argeo.swt.specific.rap/src/org/argeo/eclipse/ui/specific/UiContext.java index 72e17a22d..a81d94d11 100644 --- a/swt/rap/org.argeo.swt.specific.rap/src/org/argeo/eclipse/ui/specific/UiContext.java +++ b/swt/rap/org.argeo.swt.specific.rap/src/org/argeo/eclipse/ui/specific/UiContext.java @@ -11,10 +11,12 @@ import org.eclipse.swt.widgets.Display; /** Singleton class providing single sources infos about the UI context. */ public class UiContext { /** Can be null, thus indicating that we are not in a web context. */ + @Deprecated public static HttpServletRequest getHttpRequest() { return RWT.getRequest(); } + @Deprecated public static HttpServletResponse getHttpResponse() { return RWT.getResponse(); } diff --git a/swt/rcp/org.argeo.swt.specific.rcp/src/org/argeo/eclipse/ui/specific/UiContext.java b/swt/rcp/org.argeo.swt.specific.rcp/src/org/argeo/eclipse/ui/specific/UiContext.java index 20163cffa..67b0e755c 100644 --- a/swt/rcp/org.argeo.swt.specific.rcp/src/org/argeo/eclipse/ui/specific/UiContext.java +++ b/swt/rcp/org.argeo.swt.specific.rcp/src/org/argeo/eclipse/ui/specific/UiContext.java @@ -10,10 +10,12 @@ import org.eclipse.swt.widgets.Display; /** Singleton class providing single sources infos about the UI context. */ public class UiContext { + @Deprecated public static HttpServletRequest getHttpRequest() { return null; } + @Deprecated public static HttpServletResponse getHttpResponse() { return null; }