An error occurred while loading the file. Please try again.
-
Sakthivel G authored3a0920be
package util;
import com.fasterxml.jackson.databind.JsonNode;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import org.apache.commons.lang3.StringUtils;
import org.sunbird.auth.verifier.AccessTokenValidator;
import org.sunbird.keys.JsonKey;
import org.sunbird.logging.LoggerUtil;
import org.sunbird.request.HeaderParam;
import play.mvc.Http;
/**
* Request interceptor responsible to authenticated HTTP requests
*
* @author Amit Kumar
*/
public class RequestInterceptor {
private static LoggerUtil logger = new LoggerUtil(RequestInterceptor.class);
public static List<String> restrictedUriList = null;
private static ConcurrentHashMap<String, Short> apiHeaderIgnoreMap = new ConcurrentHashMap<>();
private RequestInterceptor() {}
static {
restrictedUriList = new ArrayList<>();
restrictedUriList.add("/v1/user/update");
restrictedUriList.add("/v1/note/create");
restrictedUriList.add("/v1/note/update");
restrictedUriList.add("/v1/note/search");
restrictedUriList.add("/v1/note/read");
restrictedUriList.add("/v1/note/delete");
restrictedUriList.add("/v1/user/feed");
// ---------------------------
short var = 1;
apiHeaderIgnoreMap.put("/v1/user/create", var);
apiHeaderIgnoreMap.put("/v2/user/create", var);
apiHeaderIgnoreMap.put("/v2/org/search", var);
apiHeaderIgnoreMap.put("/v3/user/create", var);
apiHeaderIgnoreMap.put("/v1/user/signup", var);
apiHeaderIgnoreMap.put("/v2/user/signup", var);
apiHeaderIgnoreMap.put("/v1/ssouser/create", var);
apiHeaderIgnoreMap.put("/v1/org/search", var);
apiHeaderIgnoreMap.put("/service/health", var);
apiHeaderIgnoreMap.put("/health", var);
apiHeaderIgnoreMap.put("/v1/notification/email", var);
apiHeaderIgnoreMap.put("/v2/notification", var);
apiHeaderIgnoreMap.put("/v1/data/sync", var);
apiHeaderIgnoreMap.put("/v1/file/upload", var);
apiHeaderIgnoreMap.put("/v1/user/getuser", var);
// making org read as public access
apiHeaderIgnoreMap.put("/v1/org/read", var);
// making location APIs public access
apiHeaderIgnoreMap.put("/v1/location/create", var);
apiHeaderIgnoreMap.put("/v1/location/update", var);
apiHeaderIgnoreMap.put("/v1/location/search", var);
apiHeaderIgnoreMap.put("/v1/location/delete", var);
apiHeaderIgnoreMap.put("/v1/otp/generate", var);
apiHeaderIgnoreMap.put("/v1/otp/verify", var);
apiHeaderIgnoreMap.put("/v1/user/get/email", var);
apiHeaderIgnoreMap.put("/v1/user/get/phone", var);
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
apiHeaderIgnoreMap.put("/v1/system/settings/get", var);
apiHeaderIgnoreMap.put("/v1/system/settings/list", var);
apiHeaderIgnoreMap.put("/private/user/v1/search", var);
apiHeaderIgnoreMap.put("/private/user/v1/migrate", var);
apiHeaderIgnoreMap.put("/private/user/v1/identifier/freeup", var);
apiHeaderIgnoreMap.put("/private/user/v1/password/reset", var);
apiHeaderIgnoreMap.put("/v1/user/exists/email", var);
apiHeaderIgnoreMap.put("/v1/user/exists/phone", var);
apiHeaderIgnoreMap.put("/v1/role/read", var);
apiHeaderIgnoreMap.put("/private/user/v1/lookup", var);
apiHeaderIgnoreMap.put("/private/user/feed/v1/create", var);
}
private static String getUserRequestedFor(Http.Request request) {
String requestedForUserID = null;
JsonNode jsonBody = request.body().asJson();
try {
if (!(jsonBody == null)
&& !(jsonBody.get(JsonKey.REQUEST)
== null)) { // for search and update and create_mui api's
if (!(jsonBody.get(JsonKey.REQUEST).get(JsonKey.USER_ID) == null)) {
requestedForUserID = jsonBody.get(JsonKey.REQUEST).get(JsonKey.USER_ID).asText();
}
} else { // for read-api
String uuidSegment = null;
Path path = Paths.get(request.uri());
if (request.queryString().isEmpty()) {
uuidSegment = path.getFileName().toString();
} else {
String[] queryPath = path.getFileName().toString().split("\\?");
uuidSegment = queryPath[0];
}
try {
requestedForUserID = UUID.fromString(uuidSegment).toString();
} catch (IllegalArgumentException iae) {
logger.error("Perhaps this is another API, like search that doesn't carry user id.", iae);
}
}
} catch (Exception e) {
logger.error("Likely a possibility? " + request.uri(), e);
}
return requestedForUserID;
}
/**
* Authenticates given HTTP request context
*
* @param request HTTP play request
* @return User or Client ID for authenticated request. For unauthenticated requests, UNAUTHORIZED
* is returned release-3.0.0 on-wards validating managedBy token.
*/
public static Map verifyRequestData(Http.Request request) {
Map userAuthentication = new HashMap<String, String>();
userAuthentication.put(JsonKey.USER_ID, JsonKey.UNAUTHORIZED);
userAuthentication.put(JsonKey.MANAGED_FOR, null);
String clientId = JsonKey.UNAUTHORIZED;
String managedForId = null;
Optional<String> accessToken = request.header(HeaderParam.X_Authenticated_User_Token.getName());
if (!isRequestInExcludeList(request.path()) && !isRequestPrivate(request.path())) {
// The API must be invoked with either access token or client token.
if (accessToken.isPresent()) {
clientId = AccessTokenValidator.verifyUserToken(accessToken.get());
logger.info("**learner accesstoken verified :" + clientId);
if (!JsonKey.USER_UNAUTH_STATES.contains(clientId)) {
// Now we have some valid token, next verify if the token is matching the request.
String requestedForUserID = getUserRequestedFor(request);
if (StringUtils.isNotEmpty(requestedForUserID) && !requestedForUserID.equals(clientId)) {
// LUA - MUA user combo, check the 'for' token and its parent, child identifiers
Optional<String> forTokenHeader =
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
request.header(HeaderParam.X_Authenticated_For.getName());
String managedAccessToken = forTokenHeader.isPresent() ? forTokenHeader.get() : "";
if (StringUtils.isNotEmpty(managedAccessToken)) {
String managedFor =
AccessTokenValidator.verifyManagedUserToken(
managedAccessToken, clientId, requestedForUserID);
if (!JsonKey.USER_UNAUTH_STATES.contains(managedFor)) {
managedForId = managedFor;
} else {
clientId = JsonKey.UNAUTHORIZED;
}
logger.info("**learner managed accesstoken verified :" + clientId);
}
} else {
logger.debug("Ignoring x-authenticated-for token...");
}
}
logger.info("**learner added userid to userAuthentication :" + clientId);
userAuthentication.put(JsonKey.USER_ID, clientId);
userAuthentication.put(JsonKey.MANAGED_FOR, managedForId);
}
} else {
if (accessToken.isPresent()) {
String clientAccessTokenId = null;
try {
clientAccessTokenId = AccessTokenValidator.verifyUserToken(accessToken.get());
if (JsonKey.UNAUTHORIZED.equalsIgnoreCase(clientAccessTokenId)) {
clientAccessTokenId = null;
}
} catch (Exception ex) {
logger.error(ex.getMessage(), ex);
clientAccessTokenId = null;
}
userAuthentication.put(
JsonKey.USER_ID,
StringUtils.isNotBlank(clientAccessTokenId) ? clientAccessTokenId : JsonKey.ANONYMOUS);
} else {
userAuthentication.put(JsonKey.USER_ID, JsonKey.ANONYMOUS);
}
}
logger.info("**learner userAuthentication :" + userAuthentication.toString());
return userAuthentication;
}
private static boolean isRequestPrivate(String path) {
return path.contains(JsonKey.PRIVATE);
}
/**
* Checks if request URL is in excluded (i.e. public) URL list or not
*
* @param requestUrl Request URL
* @return True if URL is in excluded (public) URLs. Otherwise, returns false
*/
public static boolean isRequestInExcludeList(String requestUrl) {
boolean resp = false;
if (!StringUtils.isBlank(requestUrl)) {
if (apiHeaderIgnoreMap.containsKey(requestUrl)) {
resp = true;
} else {
String[] splitPath = requestUrl.split("[/]");
String urlWithoutPathParam = removeLastValue(splitPath);
if (apiHeaderIgnoreMap.containsKey(urlWithoutPathParam)) {
resp = true;
}
}
}
return resp;
}
211212213214215216217218219220221222223224225226227228
/**
* Returns URL without path and query parameters.
*
* @param splitPath URL path split on slash (i.e. /)
* @return URL without path and query parameters
*/
private static String removeLastValue(String splitPath[]) {
StringBuilder builder = new StringBuilder();
if (splitPath != null && splitPath.length > 0) {
for (int i = 1; i < splitPath.length - 1; i++) {
builder.append("/" + splitPath[i]);
}
}
return builder.toString();
}
}