Merging Webapp authenticator framework implementation

revert-70aa11f8
prabathabey 10 years ago
parent 3070488adf
commit bcc1cad6e5

@ -21,8 +21,10 @@ package org.wso2.carbon.device.mgt.core.api.mgt;
import org.wso2.carbon.apimgt.api.APIProvider; import org.wso2.carbon.apimgt.api.APIProvider;
import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient; import javax.xml.bind.annotation.XmlTransient;
@XmlRootElement(name = "API")
public class APIConfig { public class APIConfig {
private String name; private String name;

@ -77,7 +77,7 @@ public class APIPublisherConfig {
Document doc = DeviceManagerUtil.convertToDocument(publisherConfig); Document doc = DeviceManagerUtil.convertToDocument(publisherConfig);
/* Un-marshaling Device Management configuration */ /* Un-marshaling Device Management configuration */
JAXBContext ctx = JAXBContext.newInstance(DeviceManagementConfig.class); JAXBContext ctx = JAXBContext.newInstance(APIPublisherConfig.class);
Unmarshaller unmarshaller = ctx.createUnmarshaller(); Unmarshaller unmarshaller = ctx.createUnmarshaller();
config = (APIPublisherConfig) unmarshaller.unmarshal(doc); config = (APIPublisherConfig) unmarshaller.unmarshal(doc);
} catch (JAXBException e) { } catch (JAXBException e) {

@ -1,39 +0,0 @@
/*
* Copyright (c) 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. 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.wso2.carbon.key.mgt.handler.valve;
public class APIFaultException extends Exception {
private static final long serialVersionUID = 1L;
private int errorCode;
public APIFaultException(int errorCode, String message) {
super(message);
this.errorCode = errorCode;
}
public APIFaultException(int errorCode, String message, Throwable cause) {
super(message, cause);
this.errorCode = errorCode;
}
public int getErrorCode() {
return errorCode;
}
}

@ -1,143 +0,0 @@
/*
* Copyright (c) 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. 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.wso2.carbon.key.mgt.handler.valve;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
import org.apache.catalina.valves.ValveBase;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.apimgt.api.APIManagementException;
import org.wso2.carbon.apimgt.core.authenticate.APITokenValidator;
import org.wso2.carbon.apimgt.core.gateway.APITokenAuthenticator;
import org.wso2.carbon.apimgt.impl.APIConstants;
import org.wso2.carbon.apimgt.impl.dao.ApiMgtDAO;
import org.wso2.carbon.apimgt.impl.utils.APIUtil;
import javax.servlet.ServletException;
import java.io.IOException;
import java.util.Enumeration;
public class OAuthTokenValidatorValve extends ValveBase {
private static final Log log = LogFactory.getLog(OAuthTokenValidatorValve.class);
APITokenAuthenticator authenticator;
public OAuthTokenValidatorValve() {
authenticator = new APITokenAuthenticator();
}
@Override
public void invoke(Request request, Response response) throws java.io.IOException, javax.servlet.ServletException {
String context = request.getContextPath();
if (context == null || context.equals("")) {
//Invoke the next valve in handler chain.
getNext().invoke(request, response);
return;
}
boolean contextExist;
Boolean contextValueInCache = null;
if (APIUtil.getAPIContextCache().get(context) != null) {
contextValueInCache = Boolean.parseBoolean(APIUtil.getAPIContextCache().get(context).toString());
}
if (contextValueInCache != null) {
contextExist = contextValueInCache;
} else {
contextExist = ApiMgtDAO.isContextExist(context);
APIUtil.getAPIContextCache().put(context, contextExist);
}
if (!contextExist) {
getNext().invoke(request, response);
return;
}
try {
handleWSDLGetRequest(request, response, context);
} catch (IOException e) {
e.printStackTrace();
} catch (ServletException e) {
e.printStackTrace();
}
String authHeader = request.getHeader(APIConstants.OperationParameter.AUTH_PARAM_NAME);
String accessToken = null;
/* Authenticate*/
try {
if (authHeader != null) {
accessToken = HandlerUtil.getAccessToken(authHeader);
} else {
// There can be some API published with None Auth Type
/*
* throw new
* APIFaultException(APIConstants.KeyValidationStatus
* .API_AUTH_INVALID_CREDENTIALS,
* "Invalid format for Authorization header. Expected 'Bearer <token>'"
* );
*/
}
String apiVersion = HandlerUtil.getAPIVersion(request);
String domain = request.getHeader(APITokenValidator.getAPIManagerClientDomainHeader());
String authLevel = authenticator.getResourceAuthenticationScheme(context,
apiVersion,
request.getRequestURI(),
request.getMethod());
if (HandlerConstants.NO_MATCHING_AUTH_SCHEME.equals(authLevel)) {
HandlerUtil.handleNoMatchAuthSchemeCallForRestService(response,
request.getMethod(), request.getRequestURI(),
apiVersion, context);
return;
} else {
HandlerUtil.doAuthenticate(context, apiVersion, accessToken, authLevel, domain);
}
} catch (APIManagementException e) {
//ignore
} catch (APIFaultException e) {
log.error("Error occurred while key validation", e);
return;
}
getNext().invoke(request, response);
}
private void handleWSDLGetRequest(Request request, Response response,
String context) throws IOException, ServletException {
if (request.getMethod().equals("GET")) {
// TODO:Need to get these paths from a config file.
if (request.getRequestURI().matches(context + "/[^/]*/services")) {
getNext().invoke(request, response);
return;
}
Enumeration<String> params = request.getParameterNames();
String paramName;
while (params.hasMoreElements()) {
paramName = params.nextElement();
if (paramName.endsWith("wsdl") || paramName.endsWith("wadl")) {
getNext().invoke(request, response);
return;
}
}
}
}
}

@ -21,14 +21,14 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent> <parent>
<groupId>org.wso2.carbon.devicemgt</groupId> <groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>key-mgt</artifactId> <artifactId>webapp-authenticator-framework</artifactId>
<version>0.9.2-SNAPSHOT</version> <version>0.9.2-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath> <relativePath>../pom.xml</relativePath>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>org.wso2.carbon.devicemgt</groupId> <groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.key.mgt.handler.valve</artifactId> <artifactId>org.wso2.carbon.webapp.authenticator.framework</artifactId>
<version>0.9.2-SNAPSHOT</version> <version>0.9.2-SNAPSHOT</version>
<packaging>bundle</packaging> <packaging>bundle</packaging>
<name>WSO2 Carbon - Key Management Handler Valve</name> <name>WSO2 Carbon - Key Management Handler Valve</name>
@ -45,10 +45,15 @@
<instructions> <instructions>
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
<Bundle-Name>${project.artifactId}</Bundle-Name> <Bundle-Name>${project.artifactId}</Bundle-Name>
<Bundle-Activator>org.wso2.carbon.webapp.authenticator.framework.internal.WebappAuthenticatorFrameworkBundleActivator</Bundle-Activator>
<Require-Bundle>org.wso2.carbon.tomcat.patch</Require-Bundle> <Require-Bundle>org.wso2.carbon.tomcat.patch</Require-Bundle>
<Private-Package> <Private-Package>
org.wso2.carbon.key.mgt.handler.valve.* org.wso2.carbon.webapp.authenticator.framework.internal
</Private-Package> </Private-Package>
<Export-Package>
!org.wso2.carbon.webapp.authenticator.framework.internal,
org.wso2.carbon.webapp.authenticator.framework.*
</Export-Package>
<Fragment-Host>tomcat</Fragment-Host> <Fragment-Host>tomcat</Fragment-Host>
</instructions> </instructions>
</configuration> </configuration>
@ -93,6 +98,10 @@
<groupId>org.wso2.carbon.identity</groupId> <groupId>org.wso2.carbon.identity</groupId>
<artifactId>org.wso2.carbon.identity.core</artifactId> <artifactId>org.wso2.carbon.identity.core</artifactId>
</dependency> </dependency>
<dependency>
<groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.core.services</artifactId>
</dependency>
</dependencies> </dependencies>
</project> </project>

@ -0,0 +1,74 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. 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.wso2.carbon.webapp.authenticator.framework;
public class AuthenticationException extends Exception {
private static final long serialVersionUID = -3151279311929070297L;
private String errorMessage;
private int errorCode;
public AuthenticationException(int errorCode, String message) {
super(message);
this.errorCode = errorCode;
}
public AuthenticationException(int errorCode, String message, Throwable cause) {
super(message, cause);
this.errorCode = errorCode;
}
public int getErrorCode() {
return errorCode;
}
public String getErrorMessage() {
return errorMessage;
}
public void setErrorMessage(String errorMessage) {
this.errorMessage = errorMessage;
}
public AuthenticationException(String msg, Exception nestedEx) {
super(msg, nestedEx);
setErrorMessage(msg);
}
public AuthenticationException(String message, Throwable cause) {
super(message, cause);
setErrorMessage(message);
}
public AuthenticationException(String msg) {
super(msg);
setErrorMessage(msg);
}
public AuthenticationException() {
super();
}
public AuthenticationException(Throwable cause) {
super(cause);
}
}

@ -0,0 +1,50 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. 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.wso2.carbon.webapp.authenticator.framework;
import org.apache.catalina.connector.Request;
public class BasicAuthAuthenticator implements WebappAuthenticator {
private static final String BASIC_AUTH_AUTHENTICATOR = "BasicAuthAuthenticator";
private String username;
private String password;
public BasicAuthAuthenticator(String username, String password) {
this.username = username;
this.password = password;
}
@Override
public boolean isAuthenticated(Request request) {
return false;
}
@Override
public Status authenticate(Request request) {
return Status.CONTINUE;
}
@Override
public String getAuthenticatorName() {
return BasicAuthAuthenticator.BASIC_AUTH_AUTHENTICATOR;
}
}

@ -15,7 +15,7 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.wso2.carbon.key.mgt.handler.valve; package org.wso2.carbon.webapp.authenticator.framework;
public class HandlerConstants { public class HandlerConstants {

@ -15,7 +15,7 @@
* specific language governing permissions and limitations * specific language governing permissions and limitations
* under the License. * under the License.
*/ */
package org.wso2.carbon.key.mgt.handler.valve; package org.wso2.carbon.webapp.authenticator.framework;
import org.apache.axiom.om.OMAbstractFactory; import org.apache.axiom.om.OMAbstractFactory;
import org.apache.axiom.om.OMElement; import org.apache.axiom.om.OMElement;
@ -38,7 +38,6 @@ import java.io.IOException;
public class HandlerUtil { public class HandlerUtil {
private static APIKeyValidationInfoDTO apiKeyValidationDTO;
private static final Log log = LogFactory.getLog(HandlerUtil.class); private static final Log log = LogFactory.getLog(HandlerUtil.class);
/** /**
@ -71,7 +70,8 @@ public class HandlerUtil {
String version, String context ) { String version, String context ) {
String errMsg = "Resource is not matched for HTTP Verb " + httpVerb + ". API context " + context + String errMsg = "Resource is not matched for HTTP Verb " + httpVerb + ". API context " + context +
",version " + version + ", request " + reqUri; ",version " + version + ", request " + reqUri;
APIFaultException e = new APIFaultException( APIManagerErrorConstants.API_AUTH_INCORRECT_API_RESOURCE, errMsg); AuthenticationException e =
new AuthenticationException(APIManagerErrorConstants.API_AUTH_INCORRECT_API_RESOURCE, errMsg);
String faultPayload = getFaultPayload(e, APIManagerErrorConstants.API_SECURITY_NS, String faultPayload = getFaultPayload(e, APIManagerErrorConstants.API_SECURITY_NS,
APIManagerErrorConstants.API_SECURITY_NS_PREFIX).toString(); APIManagerErrorConstants.API_SECURITY_NS_PREFIX).toString();
handleRestFailure(response, faultPayload); handleRestFailure(response, faultPayload);
@ -80,13 +80,13 @@ public class HandlerUtil {
public static boolean doAuthenticate(String context, String version, String accessToken, public static boolean doAuthenticate(String context, String version, String accessToken,
String requiredAuthenticationLevel, String clientDomain) String requiredAuthenticationLevel, String clientDomain)
throws APIManagementException, throws APIManagementException,
APIFaultException { AuthenticationException {
if (APIConstants.AUTH_NO_AUTHENTICATION.equals(requiredAuthenticationLevel)) { if (APIConstants.AUTH_NO_AUTHENTICATION.equals(requiredAuthenticationLevel)) {
return true; return true;
} }
APITokenValidator tokenValidator = new APITokenValidator(); APITokenValidator tokenValidator = new APITokenValidator();
apiKeyValidationDTO = tokenValidator.validateKey(context, version, accessToken, APIKeyValidationInfoDTO apiKeyValidationDTO = tokenValidator.validateKey(context, version, accessToken,
requiredAuthenticationLevel, clientDomain); requiredAuthenticationLevel, clientDomain);
if (apiKeyValidationDTO.isAuthorized()) { if (apiKeyValidationDTO.isAuthorized()) {
String userName = apiKeyValidationDTO.getEndUserName(); String userName = apiKeyValidationDTO.getEndUserName();
@ -101,7 +101,7 @@ public class HandlerUtil {
} }
return true; return true;
} else { } else {
throw new APIFaultException(apiKeyValidationDTO.getValidationStatus(), throw new AuthenticationException(apiKeyValidationDTO.getValidationStatus(),
"Access failure for API: " + context + ", version: " + "Access failure for API: " + context + ", version: " +
version + " with key: " + accessToken); version + " with key: " + accessToken);
} }
@ -118,7 +118,7 @@ public class HandlerUtil {
} }
} }
public static OMElement getFaultPayload(APIFaultException exception, String FaultNS, public static OMElement getFaultPayload(AuthenticationException exception, String FaultNS,
String FaultNSPrefix) { String FaultNSPrefix) {
OMFactory fac = OMAbstractFactory.getOMFactory(); OMFactory fac = OMAbstractFactory.getOMFactory();
OMNamespace ns = fac.createOMNamespace(FaultNS, FaultNSPrefix); OMNamespace ns = fac.createOMNamespace(FaultNS, FaultNSPrefix);

@ -0,0 +1,102 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. 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.wso2.carbon.webapp.authenticator.framework;
import org.apache.catalina.connector.Request;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.apimgt.api.APIManagementException;
import org.wso2.carbon.apimgt.core.authenticate.APITokenValidator;
import org.wso2.carbon.apimgt.core.gateway.APITokenAuthenticator;
import org.wso2.carbon.apimgt.impl.dao.ApiMgtDAO;
import org.wso2.carbon.apimgt.impl.utils.APIUtil;
public class OAuthAuthenticator implements WebappAuthenticator {
private static final String OAUTH_AUTHENTICATOR = "OAuthAuthenticator";
private static APITokenAuthenticator authenticator = new APITokenAuthenticator();
private String bearerToken;
private static final Log log = LogFactory.getLog(OAuthAuthenticator.class);
public OAuthAuthenticator(String bearerToken) {
this.bearerToken = bearerToken;
}
@Override
public boolean isAuthenticated(Request request) {
return false;
}
@Override
public Status authenticate(Request request) {
String context = request.getContextPath();
if (context == null || "".equals(context)) {
return Status.CONTINUE;
}
boolean contextExist;
Boolean contextValueInCache = null;
if (APIUtil.getAPIContextCache().get(context) != null) {
contextValueInCache = Boolean.parseBoolean(APIUtil.getAPIContextCache().get(context).toString());
}
if (contextValueInCache != null) {
contextExist = contextValueInCache;
} else {
contextExist = ApiMgtDAO.isContextExist(context);
APIUtil.getAPIContextCache().put(context, contextExist);
}
if (!contextExist) {
return Status.CONTINUE;
}
try {
String apiVersion = HandlerUtil.getAPIVersion(request);
String domain = request.getHeader(APITokenValidator.getAPIManagerClientDomainHeader());
String authLevel = authenticator.getResourceAuthenticationScheme(context,
apiVersion,
request.getRequestURI(),
request.getMethod());
if (HandlerConstants.NO_MATCHING_AUTH_SCHEME.equals(authLevel)) {
HandlerUtil.handleNoMatchAuthSchemeCallForRestService(null,
request.getMethod(), request.getRequestURI(),
apiVersion, context);
return Status.CONTINUE;
} else {
boolean isAuthenticated =
HandlerUtil.doAuthenticate(context, apiVersion, bearerToken, authLevel, domain);
return (isAuthenticated) ? Status.SUCCESS : Status.FAILURE;
}
} catch (APIManagementException e) {
//ignore
} catch (AuthenticationException e) {
log.error("Error occurred while key validation", e);
}
return Status.CONTINUE;
}
@Override
public String getAuthenticatorName() {
return OAuthAuthenticator.OAUTH_AUTHENTICATOR;
}
}

@ -0,0 +1,35 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. 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.wso2.carbon.webapp.authenticator.framework;
import org.apache.catalina.connector.Request;
public interface WebappAuthenticator {
enum Status {
SUCCESS, FAILURE, CONTINUE
}
boolean isAuthenticated(Request request);
Status authenticate(Request request);
String getAuthenticatorName();
}

@ -0,0 +1,67 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. 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.wso2.carbon.webapp.authenticator.framework;
import org.apache.catalina.connector.Request;
import org.apache.catalina.util.Base64;
import org.apache.tomcat.util.buf.ByteChunk;
import org.apache.tomcat.util.buf.CharChunk;
import org.apache.tomcat.util.buf.MessageBytes;
public class WebappAuthenticatorFactory {
public static WebappAuthenticator getAuthenticator(Request request) {
MessageBytes authorization = request.getCoyoteRequest().getMimeHeaders().getValue("authorization");
if (authorization != null) {
authorization.toBytes();
ByteChunk authBC = authorization.getByteChunk();
if (authBC.startsWithIgnoreCase("basic ", 0)) {
authBC.setOffset(authBC.getOffset() + 6);
CharChunk authCC = authorization.getCharChunk();
Base64.decode(authBC, authCC);
String username;
String password = null;
int colon = authCC.indexOf(':');
if (colon < 0) {
username = authCC.toString();
} else {
char[] buf = authCC.getBuffer();
username = new String(buf, 0, colon);
password = new String(buf, colon + 1, authCC.getEnd() - colon - 1);
}
authBC.setOffset(authBC.getOffset() - 6);
return new BasicAuthAuthenticator(username, password);
} else if (authBC.startsWithIgnoreCase("bearer ", 0)) {
authBC.setOffset(authBC.getOffset() + 7);
CharChunk authCC = authorization.getCharChunk();
char[] buf = authCC.getBuffer();
String bearer = new String(buf, 0, authCC.getEnd() - 1);
authBC.setOffset(authBC.getOffset() - 7);
return new OAuthAuthenticator(bearer);
}
}
throw new IllegalArgumentException("Failed to determine an appropriate authenticator to be used, based " +
"on the incoming request");
}
}

@ -0,0 +1,46 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. 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.wso2.carbon.webapp.authenticator.framework;
import org.apache.axis2.context.MessageContext;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
import org.apache.catalina.valves.ValveBase;
import org.wso2.carbon.core.services.authentication.CarbonServerAuthenticator;
import org.wso2.carbon.tomcat.ext.valves.CarbonTomcatValve;
import org.wso2.carbon.tomcat.ext.valves.CompositeValve;
import javax.servlet.ServletException;
import java.io.IOException;
public class WebappAuthenticatorFrameworkValve extends CarbonTomcatValve {
@Override
public void invoke(Request request, Response response, CompositeValve compositeValve) {
WebappAuthenticator authenticator = WebappAuthenticatorFactory.getAuthenticator(request);
WebappAuthenticator.Status status = authenticator.authenticate(request);
switch (status) {
case SUCCESS:
case CONTINUE:
getNext().invoke(request, response, compositeValve);
case FAILURE:
//do something
}
}
}

@ -0,0 +1,59 @@
/*
* Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. 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.wso2.carbon.webapp.authenticator.framework.internal;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.wso2.carbon.tomcat.ext.valves.CarbonTomcatValve;
import org.wso2.carbon.tomcat.ext.valves.TomcatValveContainer;
import org.wso2.carbon.webapp.authenticator.framework.WebappAuthenticatorFrameworkValve;
import java.util.ArrayList;
import java.util.List;
public class WebappAuthenticatorFrameworkBundleActivator implements BundleActivator {
private static final Log log = LogFactory.getLog(WebappAuthenticatorFrameworkBundleActivator.class);
@Override
public void start(BundleContext bundleContext) throws Exception {
if (log.isDebugEnabled()) {
log.debug("Starting Web Application Authenticator Framework Bundle");
}
try {
List<CarbonTomcatValve> valves = new ArrayList<CarbonTomcatValve>();
valves.add(new WebappAuthenticatorFrameworkValve());
TomcatValveContainer.addValves(valves);
if (log.isDebugEnabled()) {
log.debug("Web Application Authenticator Framework Bundle has been started successfully");
}
} catch (Throwable e) {
log.error("Error occurred while initializing the bundle");
}
}
@Override
public void stop(BundleContext bundleContext) throws Exception {
//do nothing
}
}

@ -30,14 +30,14 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>org.wso2.carbon.devicemgt</groupId> <groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>key-mgt</artifactId> <artifactId>webapp-authenticator-framework</artifactId>
<version>0.9.2-SNAPSHOT</version> <version>0.9.2-SNAPSHOT</version>
<packaging>pom</packaging> <packaging>pom</packaging>
<name>WSO2 Carbon - Device Management Component</name> <name>WSO2 Carbon - Device Management Component</name>
<url>http://wso2.org</url> <url>http://wso2.org</url>
<modules> <modules>
<module>org.wso2.carbon.key.mgt.handler.valve</module> <module>org.wso2.carbon.webapp.authenticator.framework</module>
</modules> </modules>
<build> <build>

@ -0,0 +1,106 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
~
~ WSO2 Inc. 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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>device-mgt-feature</artifactId>
<version>0.9.2-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>org.wso2.carbon.webapp.authenticator.framework.server.feature</artifactId>
<packaging>pom</packaging>
<version>0.9.2-SNAPSHOT</version>
<name>WSO2 Carbon - Device Management Server Feature</name>
<url>http://wso2.org</url>
<description>This feature contains the core bundles required for Back-end Device Management functionality
</description>
<dependencies>
<dependency>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>org.wso2.carbon.device.mgt.core</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>copy-resources</id>
<phase>generate-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>src/main/resources</outputDirectory>
<resources>
<resource>
<directory>resources</directory>
<includes>
<include>build.properties</include>
<include>p2.inf</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.wso2.maven</groupId>
<artifactId>carbon-p2-plugin</artifactId>
<version>${carbon.p2.plugin.version}</version>
<executions>
<execution>
<id>p2-feature-generation</id>
<phase>package</phase>
<goals>
<goal>p2-feature-gen</goal>
</goals>
<configuration>
<id>org.wso2.carbon.webapp.authenticator.framework.server</id>
<propertiesFile>../../../features/etc/feature.properties</propertiesFile>
<adviceFile>
<properties>
<propertyDef>org.wso2.carbon.p2.category.type:server</propertyDef>
<propertyDef>org.eclipse.equinox.p2.type.group:false</propertyDef>
</properties>
</adviceFile>
<bundles>
<bundleDef>org.wso2.carbon.devicemgt:org.wso2.carbon.webapp.authenticator.framework:${carbon.device.mgt.version}
</bundleDef>
</bundles>
<importFeatures>
<importFeatureDef>org.wso2.carbon.core.server:${carbon.kernel.version}</importFeatureDef>
<importFeatureDef>org.wso2.carbon.apimgt.core:${carbon.api.mgt.version}</importFeatureDef>
</importFeatures>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
~ Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
~
~ WSO2 Inc. 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.
-->
<DeviceMgtConfiguration>
<ManagementRepository>
<DataSourceConfiguration>
<JndiLookupDefinition>
<Name>jdbc/DM_DS</Name>
</JndiLookupDefinition>
</DataSourceConfiguration>
<EmailClientConfiguration>
<minimumThread>8</minimumThread>
<maximumThread>100</maximumThread>
<keepAliveTime>20</keepAliveTime>
<ThreadQueueCapacity>1000</ThreadQueueCapacity>
</EmailClientConfiguration>
</ManagementRepository>
</DeviceMgtConfiguration>

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
~ Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
~
~ WSO2 Inc. 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.
-->
<LicenseConfig>
<Licenses>
<License>
<Provider>wso2</Provider>
<Name>android</Name>
<Version>1.0.0</Version>
<Language>1.0.0</Language>
<ValidFrom>01-01-2014</ValidFrom>
<ValidTo>31-12-2035</ValidTo>
<Text><![CDATA[Test License]]></Text>
</License>
<License>
<Provider>wso2</Provider>
<Name>ios</Name>
<Version>1.0.0</Version>
<Language>1.0.0</Language>
<ValidFrom>01-01-2014</ValidFrom>
<ValidTo>31-12-2035</ValidTo>
<Text><![CDATA[IOS License]]></Text>
</License>
<License>
<Provider>wso2</Provider>
<Name>windows</Name>
<Version>1.0.0</Version>
<Language>1.0.0</Language>
<ValidFrom>01-01-2014</ValidFrom>
<ValidTo>31-12-2035</ValidTo>
<Text><![CDATA[Windows License]]></Text>
</License>
</Licenses>
</LicenseConfig>

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
~ Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
~
~ WSO2 Inc. 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.
-->
<Notifications>
<EnrolmentNotifications>
<Header>Dear {title} {user-name},</Header>
<Body>You have been registered to the WSO2 MDM. Below is the link to enroll.</Body>
<Url>{downloadUrl}</Url>
<Footer>
Best Regards,
WSO2 Carbon Team
http://www.wso2.com
</Footer>
<Subject>Enrol your device with WSO2 MDM</Subject>
</EnrolmentNotifications>
</Notifications>

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
~ Copyright (c) 2015, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
~
~ WSO2 Inc. 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.
-->
<APIPublisherConfig>
<APIs>
<API>
<Name>appmanager</Name>
<Owner>admin</Owner>
<Context>enrollment</Context>
<Version>1.0.0</Version>
<Endpoint>http://localhost:9763/</Endpoint>
<Transports>http,https</Transports>
</API>
</APIs>
</APIPublisherConfig>

@ -0,0 +1,60 @@
CREATE TABLE IF NOT EXISTS DM_DEVICE_TYPE (
ID INT auto_increment NOT NULL,
NAME VARCHAR(300) NULL DEFAULT NULL,
PRIMARY KEY (ID)
);
CREATE TABLE IF NOT EXISTS DM_DEVICE (
ID INTEGER auto_increment NOT NULL,
DESCRIPTION TEXT NULL DEFAULT NULL,
NAME VARCHAR(100) NULL DEFAULT NULL,
DATE_OF_ENROLLMENT BIGINT NULL DEFAULT NULL,
DATE_OF_LAST_UPDATE BIGINT NULL DEFAULT NULL,
OWNERSHIP VARCHAR(45) NULL DEFAULT NULL,
STATUS VARCHAR(15) NULL DEFAULT NULL,
DEVICE_TYPE_ID INT(11) NULL DEFAULT NULL,
DEVICE_IDENTIFICATION VARCHAR(300) NULL DEFAULT NULL,
OWNER VARCHAR(45) NULL DEFAULT NULL,
TENANT_ID INTEGER DEFAULT 0,
PRIMARY KEY (ID),
CONSTRAINT fk_DM_DEVICE_DM_DEVICE_TYPE2 FOREIGN KEY (DEVICE_TYPE_ID )
REFERENCES DM_DEVICE_TYPE (ID) ON DELETE NO ACTION ON UPDATE NO ACTION
);
CREATE TABLE IF NOT EXISTS DM_OPERATION (
ID INTEGER AUTO_INCREMENT NOT NULL,
TYPE VARCHAR(50) NOT NULL,
CREATED_TIMESTAMP TIMESTAMP NOT NULL,
RECEIVED_TIMESTAMP TIMESTAMP NULL,
STATUS VARCHAR(50) NULL,
PRIMARY KEY (ID)
);
CREATE TABLE IF NOT EXISTS DM_CONFIG_OPERATION (
OPERATION_ID INTEGER NOT NULL,
PRIMARY KEY (OPERATION_ID),
CONSTRAINT fk_dm_operation_config FOREIGN KEY (OPERATION_ID) REFERENCES
DM_OPERATION (ID) ON DELETE NO ACTION ON UPDATE NO ACTION
);
CREATE TABLE IF NOT EXISTS DM_COMMAND_OPERATION (
OPERATION_ID INTEGER NOT NULL,
ENABLED INTEGER NOT NULL DEFAULT 0,
PRIMARY KEY (OPERATION_ID),
CONSTRAINT fk_dm_operation_command FOREIGN KEY (OPERATION_ID) REFERENCES
DM_OPERATION (ID) ON DELETE NO ACTION ON UPDATE NO ACTION
);
CREATE TABLE IF NOT EXISTS DM_DEVICE_OPERATION_MAPPING (
ID INTEGER AUTO_INCREMENT NOT NULL,
DEVICE_ID INTEGER NOT NULL,
OPERATION_ID INTEGER NOT NULL,
PRIMARY KEY (ID),
CONSTRAINT fk_dm_device_operation_mapping_device FOREIGN KEY (DEVICE_ID) REFERENCES
DM_DEVICE (ID) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT fk_dm_device_operation_mapping_operation FOREIGN KEY (OPERATION_ID) REFERENCES
DM_OPERATION (ID) ON DELETE NO ACTION ON UPDATE NO ACTION
);
-- TO:DO - Remove this INSERT sql statement.
Insert into DM_DEVICE_TYPE (ID,NAME) VALUES (1, 'android');

@ -0,0 +1,35 @@
-- -----------------------------------------------------
-- Table `DM_DEVICE_TYPE`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `DM_DEVICE_TYPE` (
`ID` INT(11) NOT NULL ,
`NAME` VARCHAR(300) NULL DEFAULT NULL ,
PRIMARY KEY (`ID`) )
ENGINE = InnoDB
DEFAULT CHARACTER SET = latin1;
-- -----------------------------------------------------
-- Table `DM_DEVICE`
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `DM_DEVICE` (
`ID` VARCHAR(20) NOT NULL ,
`DESCRIPTION` TEXT NULL DEFAULT NULL ,
`NAME` VARCHAR(100) NULL DEFAULT NULL ,
`DATE_OF_ENROLLMENT` DATETIME NULL DEFAULT NULL ,
`DATE_OF_LAST_UPDATE` DATETIME NULL DEFAULT NULL ,
`OWNERSHIP` VARCHAR(45) NULL DEFAULT NULL ,
`STATUS` VARCHAR(15) NULL DEFAULT NULL ,
`DEVICE_TYPE_ID` INT(11) NULL DEFAULT NULL ,
`DEVICE_IDENTIFICATION` VARCHAR(300) NULL DEFAULT NULL ,
`OWNER` VARCHAR(45) NULL DEFAULT NULL ,
TENANT_ID INTEGER DEFAULT 0,
PRIMARY KEY (`ID`) ,
INDEX `fk_DM_DEVICE_DM_DEVICE_TYPE2_idx` (`DEVICE_TYPE_ID` ASC) ,
CONSTRAINT `fk_DM_DEVICE_DM_DEVICE_TYPE2`
FOREIGN KEY (`DEVICE_TYPE_ID` )
REFERENCES `DM_DEVICE_TYPE` (`ID` )
ON DELETE NO ACTION
ON UPDATE NO ACTION)
ENGINE = InnoDB
DEFAULT CHARACTER SET = latin1;

@ -0,0 +1,7 @@
instructions.configure = \
org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.device.mgt.server_${feature.version}/conf/cdm-config.xml,target:${installFolder}/../../conf/cdm-config.xml,overwrite:true);\
org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.device.mgt.server_${feature.version}/conf/notification-messages.xml,target:${installFolder}/../../conf/notification-messages.xml,overwrite:true);\
org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.device.mgt.server_${feature.version}/conf/license-config.xml,target:${installFolder}/../../conf/etc/license-config.xml,overwrite:true);\
org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.device.mgt.server_${feature.version}/conf/user-api-publisher-config.xml,target:${installFolder}/../../conf/etc/user-api-publisher-config.xml,overwrite:true);\
org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.device.mgt.server_${feature.version}/dbscripts/cdm,target:${installFolder}/../../../dbscripts/cdm,overwrite:true);\
org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.wso2.carbon.device.mgt.server_${feature.version}/rxts/license.rxt,target:${installFolder}/../../../repository/resources/rxts/license.rxt,overwrite:true);\

@ -0,0 +1,47 @@
<?xml version="1.0"?>
<artifactType type="application/vnd.wso2-license+xml" shortName="license" singularLabel="License" pluralLabel="Licenses"
hasNamespace="false" iconSet="10">
<storagePath>/device-mgt/license/@{overview_name}/@{overview_language}/@{overview_version}</storagePath>
<nameAttribute>overview_name</nameAttribute>
<ui>
<list>
<column name="Device Type">
<data type="path" value="overview_provider" href="@{storagePath}"/>
</column>
<column name="Name">
<data type="path" value="overview_name" href="@{storagePath}"/>
</column>
<column name="Language">
<data type="path" value="overview_language" href="@{storagePath}"/>
</column>
<column name="Version">
<data type="path" value="overview_version" href="@{storagePath}"/>
</column>
</list>
</ui>
<content>
<table name="Overview">
<field type="text" required="true">
<name>Provider</name>
</field>
<field type="text" required="true">
<name>Name</name>
</field>
<field type="text" required="true">
<name>Language</name>
</field>
<field type="text" required="true">
<name>Version</name>
</field>
<field type="text">
<name>Validity From</name>
</field>
<field type="text">
<name>Validity To</name>
</field>
<field type="text-area">
<name>License</name>
</field>
</table>
</content>
</artifactType>

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright (c) 2014, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
~
~ WSO2 Inc. 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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>carbon-devicemgt</artifactId>
<version>0.9.2-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.wso2.carbon.devicemgt</groupId>
<artifactId>webapp-authenticator-framework-feature</artifactId>
<version>0.9.2-SNAPSHOT</version>
<packaging>pom</packaging>
<name>WSO2 Carbon - Webapp Authenticator Framework Feature</name>
<url>http://wso2.org</url>
<modules>
<module>org.wso2.carbon.webapp.authenticator.framework.server.feature</module>
</modules>
</project>

@ -38,10 +38,11 @@
<module>components/device-mgt</module> <module>components/device-mgt</module>
<module>components/policy-mgt</module> <module>components/policy-mgt</module>
<module>components/user-mgt</module> <module>components/user-mgt</module>
<module>components/key-mgt</module> <module>components/webapp-authenticator-framework</module>
<module>features/device-mgt</module> <module>features/device-mgt</module>
<module>features/policy-mgt</module> <module>features/policy-mgt</module>
<module>features/user-mgt</module> <module>features/user-mgt</module>
<module>features/webapp-authenticator-framework</module>
</modules> </modules>
<dependencyManagement> <dependencyManagement>
@ -504,10 +505,14 @@
<artifactId>org.wso2.carbon.logging</artifactId> <artifactId>org.wso2.carbon.logging</artifactId>
<version>${carbon.kernel.version}</version> <version>${carbon.kernel.version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.wso2.carbon</groupId>
<artifactId>org.wso2.carbon.core.services</artifactId>
<version>${carbon.kernel.version}</version>
</dependency>
<!-- End of Carbon Kernel dependencies --> <!-- End of Carbon Kernel dependencies -->
<!-- Orbit dependencies --> <!-- Orbit dependencies -->
<dependency> <dependency>
<groupId>com.h2database.wso2</groupId> <groupId>com.h2database.wso2</groupId>
<artifactId>h2-database-engine</artifactId> <artifactId>h2-database-engine</artifactId>

Loading…
Cancel
Save