You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ol...@apache.org on 2021/05/29 21:12:50 UTC
[sling-org-apache-sling-commons-crypto] branch master updated:
SLING-10438 Use Service ID instead of Component ID for Crypto Services in
Web Console plugin
This is an automated email from the ASF dual-hosted git repository.
olli pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-commons-crypto.git
The following commit(s) were added to refs/heads/master by this push:
new 651a927 SLING-10438 Use Service ID instead of Component ID for Crypto Services in Web Console plugin
651a927 is described below
commit 651a927d90933b06243130f93fef162de5b8a251
Author: Oliver Lietz <ol...@apache.org>
AuthorDate: Sat May 29 23:12:26 2021 +0200
SLING-10438 Use Service ID instead of Component ID for Crypto Services in Web Console plugin
---
pom.xml | 9 +-
.../crypto/internal/EncryptWebConsolePlugin.java | 27 ++---
.../crypto/it/tests/EncryptWebConsolePluginIT.java | 134 +++++++++++++++++++++
.../crypto/it/tests/ReversingCryptoService.java | 38 ++++++
4 files changed, 193 insertions(+), 15 deletions(-)
diff --git a/pom.xml b/pom.xml
index dbdd33c..862ac49 100644
--- a/pom.xml
+++ b/pom.xml
@@ -203,7 +203,14 @@
<scope>provided</scope>
<optional>true</optional>
</dependency>
- <!-- JSR 305-->
+ <!-- jsoup -->
+ <dependency>
+ <groupId>org.jsoup</groupId>
+ <artifactId>jsoup</artifactId>
+ <version>1.13.1</version>
+ <scope>test</scope>
+ </dependency>
+ <!-- nullability -->
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
diff --git a/src/main/java/org/apache/sling/commons/crypto/internal/EncryptWebConsolePlugin.java b/src/main/java/org/apache/sling/commons/crypto/internal/EncryptWebConsolePlugin.java
index 2a2435e..7d9009c 100644
--- a/src/main/java/org/apache/sling/commons/crypto/internal/EncryptWebConsolePlugin.java
+++ b/src/main/java/org/apache/sling/commons/crypto/internal/EncryptWebConsolePlugin.java
@@ -35,14 +35,13 @@ import org.apache.sling.commons.crypto.CryptoService;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.util.tracker.ServiceTracker;
-import static org.osgi.service.component.ComponentConstants.COMPONENT_ID;
-
@Component(
service = Servlet.class,
property = {
@@ -57,7 +56,7 @@ public class EncryptWebConsolePlugin extends HttpServlet {
private ServiceTracker<CryptoService, CryptoService> tracker;
- private static final String PARAMETER_ID = "id";
+ private static final String PARAMETER_SERVICE_ID = "service-id";
private static final String PARAMETER_MESSAGE = "message";
@@ -97,7 +96,7 @@ public class EncryptWebConsolePlugin extends HttpServlet {
if (Objects.nonNull(forwardRequestUri) && forwardRequestUri.equals(request.getRequestURI())) {
final String ciphertext = (String) request.getAttribute(ATTRIBUTE_CIPHERTEXT);
if (Objects.nonNull(ciphertext)) {
- final String html = String.format("<p>Encrypted message: %s</p>", ciphertext);
+ final String html = String.format("<p id=\"ciphertext\">Encrypted message: %s</p>", ciphertext);
writer.println(html);
}
}
@@ -106,19 +105,19 @@ public class EncryptWebConsolePlugin extends HttpServlet {
@Override
protected void doPost(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
request.removeAttribute(ATTRIBUTE_CIPHERTEXT);
- final String id = request.getParameter(PARAMETER_ID);
+ final String serviceId = request.getParameter(PARAMETER_SERVICE_ID);
final String message = request.getParameter(PARAMETER_MESSAGE); // do NOT log SECRET message
- if (Objects.isNull(id)) {
- handleParameterMissing(response, PARAMETER_ID);
+ if (Objects.isNull(serviceId)) {
+ handleParameterMissing(response, PARAMETER_SERVICE_ID);
return;
}
if (Objects.isNull(message)) {
handleParameterMissing(response, PARAMETER_MESSAGE);
return;
}
- final CryptoService cryptoService = findCryptoService(id);
+ final CryptoService cryptoService = findCryptoService(serviceId);
if (Objects.isNull(cryptoService)) {
- handleCryptoServiceNotFound(response, id);
+ handleCryptoServiceNotFound(response, serviceId);
return;
}
final String ciphertext = cryptoService.encrypt(message);
@@ -133,7 +132,7 @@ public class EncryptWebConsolePlugin extends HttpServlet {
}
private void handleCryptoServiceNotFound(final HttpServletResponse response, final String id) throws IOException {
- final String message = String.format("Crypto service with component id %s not found", id);
+ final String message = String.format("Crypto service with service id %s not found", id);
response.sendError(404, message);
}
@@ -146,12 +145,12 @@ public class EncryptWebConsolePlugin extends HttpServlet {
builder.append("<br>");
builder.append("<label>Available crypto services");
builder.append("<br>");
- builder.append("<select name=\"id\">");
+ builder.append("<select id=\"service-id\" name=\"service-id\">");
for (final ServiceReference<CryptoService> reference : references) {
- final String id = reference.getProperty(COMPONENT_ID).toString();
+ final String id = reference.getProperty(Constants.SERVICE_ID).toString();
final String[] names = (String[]) reference.getProperty("names");
final String algorithm = reference.getProperty("algorithm").toString();
- final String label = String.format("Component id %s, names: %s, algorithm: %s", id, Arrays.toString(names), algorithm);
+ final String label = String.format("Service id %s, names: %s, algorithm: %s", id, Arrays.toString(names), algorithm);
builder.append("<option value=\"").append(id).append("\">");
builder.append(label);
builder.append("</option>");
@@ -170,7 +169,7 @@ public class EncryptWebConsolePlugin extends HttpServlet {
return null;
}
for (final ServiceReference<CryptoService> reference : references) {
- if (id.equals(reference.getProperty(COMPONENT_ID).toString())) {
+ if (id.equals(reference.getProperty(Constants.SERVICE_ID).toString())) {
return bundleContext.getService(reference);
}
}
diff --git a/src/test/java/org/apache/sling/commons/crypto/it/tests/EncryptWebConsolePluginIT.java b/src/test/java/org/apache/sling/commons/crypto/it/tests/EncryptWebConsolePluginIT.java
new file mode 100644
index 0000000..8827162
--- /dev/null
+++ b/src/test/java/org/apache/sling/commons/crypto/it/tests/EncryptWebConsolePluginIT.java
@@ -0,0 +1,134 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.sling.commons.crypto.it.tests;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Base64;
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import javax.inject.Inject;
+
+import org.apache.sling.commons.crypto.CryptoService;
+import org.jsoup.Jsoup;
+import org.jsoup.nodes.Document;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.ops4j.pax.exam.Configuration;
+import org.ops4j.pax.exam.Option;
+import org.ops4j.pax.exam.junit.PaxExam;
+import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy;
+import org.ops4j.pax.exam.spi.reactors.PerMethod;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+
+import static com.google.common.truth.Truth.assertThat;
+import static org.apache.sling.testing.paxexam.SlingOptions.webconsole;
+import static org.ops4j.pax.exam.CoreOptions.mavenBundle;
+import static org.ops4j.pax.exam.CoreOptions.options;
+import static org.ops4j.pax.exam.cm.ConfigurationAdminOptions.newConfiguration;
+
+@RunWith(PaxExam.class)
+@ExamReactorStrategy(PerMethod.class)
+public class EncryptWebConsolePluginIT extends CryptoTestSupport {
+
+ private String url;
+
+ private CryptoService cryptoService = new ReversingCryptoService();
+
+ private ServiceRegistration<CryptoService> registration;
+
+ @Inject
+ private BundleContext bundleContext;
+
+ private static final String CREDENTIALS = new String(Base64.getEncoder().encode("admin:admin".getBytes()));
+
+ public EncryptWebConsolePluginIT() { //
+ }
+
+ private void registerCryptoService() {
+ final Dictionary<String, Object> properties = new Hashtable<>();
+ properties.put("names", new String[]{"reverse"});
+ properties.put("algorithm", "reverse");
+ registration = bundleContext.registerService(CryptoService.class, cryptoService, properties);
+ }
+
+ @Configuration
+ public Option[] configuration() {
+ final int httpPort = findFreePort();
+ return options(
+ baseConfiguration(),
+ newConfiguration("org.apache.felix.http")
+ .put("org.osgi.service.http.port", httpPort)
+ .asOption(),
+ webconsole(),
+ mavenBundle().groupId("org.jsoup").artifactId("jsoup").versionAsInProject()
+ );
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ url = String.format("http://localhost:%s/system/console/sling-commons-crypto-encrypt", httpPort());
+ registerCryptoService();
+ }
+
+ @Test
+ public void testGetFormNoCryptoServiceAvailable() throws IOException {
+ registration.unregister();
+ final Document document = Jsoup.connect(url)
+ .header("Authorization", String.format("Basic %s", CREDENTIALS))
+ .get();
+ assertThat(document.title()).isEqualTo("Apache Felix Web Console - Sling Commons Crypto Encrypt");
+ assertThat(document.getElementById("content").child(0).text()).isEqualTo("No crypto service available");
+ }
+
+ @Test
+ public void testGetFormCryptoServiceAvailable() throws IOException {
+ final ServiceReference<CryptoService> reference = registration.getReference();
+ final String id = reference.getProperty(Constants.SERVICE_ID).toString();
+ final String[] names = (String[]) reference.getProperty("names");
+ final String algorithm = reference.getProperty("algorithm").toString();
+ final String label = String.format("Service id %s, names: %s, algorithm: %s", id, Arrays.toString(names), algorithm);
+ final Document document = Jsoup.connect(url)
+ .header("Authorization", String.format("Basic %s", CREDENTIALS))
+ .get();
+ assertThat(document.title()).isEqualTo("Apache Felix Web Console - Sling Commons Crypto Encrypt");
+ assertThat(document.getElementById("service-id").child(0).text()).isEqualTo(label);
+ }
+
+ @Test
+ public void testEncrypt() throws IOException {
+ final ServiceReference<CryptoService> reference = registration.getReference();
+ final String id = reference.getProperty(Constants.SERVICE_ID).toString();
+ final String message = "Very secret message";
+ final String text = String.format("Encrypted message: %s", cryptoService.encrypt(message));
+ final Document document = Jsoup.connect(url)
+ .header("Authorization", String.format("Basic %s", CREDENTIALS))
+ .data("service-id", id)
+ .data("message", message)
+ .post();
+ assertThat(document.title()).isEqualTo("Apache Felix Web Console - Sling Commons Crypto Encrypt");
+ assertThat(document.getElementById("ciphertext").text()).isEqualTo(text);
+ }
+
+}
diff --git a/src/test/java/org/apache/sling/commons/crypto/it/tests/ReversingCryptoService.java b/src/test/java/org/apache/sling/commons/crypto/it/tests/ReversingCryptoService.java
new file mode 100644
index 0000000..3c30108
--- /dev/null
+++ b/src/test/java/org/apache/sling/commons/crypto/it/tests/ReversingCryptoService.java
@@ -0,0 +1,38 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.sling.commons.crypto.it.tests;
+
+import org.apache.sling.commons.crypto.CryptoService;
+import org.jetbrains.annotations.NotNull;
+
+public class ReversingCryptoService implements CryptoService {
+
+ @Override
+ public @NotNull String encrypt(@NotNull String message) {
+ final StringBuilder sb = new StringBuilder(message);
+ return sb.reverse().toString();
+ }
+
+ @Override
+ public @NotNull String decrypt(@NotNull String ciphertext) {
+ final StringBuilder sb = new StringBuilder(ciphertext);
+ return sb.reverse().toString();
+ }
+
+}