mirror of
https://repository.entgra.net/community/device-mgt-core.git
synced 2025-10-06 02:01:45 +00:00
Merge branch 'reporting2' into 'reporting'
Reporting2 See merge request entgra/carbon-device-mgt!484
This commit is contained in:
commit
397e00d2f7
@ -86,6 +86,7 @@
|
|||||||
org.wso2.carbon.utils,
|
org.wso2.carbon.utils,
|
||||||
org.wso2.carbon.utils.multitenancy,
|
org.wso2.carbon.utils.multitenancy,
|
||||||
org.xml.sax,
|
org.xml.sax,
|
||||||
|
com.google.gson.*,
|
||||||
javax.servlet,
|
javax.servlet,
|
||||||
javax.servlet.http,
|
javax.servlet.http,
|
||||||
javax.xml,
|
javax.xml,
|
||||||
@ -215,6 +216,10 @@
|
|||||||
<groupId>org.wso2.carbon.devicemgt</groupId>
|
<groupId>org.wso2.carbon.devicemgt</groupId>
|
||||||
<artifactId>org.wso2.carbon.device.mgt.common</artifactId>
|
<artifactId>org.wso2.carbon.device.mgt.common</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.code.gson</groupId>
|
||||||
|
<artifactId>gson</artifactId>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.wso2.orbit.org.apache.httpcomponents</groupId>
|
<groupId>org.wso2.orbit.org.apache.httpcomponents</groupId>
|
||||||
<artifactId>httpclient</artifactId>
|
<artifactId>httpclient</artifactId>
|
||||||
|
|||||||
@ -22,6 +22,13 @@ import org.apache.catalina.connector.Response;
|
|||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
|
import org.wso2.carbon.base.MultitenantConstants;
|
||||||
|
import org.wso2.carbon.context.PrivilegedCarbonContext;
|
||||||
|
import org.wso2.carbon.user.api.UserRealm;
|
||||||
|
import org.wso2.carbon.user.api.UserStoreException;
|
||||||
|
import org.wso2.carbon.user.core.service.RealmService;
|
||||||
|
import org.wso2.carbon.utils.multitenancy.MultitenantUtils;
|
||||||
|
import org.wso2.carbon.webapp.authenticator.framework.internal.AuthenticatorFrameworkDataHolder;
|
||||||
|
|
||||||
import javax.xml.XMLConstants;
|
import javax.xml.XMLConstants;
|
||||||
import javax.xml.parsers.DocumentBuilder;
|
import javax.xml.parsers.DocumentBuilder;
|
||||||
@ -32,6 +39,7 @@ import java.io.IOException;
|
|||||||
public class AuthenticationFrameworkUtil {
|
public class AuthenticationFrameworkUtil {
|
||||||
|
|
||||||
private static final Log log = LogFactory.getLog(AuthenticationFrameworkUtil.class);
|
private static final Log log = LogFactory.getLog(AuthenticationFrameworkUtil.class);
|
||||||
|
private static final String UI_EXECUTE = "ui.execute";
|
||||||
|
|
||||||
static void handleResponse(Request request, Response response, int statusCode, String payload) {
|
static void handleResponse(Request request, Response response, int statusCode, String payload) {
|
||||||
response.setStatus(statusCode);
|
response.setStatus(statusCode);
|
||||||
@ -65,4 +73,43 @@ public class AuthenticationFrameworkUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static boolean isUserAuthorized(int tenantId, String tenantDomain, String username, String
|
||||||
|
permission) throws
|
||||||
|
AuthenticationException {
|
||||||
|
boolean tenantFlowStarted = false;
|
||||||
|
|
||||||
|
try{
|
||||||
|
//If this is a tenant user
|
||||||
|
if(tenantId != MultitenantConstants.SUPER_TENANT_ID){
|
||||||
|
PrivilegedCarbonContext.startTenantFlow();
|
||||||
|
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(tenantDomain);
|
||||||
|
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantId(tenantId);
|
||||||
|
PrivilegedCarbonContext.getThreadLocalCarbonContext().setUsername(username);
|
||||||
|
tenantFlowStarted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
RealmService realmService = AuthenticatorFrameworkDataHolder.getInstance().getRealmService();
|
||||||
|
if (realmService == null) {
|
||||||
|
String msg = "RealmService is not initialized";
|
||||||
|
log.error(msg);
|
||||||
|
throw new AuthenticationException(msg);
|
||||||
|
}
|
||||||
|
UserRealm userRealm = realmService.getTenantUserRealm(tenantId);
|
||||||
|
|
||||||
|
return userRealm.getAuthorizationManager()
|
||||||
|
.isUserAuthorized(MultitenantUtils
|
||||||
|
.getTenantAwareUsername(username), permission, UI_EXECUTE);
|
||||||
|
|
||||||
|
} catch (UserStoreException e) {
|
||||||
|
String msg = "Error while getting username";
|
||||||
|
log.error(msg, e);
|
||||||
|
throw new AuthenticationException(msg, e);
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
if (tenantFlowStarted) {
|
||||||
|
PrivilegedCarbonContext.endTenantFlow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,7 +22,7 @@ public final class Constants {
|
|||||||
|
|
||||||
public static final String AUTHORIZATION_HEADER_PREFIX_BEARER = "Bearer";
|
public static final String AUTHORIZATION_HEADER_PREFIX_BEARER = "Bearer";
|
||||||
public static final String NO_MATCHING_AUTH_SCHEME = "noMatchedAuthScheme";
|
public static final String NO_MATCHING_AUTH_SCHEME = "noMatchedAuthScheme";
|
||||||
public static final String PROXY_TENANT_ID = "ProxyTenantId";
|
public static final String PROXY_TENANT_ID = "Proxy-Tenant-Id";
|
||||||
|
|
||||||
public static final class HTTPHeaders {
|
public static final class HTTPHeaders {
|
||||||
private HTTPHeaders() {
|
private HTTPHeaders() {
|
||||||
|
|||||||
@ -18,9 +18,11 @@
|
|||||||
*/
|
*/
|
||||||
package org.wso2.carbon.webapp.authenticator.framework;
|
package org.wso2.carbon.webapp.authenticator.framework;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
import org.apache.catalina.Context;
|
import org.apache.catalina.Context;
|
||||||
import org.apache.catalina.connector.Request;
|
import org.apache.catalina.connector.Request;
|
||||||
import org.apache.catalina.connector.Response;
|
import org.apache.catalina.connector.Response;
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.owasp.encoder.Encode;
|
import org.owasp.encoder.Encode;
|
||||||
@ -42,12 +44,15 @@ public class WebappAuthenticationValve extends CarbonTomcatValve {
|
|||||||
|
|
||||||
private static final Log log = LogFactory.getLog(WebappAuthenticationValve.class);
|
private static final Log log = LogFactory.getLog(WebappAuthenticationValve.class);
|
||||||
private static TreeMap<String, String> nonSecuredEndpoints = new TreeMap<>();
|
private static TreeMap<String, String> nonSecuredEndpoints = new TreeMap<>();
|
||||||
|
private static final String PERMISSION_PREFIX = "/permission/admin";
|
||||||
|
public static final String AUTHORIZE_PERMISSION = "Authorize-Permission";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void invoke(Request request, Response response, CompositeValve compositeValve) {
|
public void invoke(Request request, Response response, CompositeValve compositeValve) {
|
||||||
|
|
||||||
if (this.isContextSkipped(request) || this.skipAuthentication(request)) {
|
if ((this.isContextSkipped(request) || this.skipAuthentication(request))
|
||||||
this.getNext().invoke(request, response, compositeValve);
|
&& (StringUtils.isEmpty(request.getHeader(AUTHORIZE_PERMISSION)))) {
|
||||||
|
this.getNext().invoke(request, response, compositeValve);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,6 +69,39 @@ public class WebappAuthenticationValve extends CarbonTomcatValve {
|
|||||||
authenticationInfo.setStatus(status);
|
authenticationInfo.setStatus(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This section will allow to validate a given access token is authenticated to access given
|
||||||
|
// resource(permission)
|
||||||
|
if (request.getCoyoteRequest() != null
|
||||||
|
&& StringUtils.isNotEmpty(request.getHeader(AUTHORIZE_PERMISSION))
|
||||||
|
&& (authenticationInfo.getStatus() == WebappAuthenticator.Status.CONTINUE ||
|
||||||
|
authenticationInfo.getStatus() == WebappAuthenticator.Status.SUCCESS)) {
|
||||||
|
boolean isAllowed;
|
||||||
|
try {
|
||||||
|
isAllowed = AuthenticationFrameworkUtil.isUserAuthorized(
|
||||||
|
authenticationInfo.getTenantId(), authenticationInfo.getTenantDomain(),
|
||||||
|
authenticationInfo.getUsername(),
|
||||||
|
PERMISSION_PREFIX + request.getHeader (AUTHORIZE_PERMISSION));
|
||||||
|
} catch (AuthenticationException e) {
|
||||||
|
String msg = "Could not authorize permission";
|
||||||
|
log.error(msg);
|
||||||
|
AuthenticationFrameworkUtil.handleResponse(request, response,
|
||||||
|
HttpServletResponse.SC_INTERNAL_SERVER_ERROR, msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isAllowed) {
|
||||||
|
Gson gson = new Gson();
|
||||||
|
AuthenticationFrameworkUtil.handleResponse(request, response, HttpServletResponse.SC_OK,
|
||||||
|
gson.toJson(authenticationInfo));
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
log.error("Unauthorized message from user " + authenticationInfo.getUsername());
|
||||||
|
AuthenticationFrameworkUtil.handleResponse(request, response,
|
||||||
|
HttpServletResponse.SC_FORBIDDEN, "Unauthorized to access the API");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Tenant tenant = null;
|
Tenant tenant = null;
|
||||||
if (authenticationInfo.getTenantId() != -1) {
|
if (authenticationInfo.getTenantId() != -1) {
|
||||||
try {
|
try {
|
||||||
@ -72,7 +110,8 @@ public class WebappAuthenticationValve extends CarbonTomcatValve {
|
|||||||
privilegedCarbonContext.setTenantId(authenticationInfo.getTenantId());
|
privilegedCarbonContext.setTenantId(authenticationInfo.getTenantId());
|
||||||
privilegedCarbonContext.setTenantDomain(authenticationInfo.getTenantDomain());
|
privilegedCarbonContext.setTenantDomain(authenticationInfo.getTenantDomain());
|
||||||
privilegedCarbonContext.setUsername(authenticationInfo.getUsername());
|
privilegedCarbonContext.setUsername(authenticationInfo.getUsername());
|
||||||
if (authenticationInfo.isSuperTenantAdmin()) {
|
if (authenticationInfo.isSuperTenantAdmin() && request.getHeader(Constants
|
||||||
|
.PROXY_TENANT_ID) != null) {
|
||||||
// If this is a call from super admin to an API and the ProxyTenantId is also
|
// If this is a call from super admin to an API and the ProxyTenantId is also
|
||||||
// present, this is a call that is made with super admin credentials to call
|
// present, this is a call that is made with super admin credentials to call
|
||||||
// an API on behalf of another tenant. Hence the actual tenants, details are
|
// an API on behalf of another tenant. Hence the actual tenants, details are
|
||||||
|
|||||||
@ -55,8 +55,9 @@ public class WebappAuthenticationValveTest {
|
|||||||
|
|
||||||
@Test(description = "This method tests the invoke method of the WebAppAuthenticationValve with the context path "
|
@Test(description = "This method tests the invoke method of the WebAppAuthenticationValve with the context path "
|
||||||
+ "starting with carbon")
|
+ "starting with carbon")
|
||||||
public void testInvokeWithContextSkippedScenario1() {
|
public void testInvokeWithContextSkippedScenario1() throws NoSuchFieldException, IllegalAccessException {
|
||||||
Request request = new Request();
|
Request request = new Request();
|
||||||
|
getCoyoteRequest(request);
|
||||||
Context context = new StandardContext();
|
Context context = new StandardContext();
|
||||||
context.setPath("carbon");
|
context.setPath("carbon");
|
||||||
CompositeValve compositeValve = Mockito.mock(CompositeValve.class);
|
CompositeValve compositeValve = Mockito.mock(CompositeValve.class);
|
||||||
@ -64,6 +65,7 @@ public class WebappAuthenticationValveTest {
|
|||||||
request.setContext(context);
|
request.setContext(context);
|
||||||
webappAuthenticationValve.invoke(request, null, compositeValve);
|
webappAuthenticationValve.invoke(request, null, compositeValve);
|
||||||
request = new TestRequest("", "test");
|
request = new TestRequest("", "test");
|
||||||
|
getCoyoteRequest(request);
|
||||||
context = new StandardContext();
|
context = new StandardContext();
|
||||||
compositeValve = Mockito.mock(CompositeValve.class);
|
compositeValve = Mockito.mock(CompositeValve.class);
|
||||||
Mockito.doNothing().when(compositeValve).continueInvocation(Mockito.any(), Mockito.any());
|
Mockito.doNothing().when(compositeValve).continueInvocation(Mockito.any(), Mockito.any());
|
||||||
@ -73,8 +75,9 @@ public class WebappAuthenticationValveTest {
|
|||||||
|
|
||||||
@Test(description = "This method tests the behaviour of the invoke method of WebAuthenticationValve when "
|
@Test(description = "This method tests the behaviour of the invoke method of WebAuthenticationValve when "
|
||||||
+ "un-secured endpoints are invoked.")
|
+ "un-secured endpoints are invoked.")
|
||||||
public void testInvokeUnSecuredEndpoints() {
|
public void testInvokeUnSecuredEndpoints() throws IllegalAccessException, NoSuchFieldException {
|
||||||
Request request = new TestRequest("", "test");
|
Request request = new TestRequest("", "test");
|
||||||
|
getCoyoteRequest(request);
|
||||||
Context context = new StandardContext();
|
Context context = new StandardContext();
|
||||||
context.setPath("carbon1");
|
context.setPath("carbon1");
|
||||||
context.addParameter("doAuthentication", String.valueOf(true));
|
context.addParameter("doAuthentication", String.valueOf(true));
|
||||||
@ -85,6 +88,22 @@ public class WebappAuthenticationValveTest {
|
|||||||
webappAuthenticationValve.invoke(request, null, compositeValve);
|
webappAuthenticationValve.invoke(request, null, compositeValve);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void getCoyoteRequest(Request request) throws
|
||||||
|
IllegalAccessException,
|
||||||
|
NoSuchFieldException {
|
||||||
|
|
||||||
|
Field headersField = org.apache.coyote.Request.class.getDeclaredField("headers");
|
||||||
|
headersField.setAccessible(true);
|
||||||
|
org.apache.coyote.Request coyoteRequest = new org.apache.coyote.Request();
|
||||||
|
|
||||||
|
MimeHeaders mimeHeaders = new MimeHeaders();
|
||||||
|
MessageBytes bytes = mimeHeaders.addValue("content-type");
|
||||||
|
bytes.setString("test");
|
||||||
|
|
||||||
|
headersField.set(coyoteRequest, mimeHeaders);
|
||||||
|
request.setCoyoteRequest(coyoteRequest);
|
||||||
|
}
|
||||||
|
|
||||||
@Test(description = "This method tests the behaviour of the invoke method of WebAuthenticationValve when "
|
@Test(description = "This method tests the behaviour of the invoke method of WebAuthenticationValve when "
|
||||||
+ "secured endpoints are invoked.")
|
+ "secured endpoints are invoked.")
|
||||||
public void testInvokeSecuredEndpoints() throws NoSuchFieldException, IllegalAccessException {
|
public void testInvokeSecuredEndpoints() throws NoSuchFieldException, IllegalAccessException {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user