You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by cz...@apache.org on 2020/12/12 13:36:14 UTC
[felix-dev] branch master updated: FELIX-6370 : Provide a User
interface for checks within plugins
This is an automated email from the ASF dual-hosted git repository.
cziegeler pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/felix-dev.git
The following commit(s) were added to refs/heads/master by this push:
new 00be08c FELIX-6370 : Provide a User interface for checks within plugins
00be08c is described below
commit 00be08cb16669f34d763eb38b9fe11677504dbfe
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Sat Dec 12 14:36:19 2020 +0100
FELIX-6370 : Provide a User interface for checks within plugins
---
webconsole/changelog.txt | 1 +
webconsole/pom.xml | 21 +++-
.../java/org/apache/felix/webconsole/User.java | 53 +++++++++
.../webconsole/WebConsoleSecurityProvider.java | 2 +-
.../felix/webconsole/bundleinfo/package-info.java | 21 ++++
.../apache/felix/webconsole/i18n/package-info.java | 21 ++++
.../webconsole/internal/servlet/OsgiManager.java | 121 +++++++++------------
.../internal/servlet/OsgiManagerHttpContext.java | 80 ++++++++------
.../org/apache/felix/webconsole/package-info.java | 21 ++++
.../servlet/OsgiManagerHttpContextTest.java | 4 +-
.../internal/servlet/OsgiManagerTest.java | 5 +-
11 files changed, 241 insertions(+), 109 deletions(-)
diff --git a/webconsole/changelog.txt b/webconsole/changelog.txt
index 5330860..46194e1 100644
--- a/webconsole/changelog.txt
+++ b/webconsole/changelog.txt
@@ -3,6 +3,7 @@ Changes in 4.5.6
** Improvement
* [FELIX-6366] - Update to jQuery 3.5.1 and jQuery migrate 3.3.0
* [FELIX-6363] - Simplify updating of OSGi configurations through REST API
+ * [FELIX-6370] - Provide a User interface for checks within plugins
** Bug
* [FELIX-6341] - ConfigAdmin - deleting a configuration logs a string that should be translated
* [FELIX-6328] - Web Console (All In One) imports javax.portlet via fileupload
diff --git a/webconsole/pom.xml b/webconsole/pom.xml
index 065b29b..e4b272f 100644
--- a/webconsole/pom.xml
+++ b/webconsole/pom.xml
@@ -39,9 +39,9 @@
<properties>
<webconsole.exports>
- org.apache.felix.webconsole;version=3.3.0;provide:=true,
- org.apache.felix.webconsole.bundleinfo;version=1.0.0;provide:=true,
- org.apache.felix.webconsole.i18n;version=1.0.0;provide:=true
+ org.apache.felix.webconsole;provide:=true,
+ org.apache.felix.webconsole.bundleinfo;provide:=true,
+ org.apache.felix.webconsole.i18n;provide:=true
</webconsole.exports>
</properties>
@@ -145,6 +145,14 @@
</_removeheaders>
</instructions>
</configuration>
+ <executions>
+ <execution>
+ <id>baseline</id>
+ <goals>
+ <goal>baseline</goal>
+ </goals>
+ </execution>
+ </executions>
</plugin>
<plugin>
<artifactId>maven-javadoc-plugin</artifactId>
@@ -331,6 +339,13 @@
<dependencies>
<dependency>
+ <groupId>org.osgi</groupId>
+ <artifactId>org.osgi.annotation.versioning</artifactId>
+ <version>1.1.0</version>
+ <scope>provided</scope>
+ </dependency>
+
+ <dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.4</version>
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/User.java b/webconsole/src/main/java/org/apache/felix/webconsole/User.java
new file mode 100644
index 0000000..0e56790
--- /dev/null
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/User.java
@@ -0,0 +1,53 @@
+/*
+ * 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.felix.webconsole;
+
+import org.osgi.annotation.versioning.ProviderType;
+
+/**
+ * Representation of a user.
+ * The user object can be used by plugins to {@link #authorize(String)} the user.
+ * @since 3.4.0
+ */
+@ProviderType
+public interface User {
+
+ /**
+ * The name of the request attribute providing an object of this class
+ */
+ String USER_ATTRIBUTE = User.class.getName();
+
+ /**
+ * Return the user object.
+ * This method might return {@code null} if no web console security provider is configured and
+ * access to the console is allowed without authentication.
+ * This is the same value as the request attribute from {@link WebConsoleSecurityProvider2#USER_ATTRIBUTE}.
+ * @return The user object or {@code null}
+ */
+ Object getUserObject();
+
+
+ /**
+ * Checks whether the user has the given role permission.
+ *
+ * @param role The requested role
+ * @return {@code true} if the user is given permission for the given role.
+ */
+ boolean authorize( String role );
+}
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/WebConsoleSecurityProvider.java b/webconsole/src/main/java/org/apache/felix/webconsole/WebConsoleSecurityProvider.java
index fa62d5e..39b0e07 100644
--- a/webconsole/src/main/java/org/apache/felix/webconsole/WebConsoleSecurityProvider.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/WebConsoleSecurityProvider.java
@@ -44,7 +44,7 @@ public interface WebConsoleSecurityProvider
/**
- * Checks whether bthe authenticated user has the given role permission.
+ * Checks whether the authenticated user has the given role permission.
*
* @param user The object referring to the authenticated user. This is the
* object returned from the {@link #authenticate(String, String)}
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/bundleinfo/package-info.java b/webconsole/src/main/java/org/apache/felix/webconsole/bundleinfo/package-info.java
new file mode 100644
index 0000000..46d6e34
--- /dev/null
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/bundleinfo/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+@org.osgi.annotation.versioning.Version("1.0.0")
+package org.apache.felix.webconsole.bundleinfo;
+
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/i18n/package-info.java b/webconsole/src/main/java/org/apache/felix/webconsole/i18n/package-info.java
new file mode 100644
index 0000000..59cd5c3
--- /dev/null
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/i18n/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+@org.osgi.annotation.versioning.Version("1.0.0")
+package org.apache.felix.webconsole.i18n;
+
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java
index 28a46c6..548f53e 100644
--- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManager.java
@@ -53,6 +53,7 @@ import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.FilenameUtils;
import org.apache.felix.webconsole.AbstractWebConsolePlugin;
import org.apache.felix.webconsole.BrandingPlugin;
+import org.apache.felix.webconsole.User;
import org.apache.felix.webconsole.WebConsoleConstants;
import org.apache.felix.webconsole.WebConsoleSecurityProvider;
import org.apache.felix.webconsole.WebConsoleSecurityProvider2;
@@ -219,13 +220,13 @@ public class OsgiManager extends GenericServlet
private ServiceTracker brandingTracker;
- private ServiceTracker securityProviderTracker;
+ private ServiceTracker<WebConsoleSecurityProvider, WebConsoleSecurityProvider> securityProviderTracker;
private ServiceRegistration configurationListener;
// list of OsgiManagerPlugin instances activated during init. All these
// instances will have to be deactivated during destroy
- private List osgiManagerPlugins = new ArrayList();
+ private List<OsgiManagerPlugin> osgiManagerPlugins = new ArrayList<>();
private String webManagerRoot;
@@ -236,15 +237,15 @@ public class OsgiManager extends GenericServlet
private boolean httpResourcesRegistered;
// default configuration from framework properties
- private HashMap defaultConfiguration;
+ private Map<String, Object> defaultConfiguration;
// configuration from Configuration Admin
- private HashMap configuration;
+ private volatile Map<String, Object> configuration;
// See https://issues.apache.org/jira/browse/FELIX-2267
private Locale configuredLocale;
- private Set enabledPlugins;
+ private Set<String> enabledPlugins;
final ConcurrentSkipListSet<String> registeredSecurityProviders = new ConcurrentSkipListSet<String>();
@@ -277,13 +278,14 @@ public class OsgiManager extends GenericServlet
try
{
- Class pluginClass = classLoader.loadClass(pluginClassName);
- Object plugin = pluginClass.newInstance();
+ Class<?> pluginClass = classLoader.loadClass(pluginClassName);
+ Object plugin = pluginClass.getDeclaredConstructor(null).newInstance(null);
if (plugin instanceof OsgiManagerPlugin)
{
- ((OsgiManagerPlugin) plugin).activate(bundleContext);
- osgiManagerPlugins.add(plugin);
+ final OsgiManagerPlugin p = (OsgiManagerPlugin)plugin;
+ p.activate(bundleContext);
+ osgiManagerPlugins.add(p);
}
if (plugin instanceof BrandingPlugin)
{
@@ -332,13 +334,12 @@ public class OsgiManager extends GenericServlet
this.requiredSecurityProviders = splitCommaSeparatedString(bundleContext.getProperty(FRAMEWORK_PROP_SECURITY_PROVIDERS));
// add support for pluggable security
- securityProviderTracker = new ServiceTracker(bundleContext,
- WebConsoleSecurityProvider.class.getName(),
- new UpdateDependenciesStateCustomizer());
+ securityProviderTracker = new ServiceTracker<>(bundleContext, WebConsoleSecurityProvider.class,
+ new UpdateDependenciesStateCustomizer());
securityProviderTracker.open();
// load the default configuration from the framework
- this.defaultConfiguration = new HashMap();
+ this.defaultConfiguration = new HashMap<>();
this.defaultConfiguration.put( PROP_MANAGER_ROOT,
ConfigurationUtil.getProperty( bundleContext, FRAMEWORK_PROP_MANAGER_ROOT, DEFAULT_MANAGER_ROOT ) );
this.defaultConfiguration.put( PROP_REALM,
@@ -348,7 +349,7 @@ public class OsgiManager extends GenericServlet
this.defaultConfiguration.put( PROP_PASSWORD,
ConfigurationUtil.getProperty( bundleContext, FRAMEWORK_PROP_PASSWORD, DEFAULT_PASSWORD ) );
this.defaultConfiguration.put( PROP_LOG_LEVEL,
- new Integer( ConfigurationUtil.getProperty( bundleContext, FRAMEWORK_PROP_LOG_LEVEL, DEFAULT_LOG_LEVEL ) ) );
+ ConfigurationUtil.getProperty( bundleContext, FRAMEWORK_PROP_LOG_LEVEL, DEFAULT_LOG_LEVEL ) );
this.defaultConfiguration.put( PROP_LOCALE,
ConfigurationUtil.getProperty( bundleContext, FRAMEWORK_PROP_LOCALE, null ) );
@@ -386,7 +387,7 @@ public class OsgiManager extends GenericServlet
{
// do nothing
}
- }, new Hashtable()
+ }, new Hashtable<String, Object>()
{
{
put( Constants.SERVICE_VENDOR, "The Apache Software Foundation" ); //$NON-NLS-1$
@@ -431,10 +432,10 @@ public class OsgiManager extends GenericServlet
}
// deactivate any remaining plugins
- for (Iterator pi = osgiManagerPlugins.iterator(); pi.hasNext();)
+ for (Iterator<OsgiManagerPlugin> pi = osgiManagerPlugins.iterator(); pi.hasNext();)
{
- Object plugin = pi.next();
- ((OsgiManagerPlugin) plugin).deactivate();
+ OsgiManagerPlugin plugin = pi.next();
+ plugin.deactivate();
}
// simply remove all operations, we should not be used anymore
@@ -487,7 +488,7 @@ public class OsgiManager extends GenericServlet
// don't really expect to be called within a non-HTTP environment
try
{
- AccessController.doPrivileged(new PrivilegedExceptionAction()
+ AccessController.doPrivileged(new PrivilegedExceptionAction<Object>()
{
public Object run() throws Exception
{
@@ -648,7 +649,7 @@ public class OsgiManager extends GenericServlet
// check for basic authentication
String auth = request.getHeader(HEADER_AUTHORIZATION); //$NON-NLS-1$
if (null != auth && auth.toLowerCase().startsWith("basic ")) { //$NON-NLS-1$
- Map config = getConfiguration();
+ Map<String, Object> config = getConfiguration();
String realm = ConfigurationUtil.getProperty(config, PROP_REALM, DEFAULT_REALM);
response.setHeader(HEADER_WWW_AUTHENTICATE, "Basic realm=\"" + realm + "\""); //$NON-NLS-1$ //$NON-NLS-2$
response.addCookie(new Cookie("logout", "true")); //$NON-NLS-1$ //$NON-NLS-2$
@@ -660,6 +661,7 @@ public class OsgiManager extends GenericServlet
request.removeAttribute(HttpContext.REMOTE_USER);
request.removeAttribute(HttpContext.AUTHORIZATION);
request.removeAttribute(WebConsoleSecurityProvider2.USER_ATTRIBUTE);
+ request.removeAttribute(User.USER_ATTRIBUTE);
}
private final AbstractWebConsolePlugin getConsolePlugin(final String label)
@@ -840,11 +842,8 @@ public class OsgiManager extends GenericServlet
return new FilteringResponseWrapper(response, resourceBundle, request);
}
- private static class HttpServiceTracker extends ServiceTracker
+ private static class HttpServiceTracker extends ServiceTracker<HttpService, HttpService>
{
-
- private static final String HTTP_SERVICE = "org.osgi.service.http.HttpService"; //$NON-NLS-1$
-
private final OsgiManager osgiManager;
private final String httpServiceSelector;
@@ -858,7 +857,7 @@ public class OsgiManager extends GenericServlet
try
{
final String filterString = "(&(" + Constants.OBJECTCLASS + "=" //$NON-NLS-1$ //$NON-NLS-2$
- + HTTP_SERVICE + ")(" + httpServiceSelector + "))"; //$NON-NLS-1$ //$NON-NLS-2$
+ + HttpService.class.getName() + ")(" + httpServiceSelector + "))"; //$NON-NLS-1$ //$NON-NLS-2$
Filter filter = osgiManager.getBundleContext().createFilter(
filterString);
return new HttpServiceTracker(osgiManager, httpServiceSelector,
@@ -876,7 +875,7 @@ public class OsgiManager extends GenericServlet
private HttpServiceTracker(final OsgiManager osgiManager)
{
- super(osgiManager.getBundleContext(), HTTP_SERVICE, null);
+ super(osgiManager.getBundleContext(), HttpService.class, null);
this.osgiManager = osgiManager;
this.httpServiceSelector = null;
}
@@ -897,50 +896,38 @@ public class OsgiManager extends GenericServlet
return httpServiceSelector == null;
}
- public Object addingService(ServiceReference reference)
+ public HttpService addingService(ServiceReference<HttpService> reference)
{
- Object service = super.addingService(reference);
- if (service instanceof HttpService)
- {
- osgiManager.bindHttpService((HttpService) service);
- }
+ HttpService service = super.addingService(reference);
+ osgiManager.bindHttpService(service);
return service;
}
- public void removedService(ServiceReference reference, Object service)
+ public void removedService(ServiceReference<HttpService> reference, HttpService service)
{
- if (service instanceof HttpService)
- {
- osgiManager.unbindHttpService((HttpService) service);
- }
+ osgiManager.unbindHttpService(service);
super.removedService(reference, service);
}
}
- private static class BrandingServiceTracker extends ServiceTracker
+ private static class BrandingServiceTracker extends ServiceTracker<BrandingPlugin, BrandingPlugin>
{
BrandingServiceTracker(OsgiManager osgiManager)
{
- super(osgiManager.getBundleContext(), BrandingPlugin.class.getName(), null);
+ super(osgiManager.getBundleContext(), BrandingPlugin.class, null);
}
- public Object addingService(ServiceReference reference)
+ public BrandingPlugin addingService(ServiceReference<BrandingPlugin> reference)
{
- Object plugin = super.addingService(reference);
- if (plugin instanceof BrandingPlugin)
- {
- AbstractWebConsolePlugin.setBrandingPlugin((BrandingPlugin) plugin);
- }
+ BrandingPlugin plugin = super.addingService(reference);
+ AbstractWebConsolePlugin.setBrandingPlugin( plugin);
return plugin;
}
- public void removedService(ServiceReference reference, Object service)
+ public void removedService(ServiceReference<BrandingPlugin> reference, BrandingPlugin service)
{
- if (service instanceof BrandingPlugin)
- {
- AbstractWebConsolePlugin.setBrandingPlugin(null);
- }
+ AbstractWebConsolePlugin.setBrandingPlugin(null);
super.removedService(reference, service);
}
@@ -961,7 +948,7 @@ public class OsgiManager extends GenericServlet
}
synchronized void registerHttpService() {
- Map config = getConfiguration();
+ Map<String, Object> config = getConfiguration();
// get authentication details
String realm = ConfigurationUtil.getProperty(config, PROP_REALM, DEFAULT_REALM);
@@ -974,7 +961,7 @@ public class OsgiManager extends GenericServlet
HttpContext httpContext = new OsgiManagerHttpContext(bundleContext, httpService,
securityProviderTracker, userId, password, realm);
- Dictionary servletConfig = toStringConfig(config);
+ Dictionary<String, String> servletConfig = toStringConfig(config);
if (!httpServletRegistered) {
// register this servlet and take note of this
@@ -1045,27 +1032,27 @@ public class OsgiManager extends GenericServlet
}
- private Map getConfiguration()
+ private Map<String, Object> getConfiguration()
{
return configuration;
}
- Map getDefaultConfiguration()
+ Map<String, Object> getDefaultConfiguration()
{
return defaultConfiguration;
}
- synchronized void updateConfiguration( Dictionary osgiConfig )
+ synchronized void updateConfiguration( Dictionary<String, Object> osgiConfig )
{
- HashMap config = new HashMap( this.defaultConfiguration );
+ Map<String, Object> config = new HashMap<String, Object>( this.defaultConfiguration );
if ( osgiConfig != null )
{
- for ( Enumeration keys = osgiConfig.keys(); keys.hasMoreElements(); )
+ for ( Enumeration<String> keys = osgiConfig.keys(); keys.hasMoreElements(); )
{
- final Object key = keys.nextElement();
+ final String key = keys.nextElement();
config.put( key, osgiConfig.get( key ) );
}
}
@@ -1105,7 +1092,7 @@ public class OsgiManager extends GenericServlet
// get enabled plugins
String[] plugins = ConfigurationUtil.getStringArrayProperty(config, PROP_ENABLED_PLUGINS);
- enabledPlugins = null == plugins ? null : new HashSet(Arrays.asList(plugins));
+ enabledPlugins = null == plugins ? null : new HashSet<String>(Arrays.asList(plugins));
// check for moved config manager class (see FELIX-4074)
if ( enabledPlugins != null )
{
@@ -1180,12 +1167,12 @@ public class OsgiManager extends GenericServlet
}
- private Dictionary toStringConfig( Map config )
+ private Dictionary<String, String> toStringConfig( Map<String, Object> config )
{
- Dictionary stringConfig = new Hashtable();
- for ( Iterator ei = config.entrySet().iterator(); ei.hasNext(); )
+ Dictionary<String, String> stringConfig = new Hashtable<>();
+ for ( Iterator<Map.Entry<String, Object>> ei = config.entrySet().iterator(); ei.hasNext(); )
{
- Entry entry = ( Entry ) ei.next();
+ Entry<String, Object> entry = ei.next();
stringConfig.put( entry.getKey(), String.valueOf( entry.getValue() ) );
}
return stringConfig;
@@ -1233,9 +1220,9 @@ public class OsgiManager extends GenericServlet
return langMap = map;
}
- class UpdateDependenciesStateCustomizer implements ServiceTrackerCustomizer {
+ class UpdateDependenciesStateCustomizer implements ServiceTrackerCustomizer<WebConsoleSecurityProvider, WebConsoleSecurityProvider> {
@Override
- public Object addingService(ServiceReference reference) {
+ public WebConsoleSecurityProvider addingService(ServiceReference<WebConsoleSecurityProvider> reference) {
Object nameObj = reference.getProperty(SECURITY_PROVIDER_PROPERTY_NAME);
if (nameObj instanceof String) {
String name = (String) nameObj;
@@ -1246,13 +1233,13 @@ public class OsgiManager extends GenericServlet
}
@Override
- public void modifiedService(ServiceReference reference, Object service) {
+ public void modifiedService(ServiceReference<WebConsoleSecurityProvider> reference, WebConsoleSecurityProvider service) {
removedService(reference, service);
addingService(reference);
}
@Override
- public void removedService(ServiceReference reference, Object service) {
+ public void removedService(ServiceReference<WebConsoleSecurityProvider> reference, WebConsoleSecurityProvider service) {
Object nameObj = reference.getProperty(SECURITY_PROVIDER_PROPERTY_NAME);
if (nameObj instanceof String) {
String name = (String) nameObj;
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManagerHttpContext.java b/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManagerHttpContext.java
index 03cf735..c7d472f 100644
--- a/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManagerHttpContext.java
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/internal/servlet/OsgiManagerHttpContext.java
@@ -23,6 +23,7 @@ import java.net.URL;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.apache.felix.webconsole.User;
import org.apache.felix.webconsole.WebConsoleSecurityProvider;
import org.apache.felix.webconsole.WebConsoleSecurityProvider2;
import org.osgi.framework.BundleContext;
@@ -44,7 +45,7 @@ final class OsgiManagerHttpContext implements HttpContext
private final HttpContext base;
- private final ServiceTracker tracker;
+ private final ServiceTracker<WebConsoleSecurityProvider, WebConsoleSecurityProvider> tracker;
private final String username;
@@ -54,7 +55,7 @@ final class OsgiManagerHttpContext implements HttpContext
OsgiManagerHttpContext(final BundleContext bundleContext,
- final HttpService httpService, final ServiceTracker tracker, final String username,
+ final HttpService httpService, final ServiceTracker<WebConsoleSecurityProvider, WebConsoleSecurityProvider> tracker, final String username,
final String password, final String realm )
{
this.bundleContext = bundleContext;
@@ -95,19 +96,52 @@ final class OsgiManagerHttpContext implements HttpContext
* <code>Authorization</code> header.
* @param response The HTTP response used to send the authentication request
* if authentication is required but not satisfied.
- * @return <code>true</code> if authentication is required and not
- * satisfied by the request.
+ * @return {@code} true if authentication is required and not satisfied by the request.
*/
- public boolean handleSecurity( HttpServletRequest request, HttpServletResponse response )
- {
- Object provider = tracker.getService();
+ public boolean handleSecurity( final HttpServletRequest request, final HttpServletResponse response ) {
+ final WebConsoleSecurityProvider provider = tracker.getService();
// check whether the security provider can fully handle the request
- if ( provider instanceof WebConsoleSecurityProvider2 )
- {
- return ( ( WebConsoleSecurityProvider2 ) provider ).authenticate( request, response );
+ final boolean result;
+ if ( provider instanceof WebConsoleSecurityProvider2 ) {
+ result = ( ( WebConsoleSecurityProvider2 ) provider ).authenticate( request, response );
+ } else {
+ result = handleSecurity(provider, request, response);
+ }
+
+ if ( result ) {
+ request.setAttribute(User.USER_ATTRIBUTE, new User(){
+
+ @Override
+ public boolean authorize(String role) {
+ final Object user = this.getUserObject();
+ if ( user == null ) {
+ // no user object in request, deny
+ return false;
+ }
+ if ( provider == null ) {
+ // no provider, allow (compatibility)
+ return true;
+ }
+ return provider.authorize(this.getUserObject(), role);
+ }
+
+ @Override
+ public Object getUserObject() {
+ return request.getAttribute(WebConsoleSecurityProvider2.USER_ATTRIBUTE);
+ }
+
+ });
}
+ return result;
+ }
+ /**
+ * Handle security with an optional web console security provider
+ */
+ private boolean handleSecurity( final WebConsoleSecurityProvider provider,
+ final HttpServletRequest request,
+ final HttpServletResponse response) {
// Return immediately if the header is missing
String authHeader = request.getHeader( HEADER_AUTHORIZATION );
if ( authHeader != null && authHeader.length() > 0 )
@@ -170,27 +204,6 @@ final class OsgiManagerHttpContext implements HttpContext
return false;
}
-
- public boolean authorize( final HttpServletRequest request, String role )
- {
- Object user = request.getAttribute( WebConsoleSecurityProvider2.USER_ATTRIBUTE );
- if ( user != null )
- {
- WebConsoleSecurityProvider provider = ( WebConsoleSecurityProvider ) tracker.getService();
- if ( provider != null )
- {
- return provider.authorize( user, role );
- }
-
- // no provider, grant access (backwards compatibility)
- return true;
- }
-
- // missing user in the request, deny access
- return false;
- }
-
-
private static byte[][] base64Decode( String srcString )
{
byte[] transformed = Base64.decodeBase64( srcString );
@@ -225,11 +238,11 @@ final class OsgiManagerHttpContext implements HttpContext
}
- private boolean authenticate( Object provider, String username, byte[] password )
+ private boolean authenticate( WebConsoleSecurityProvider provider, String username, byte[] password )
{
if ( provider != null )
{
- return ( ( WebConsoleSecurityProvider ) provider ).authenticate( username, toString( password ) ) != null;
+ return provider.authenticate( username, toString( password ) ) != null;
}
if ( this.username.equals( username ) && this.password.matches( password ) )
{
@@ -240,5 +253,4 @@ final class OsgiManagerHttpContext implements HttpContext
}
return false;
}
-
}
diff --git a/webconsole/src/main/java/org/apache/felix/webconsole/package-info.java b/webconsole/src/main/java/org/apache/felix/webconsole/package-info.java
new file mode 100644
index 0000000..beefc07
--- /dev/null
+++ b/webconsole/src/main/java/org/apache/felix/webconsole/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+@org.osgi.annotation.versioning.Version("3.4.0")
+package org.apache.felix.webconsole;
+
diff --git a/webconsole/src/test/java/org/apache/felix/webconsole/internal/servlet/OsgiManagerHttpContextTest.java b/webconsole/src/test/java/org/apache/felix/webconsole/internal/servlet/OsgiManagerHttpContextTest.java
index 2664100..0b49dbd 100644
--- a/webconsole/src/test/java/org/apache/felix/webconsole/internal/servlet/OsgiManagerHttpContextTest.java
+++ b/webconsole/src/test/java/org/apache/felix/webconsole/internal/servlet/OsgiManagerHttpContextTest.java
@@ -36,7 +36,7 @@ public class OsgiManagerHttpContextTest {
OsgiManagerHttpContext ctx = new OsgiManagerHttpContext(bc, svc, null, "foo", "bar", "blah");
Method authenticateMethod = OsgiManagerHttpContext.class.getDeclaredMethod(
- "authenticate", new Class [] {Object.class, String.class, byte[].class});
+ "authenticate", new Class [] {WebConsoleSecurityProvider.class, String.class, byte[].class});
authenticateMethod.setAccessible(true);
assertEquals(true, authenticateMethod.invoke(ctx, null, "foo", "bar".getBytes()));
@@ -57,7 +57,7 @@ public class OsgiManagerHttpContextTest {
OsgiManagerHttpContext ctx = new OsgiManagerHttpContext(bc, svc, null, "foo", "bar", "blah");
Method authenticateMethod = OsgiManagerHttpContext.class.getDeclaredMethod(
- "authenticate", new Class [] {Object.class, String.class, byte[].class});
+ "authenticate", new Class [] {WebConsoleSecurityProvider.class, String.class, byte[].class});
authenticateMethod.setAccessible(true);
assertEquals("A required security provider is configured, logging in using "
diff --git a/webconsole/src/test/java/org/apache/felix/webconsole/internal/servlet/OsgiManagerTest.java b/webconsole/src/test/java/org/apache/felix/webconsole/internal/servlet/OsgiManagerTest.java
index 49f6af7..7c52482 100644
--- a/webconsole/src/test/java/org/apache/felix/webconsole/internal/servlet/OsgiManagerTest.java
+++ b/webconsole/src/test/java/org/apache/felix/webconsole/internal/servlet/OsgiManagerTest.java
@@ -36,6 +36,7 @@ import java.util.Hashtable;
import java.util.List;
import java.util.Set;
+import org.apache.felix.webconsole.WebConsoleSecurityProvider;
import org.junit.Test;
import org.mockito.Mockito;
import org.mockito.invocation.InvocationOnMock;
@@ -134,13 +135,13 @@ public class OsgiManagerTest {
final List<String> invocations = new ArrayList<String>();
ServiceTrackerCustomizer stc = mgr.new UpdateDependenciesStateCustomizer() {
@Override
- public Object addingService(ServiceReference reference) {
+ public WebConsoleSecurityProvider addingService(ServiceReference<WebConsoleSecurityProvider> reference) {
invocations.add("added:" + reference);
return null;
}
@Override
- public void removedService(ServiceReference reference, Object service) {
+ public void removedService(ServiceReference<WebConsoleSecurityProvider> reference, WebConsoleSecurityProvider service) {
invocations.add("removed:" + reference);
}
};