From f25b69ec7e4359d6586383e678069c6fb68d9c0a Mon Sep 17 00:00:00 2001 From: pkapaleeswaran Date: Wed, 18 Apr 2018 18:19:37 +0000 Subject: [PATCH 0001/1906] Use this to customize and copy to your own client id key and such. SOCIAL C:\\Users\\pkapaleeswaran\\workspacej3\\MonolithDev4\\social.properties git-svn-id: svn://107.170.10.188:8080/Monolith/dev@27492 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 9e5d1f3f51bbebd0ae9b619463eb8745b572cbad --- social - Copy.properties | 49 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 social - Copy.properties diff --git a/social - Copy.properties b/social - Copy.properties new file mode 100644 index 000000000..ce8a3d151 --- /dev/null +++ b/social - Copy.properties @@ -0,0 +1,49 @@ +ms_authority https://login.microsoftonline.com/ +ms_tenant umweltoutlook.onmicrosoft.com +ms_client_id 88dd3ada-bde3-40f4-bdfd-ffafee14eb2d +ms_secret_key tnowmSRJG3995+[rpAAU1)} +ms_redirect_uri https://localhost:8443/Monolith/api/auth/login/ms +ms_scope User.Read.All People.Read.All Notes.ReadWrite.All Files.ReadWrite.All Mail.ReadWrite + + +git_client_id fa7d7e87dadda8f81010 +git_secret_key f643133c41bd828135b8783a5349f1a11e58ccca +git_redirect_uri https://localhost:8443/Monolith/api/auth/login/git +git_scope public_repo + +sf_client_id 3MVG9VmVOCGHKYBTBlNb_0gK2dzXQyp8BCpaRlwliCFRAOAyShcFh24TGLeVpJbw9cwshq378TZsXwCz9tjxZ +sf_secret_key 8073418897645717308 +sf_redirect_uri https://localhost:8443/Monolith/api/auth/login/sf + +dropbox_client_id nfqtet2kz9joqaa +dropbox_secret_key n6113ralaix4n4r +dropbox_role personal +dropbox_redirect_uri https://localhost:8443/Monolith/api/auth/login/dropbox + + +google_client_id 240368406693-g7985bej47c10fikkgr6ous6hpm95cbb.apps.googleusercontent.com +google_secret_key kEOyUUeWrOhvfmJ2PrsPB6SS +google_redirect_uri https://localhost:8443/Monolith/api/auth/login/google2 +google_scope https://www.googleapis.com/auth/forms https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/drive.metadata https://www.googleapis.com/auth/cloud-language +google_access_type online +google_maps_api ***REMOVED*** + +twitter_client_id ***REMOVED*** +twitter_secret_key ***REMOVED*** +twitter_redirect_uri https://localhost:8443/Monolith/api/auth/login/twitter + +in_client_id 77tg7s1lxx8mbh +in_secret_key eLCa8WsXquU8sPbl +in_redirect_uri https://localhost:8443/Monolith/api/auth/login/linkedin +in_scope r_network + + +producthunt_client_id 4d28e19836d50033c9329c55f30886f3f6e992e69732a2e48d80ad0d86466449 +producthunt_secret_key 88e5626b525eed525dc85b69c2c28f2a3476b54785c1f1106ef960f90617690a +producthunt_redirect_uri https://localhost:8443/Monolith/api/auth/login/producthunt +producthunt_scope public + +census_client_id d26315559398d855100a32a0ab1bfde2962d0cce + + + From 83fad161b6bc957829bb1d52b1cbcf7bd8508a54 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 18 Apr 2018 18:28:15 +0000 Subject: [PATCH 0002/1906] UPDATE ::: Pushing catch all for User Resource so if socialData doesn't load the application still does git-svn-id: svn://107.170.10.188:8080/Monolith/dev@27494 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 216d22ebaa9f7ac5cb603aee4e619886cb6cc184 --- .../semoss/web/services/UserResource.java | 43 +++++++++---------- 1 file changed, 21 insertions(+), 22 deletions(-) diff --git a/src/prerna/semoss/web/services/UserResource.java b/src/prerna/semoss/web/services/UserResource.java index 77e59c684..847702b0e 100644 --- a/src/prerna/semoss/web/services/UserResource.java +++ b/src/prerna/semoss/web/services/UserResource.java @@ -72,8 +72,6 @@ import javax.ws.rs.core.Response; import javax.ws.rs.core.StreamingOutput; -import jodd.util.URLDecoder; - import org.apache.http.HttpEntity; import org.apache.http.NameValuePair; import org.apache.http.client.ResponseHandler; @@ -87,6 +85,25 @@ import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; +import com.google.api.client.auth.oauth2.TokenResponseException; +import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeTokenRequest; +import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; +import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken; +import com.google.api.client.googleapis.auth.oauth2.GoogleTokenResponse; +import com.google.api.client.http.HttpTransport; +import com.google.api.client.http.javanet.NetHttpTransport; +import com.google.api.client.json.jackson2.JacksonFactory; +import com.google.api.services.oauth2.Oauth2; +import com.google.api.services.oauth2.model.Userinfoplus; +import com.google.gson.Gson; +import com.google.gson.internal.StringMap; +import com.restfb.DefaultFacebookClient; +import com.restfb.FacebookClient; +import com.restfb.Parameter; +import com.sun.jna.platform.win32.Secur32; +import com.sun.jna.platform.win32.Secur32Util; + +import jodd.util.URLDecoder; import prerna.auth.AccessToken; import prerna.auth.AuthProvider; import prerna.auth.CACReader; @@ -107,24 +124,6 @@ import prerna.web.services.util.WebUtility; import waffle.servlet.WindowsPrincipal; -import com.google.api.client.auth.oauth2.TokenResponseException; -import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeTokenRequest; -import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; -import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken; -import com.google.api.client.googleapis.auth.oauth2.GoogleTokenResponse; -import com.google.api.client.http.HttpTransport; -import com.google.api.client.http.javanet.NetHttpTransport; -import com.google.api.client.json.jackson2.JacksonFactory; -import com.google.api.services.oauth2.Oauth2; -import com.google.api.services.oauth2.model.Userinfoplus; -import com.google.gson.Gson; -import com.google.gson.internal.StringMap; -import com.restfb.DefaultFacebookClient; -import com.restfb.FacebookClient; -import com.restfb.Parameter; -import com.sun.jna.platform.win32.Secur32; -import com.sun.jna.platform.win32.Secur32Util; - @Path("/auth") public class UserResource { @@ -175,10 +174,10 @@ public static void loadConnectors() // also make the twit token and such } } catch (FileNotFoundException e) { - // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { - // TODO Auto-generated catch block + e.printStackTrace(); + } catch (Exception e) { e.printStackTrace(); } } From e4a2aa48799548a673a6e830ab0f4054bca8a1d7 Mon Sep 17 00:00:00 2001 From: pkapaleeswaran Date: Sat, 21 Apr 2018 02:31:49 +0000 Subject: [PATCH 0003/1906] JSoup for Web Scraper git-svn-id: svn://107.170.10.188:8080/Monolith/dev@27515 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 0bc660bd9dadd3d8c76e34823d2a03345e89be3e --- pom.xml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/pom.xml b/pom.xml index 3a7c0d676..495f501bf 100644 --- a/pom.xml +++ b/pom.xml @@ -2365,6 +2365,22 @@ jmespath-jackson 0.2.0 + + com.microsoft.azure + adal4j + 1.1.1 + + + com.nimbusds + oauth2-oidc-sdk + 4.5 + + + + org.jsoup + jsoup + 1.11.3 + \ No newline at end of file From 3f9b43455363d2ef601f68a14afa58248c044c89 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 23 Apr 2018 17:58:07 +0000 Subject: [PATCH 0004/1906] UPDATE ::: Shifting streaming from taking the map of processed noun metas to doing it in the stream w/ the pixel runner git-svn-id: svn://107.170.10.188:8080/Monolith/dev@27521 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 136670371d8bb43afcb19dedf1838328be06f333 --- .../semoss/web/services/NameServer.java | 91 ++++---- src/prerna/web/services/util/WebUtility.java | 195 ++++-------------- 2 files changed, 87 insertions(+), 199 deletions(-) diff --git a/src/prerna/semoss/web/services/NameServer.java b/src/prerna/semoss/web/services/NameServer.java index 5a946e743..3636c3723 100644 --- a/src/prerna/semoss/web/services/NameServer.java +++ b/src/prerna/semoss/web/services/NameServer.java @@ -83,6 +83,10 @@ import org.apache.solr.common.SolrDocumentList; import org.jsoup.Jsoup; +import com.google.gson.Gson; +import com.google.gson.internal.StringMap; +import com.google.gson.reflect.TypeToken; + import prerna.auth.User; import prerna.auth.User2; import prerna.auth.UserPermissionsMasterDB; @@ -93,6 +97,7 @@ import prerna.om.Insight; import prerna.om.InsightStore; import prerna.sablecc.PKQLRunner; +import prerna.sablecc2.PixelRunner; import prerna.sablecc2.comm.JobManager; import prerna.sablecc2.comm.JobThread; import prerna.sablecc2.reactor.utils.ImageCaptureReactor; @@ -115,10 +120,6 @@ import prerna.web.services.util.SemossThread; import prerna.web.services.util.WebUtility; -import com.google.gson.Gson; -import com.google.gson.internal.StringMap; -import com.google.gson.reflect.TypeToken; - @Path("/engine") public class NameServer { @@ -1211,47 +1212,49 @@ public Response runPixelSync(MultivaluedMap form, @Context HttpS // return WebUtility.getResponse(errorMap, 400); // } } - if(insight != null) - { - synchronized(insight) { - insight.setUser(user); - - // set the other user - insight.setUser2(user2); - JobManager manager = JobManager.getManager(); - JobThread jt = null; - if(insightId.equals(tempInsightId)) { - jt = manager.makeJob(); - } else { - jt = manager.makeJob(insightId); - } - jobId = jt.getJobId(); - session.setAttribute(jobId+"", "TRUE"); - String job = "META | Job(\"" + jobId + "\", \"" + insightId + "\", \"" + sessionId + "\");"; - expression = job + expression; - - jt.setInsight(insight); - jt.addPixel(expression); - jt.run(); - dataReturn = jt.getOutput(); - Vector pixelReturnVector = (Vector)dataReturn.get("pixelReturn"); - // TODO: need FE to not react based on the size ... - // but basically want to return an error - // but dont want to show the implicit Job reactor we are adding - if(pixelReturnVector.size() > 1) { - pixelReturnVector.remove(0); - } else { - // this is most likely due to an error with compiling the expression being sent - String newExp = (String) ((Map) pixelReturnVector.get(0)).get("pixelExpression"); - newExp = newExp.replace(job, ""); - ((Map) pixelReturnVector.get(0)).put("pixelExpression", newExp); - } - dataReturn.put("pixelReturn", pixelReturnVector); - // i need to kill this job - manager.flushJob(jobId); + synchronized(insight) { + insight.setUser(user); + + // set the other user + insight.setUser2(user2); + JobManager manager = JobManager.getManager(); + JobThread jt = null; + if(insightId.equals(tempInsightId)) { + jt = manager.makeJob(); + } else { + jt = manager.makeJob(insightId); } - } - return WebUtility.getResponse(dataReturn, 200); + jobId = jt.getJobId(); + session.setAttribute(jobId+"", "TRUE"); + String job = "META | Job(\"" + jobId + "\", \"" + insightId + "\", \"" + sessionId + "\");"; + expression = job + expression; + + jt.setInsight(insight); + jt.addPixel(expression); + jt.run2(); + PixelRunner pixelRunner = jt.getRunner(); + + manager.flushJob(jobId); + return Response.status(200).entity(WebUtility.collectPixelData(pixelRunner)).build(); + + // jt.run(); + // dataReturn = jt.getOutput(); + // Vector pixelReturnVector = (Vector)dataReturn.get("pixelReturn"); + // // TODO: need FE to not react based on the size ... + // // but basically want to return an error + // // but dont want to show the implicit Job reactor we are adding + // if(pixelReturnVector.size() > 1) { + // pixelReturnVector.remove(0); + // } else { + // // this is most likely due to an error with compiling the expression being sent + // String newExp = (String) ((Map) pixelReturnVector.get(0)).get("pixelExpression"); + // newExp = newExp.replace(job, ""); + // ((Map) pixelReturnVector.get(0)).put("pixelExpression", newExp); + // } + // dataReturn.put("pixelReturn", pixelReturnVector); + // // i need to kill this job + // manager.flushJob(jobId); + } } @POST diff --git a/src/prerna/web/services/util/WebUtility.java b/src/prerna/web/services/util/WebUtility.java index 8aa14a77e..4da931073 100644 --- a/src/prerna/web/services/util/WebUtility.java +++ b/src/prerna/web/services/util/WebUtility.java @@ -32,7 +32,6 @@ import java.io.PrintStream; import java.io.UnsupportedEncodingException; import java.lang.reflect.Modifier; -import java.util.Iterator; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Response; @@ -44,7 +43,8 @@ import com.google.gson.GsonBuilder; import prerna.date.SemossDate; -import prerna.ds.export.gexf.IGexfIterator; +import prerna.sablecc2.PixelRunner; +import prerna.sablecc2.PixelStreamUtility; import prerna.util.gson.NumberAdapter; import prerna.util.gson.SemossDateAdapter; @@ -54,8 +54,18 @@ */ public class WebUtility { - public static int id = 0; - static Logger logger = Logger.getLogger(prerna.web.services.util.WebUtility.class); + private static final String CLASS_NAME = WebUtility.class.getName(); + private static final Logger LOGGER = Logger.getLogger(CLASS_NAME); + + private static Gson getDefaultGson() { + Gson gson = new GsonBuilder() + .disableHtmlEscaping() + .excludeFieldsWithModifiers(Modifier.STATIC, Modifier.TRANSIENT) + .registerTypeAdapter(Double.class, new NumberAdapter()) + .registerTypeAdapter(SemossDate.class, new SemossDateAdapter()) + .create(); + return gson; + } public static StreamingOutput getSO(Object vec) { @@ -74,13 +84,13 @@ public void write(OutputStream outputStream) throws IOException, WebApplicationE }}; } catch (UnsupportedEncodingException e) { e.printStackTrace(); - logger.error("Failed to write object to stream"); + LOGGER.error("Failed to write object to stream"); } } - + return null; } - + public static Response getResponse(Object vec, int status) { if(vec != null) { Gson gson = getDefaultGson(); @@ -93,11 +103,11 @@ public static Response getResponse(Object vec, int status) { } return Response.status(200).entity(WebUtility.getSO(vec)).build(); } - + return null; } - - public static StreamingOutput getSO(byte[] output2) + + public static StreamingOutput getSO(byte[] output) { try { return new StreamingOutput() { @@ -105,163 +115,38 @@ public void write(OutputStream outputStream) throws IOException, WebApplicationE try( PrintStream ps = new PrintStream(outputStream); //using try with resources to automatically close PrintStream object since it implements AutoCloseable ){ - ps.write(output2, 0 , output2.length); + ps.write(output, 0 , output.length); } }}; } catch (Exception e) { e.printStackTrace(); - logger.error("Failed to write object to stream"); + LOGGER.error("Failed to write object to stream"); } - - return null; - } - - public static StreamingOutput getSO(String insightId, String [] headers, Iterator iterator) - { - if(iterator != null) - { - Gson gson = getDefaultGson(); - try { - return new StreamingOutput() { - public void write(OutputStream outputStream) throws IOException, WebApplicationException { - try( - PrintStream ps = new PrintStream(outputStream); //using try with resources to automatically close PrintStream object since it implements AutoCloseable - ) - { - String headerStr ="{\"headers\": "; - ps.print(headerStr); - String headerOutput = gson.toJson(headers); - ps.print(headerOutput); - ps.flush(); - - ps.print(", \"data\": ["); - ps.flush(); - while(iterator.hasNext()) - { - Object obj = iterator.next(); - ps.print(gson.toJson(obj)); - if(iterator.hasNext()) - ps.print(", "); - ps.flush(); - } - byte[] insight = new String("] , \"insightID\": \"" + insightId + "\" }").getBytes("UTF8"); - ps.write(insight, 0 , insight.length); - ps.flush(); - } - }}; - } catch (Exception e) { - logger.error("Failed to write object to stream"); - } - } return null; } - -// public static Response getResponse(String insightId, IGraphExporter iterator) { -// if(iterator != null) { -// StringBuilder builder = new StringBuilder(); -// builder.append("{").append("\"insightID\":\"").append(insightId).append("\","); -// Gson gson = getDefaultGson(); -// try { -// List> edges = new ArrayList>(); -// while(iterator.hasNextEdge()) { -// edges.add(iterator.getNextEdge()); -// } -// builder.append("\"edges\":").append(gson.toJson(edges)).append(","); -// -// List> vertices = new ArrayList>(); -// while(iterator.hasNextVert()) { -// vertices.add(iterator.getNextVert()); -// } -// builder.append("\"nodes\":").append(gson.toJson(vertices)).append(","); -// -// // add the meta data pieces -// builder.append("\"graphMeta\":").append(gson.toJson(iterator.getVertCounts())); -// builder.append("}"); -// final byte[] output = builder.toString().getBytes("UTF8"); -// int length = output.length; -// return Response.status(200).entity(WebUtility.getSO(output)).header("Content-Length", length).build(); -// } catch (UnsupportedEncodingException e) { -// e.printStackTrace(); -// } -// return Response.status(200).entity(WebUtility.getSO(insightId)).build(); -// } -// -// return null; -// } - - public static StreamingOutput getSO(String insightId, IGexfIterator gexf) { - if(gexf != null) { - try { - Gson gson = getDefaultGson(); - return new StreamingOutput() { - public void write(OutputStream outputStream) throws IOException, WebApplicationException { - try( - PrintStream ps = new PrintStream(outputStream); //using try with resources to automatically close PrintStream object since it implements AutoCloseable - ) - { - // note: to be able to stream this - // we have to substring the outputs after being gson'ed - // so that the gexf points to a single string - - // get start of gexf - ps.print("{\"gexf\": \""); - ps.flush(); - String out = gson.toJson( gexf.getStartString() ); - ps.print( out.substring(1, out.length()-1) ); - ps.flush(); - - // print the nodes - out = gson.toJson( gexf.getNodeStart()); - ps.print( out.substring(1, out.length()-1) ); - ps.flush(); - while(gexf.hasNextNode()) { - out = gson.toJson( gexf.getNextNodeString()); - ps.print( out.substring(1, out.length()-1) ); - ps.flush(); - } - out = gson.toJson( gexf.getNodeEnd()); - ps.print( out.substring(1, out.length()-1) ); - ps.flush(); - // print the edges - out = gson.toJson( gexf.getEdgeStart()); - ps.print( out.substring(1, out.length()-1) ); - ps.flush(); - while(gexf.hasNextEdge()) { - out = gson.toJson( gexf.getNextEdgeString()); - ps.print( out.substring(1, out.length()-1) ); - ps.flush(); - } - out = gson.toJson( gexf.getEdgeEnd()); - ps.print( out.substring(1, out.length()-1) ); - ps.flush(); + /** + * Collect pixel data from the runner + * @param runner + * @return + */ + public static StreamingOutput collectPixelData(PixelRunner runner) { + // get the default gson object + Gson gson = getDefaultGson(); - // end the gexf - out = gson.toJson( gexf.getEndString()); - ps.print( out.substring(1, out.length()-1) ); - ps.flush(); - - byte[] insight = new String("\" , \"insightID\": \"" + insightId + "\" }").getBytes("UTF8"); - ps.write(insight, 0 , insight.length); - ps.flush(); - ps.close(); - } - }}; - } catch (Exception e) { - logger.error("Failed to write object to stream"); - } + // now process everything + try { + return new StreamingOutput() { + public void write(OutputStream outputStream) throws IOException, WebApplicationException { + try(PrintStream ps = new PrintStream(outputStream)) { + PixelStreamUtility.processPixelRunner(ps, gson, runner); + } + }}; + } catch (Exception e) { + LOGGER.error("Failed to write object to stream"); } return null; } - private static Gson getDefaultGson() { - Gson gson = new GsonBuilder() - .disableHtmlEscaping() - .excludeFieldsWithModifiers(Modifier.STATIC, Modifier.TRANSIENT) - .registerTypeAdapter(Double.class, new NumberAdapter()) - .registerTypeAdapter(SemossDate.class, new SemossDateAdapter()) - .create(); - return gson; - } } From de95a565974ae33c8eebbd79948a22e86934ab06 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 23 Apr 2018 18:11:08 +0000 Subject: [PATCH 0005/1906] UPDATE ::: Fixing error with running saved insight git-svn-id: svn://107.170.10.188:8080/Monolith/dev@27522 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 509c1e2479757dfabd89b1e0774fbe221d03b0ff --- src/prerna/web/services/util/WebUtility.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/prerna/web/services/util/WebUtility.java b/src/prerna/web/services/util/WebUtility.java index 4da931073..35d5b2b94 100644 --- a/src/prerna/web/services/util/WebUtility.java +++ b/src/prerna/web/services/util/WebUtility.java @@ -140,7 +140,8 @@ public static StreamingOutput collectPixelData(PixelRunner runner) { return new StreamingOutput() { public void write(OutputStream outputStream) throws IOException, WebApplicationException { try(PrintStream ps = new PrintStream(outputStream)) { - PixelStreamUtility.processPixelRunner(ps, gson, runner); + // we want to ignore the first index since it will be a job + PixelStreamUtility.processPixelRunner(ps, gson, runner, true); } }}; } catch (Exception e) { From 123ce4bddf808da1feba1bbea561f27a456dbbe2 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 23 Apr 2018 19:37:05 +0000 Subject: [PATCH 0006/1906] UPDATE ::: Creating new web utility where stream is contained within the class instead of using web utility and passing to pixel stream utility git-svn-id: svn://107.170.10.188:8080/Monolith/dev@27523 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 246547ffa11c1f710ffaf83771b31b4ac2f6dbcc --- .../semoss/web/services/NameServer.java | 3 +- .../web/services/util/PixelWebUtility.java | 274 ++++++++++++++++++ src/prerna/web/services/util/WebUtility.java | 28 +- 3 files changed, 277 insertions(+), 28 deletions(-) create mode 100644 src/prerna/web/services/util/PixelWebUtility.java diff --git a/src/prerna/semoss/web/services/NameServer.java b/src/prerna/semoss/web/services/NameServer.java index 3636c3723..039d00558 100644 --- a/src/prerna/semoss/web/services/NameServer.java +++ b/src/prerna/semoss/web/services/NameServer.java @@ -115,6 +115,7 @@ import prerna.util.Utility; import prerna.util.insight.InsightScreenshot; import prerna.util.insight.TextToGraphic; +import prerna.web.services.util.PixelWebUtility; import prerna.web.services.util.ResponseHashSingleton; import prerna.web.services.util.SemossExecutorSingleton; import prerna.web.services.util.SemossThread; @@ -1235,7 +1236,7 @@ public Response runPixelSync(MultivaluedMap form, @Context HttpS PixelRunner pixelRunner = jt.getRunner(); manager.flushJob(jobId); - return Response.status(200).entity(WebUtility.collectPixelData(pixelRunner)).build(); + return Response.status(200).entity(PixelWebUtility.collectPixelData(pixelRunner)).build(); // jt.run(); // dataReturn = jt.getOutput(); diff --git a/src/prerna/web/services/util/PixelWebUtility.java b/src/prerna/web/services/util/PixelWebUtility.java new file mode 100644 index 000000000..b5a7c0dfc --- /dev/null +++ b/src/prerna/web/services/util/PixelWebUtility.java @@ -0,0 +1,274 @@ +package prerna.web.services.util; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.PrintStream; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.StreamingOutput; + +import org.apache.log4j.Logger; + +import com.google.gson.Gson; + +import prerna.algorithm.api.ITableDataFrame; +import prerna.engine.api.IHeadersDataRow; +import prerna.om.Insight; +import prerna.sablecc2.PixelRunner; +import prerna.sablecc2.PixelUtility; +import prerna.sablecc2.om.PixelDataType; +import prerna.sablecc2.om.nounmeta.NounMetadata; +import prerna.sablecc2.om.task.ConstantDataTask; +import prerna.sablecc2.om.task.ITask; +import prerna.sablecc2.reactor.frame.FrameFactory; + +public class PixelWebUtility extends WebUtility{ + + private static final String CLASS_NAME = PixelWebUtility.class.getName(); + private static final Logger LOGGER = Logger.getLogger(CLASS_NAME); + + /** + * Collect pixel data from the runner + * @param runner + * @return + */ + public static StreamingOutput collectPixelData(PixelRunner runner) { + // get the default gson object + Gson gson = getDefaultGson(); + + // now process everything + try { + return new StreamingOutput() { + public void write(OutputStream outputStream) throws IOException, WebApplicationException { + try(PrintStream ps = new PrintStream(outputStream)) { + // we want to ignore the first index since it will be a job + processPixelRunner(ps, gson, runner, true); + } + }}; + } catch (Exception e) { + LOGGER.error("Failed to write object to stream"); + } + return null; + } + + private static void processPixelRunner(PrintStream ps, Gson gson, PixelRunner runner, boolean ignoreFirst) { + // get the values we need from the runner + Insight in = runner.getInsight(); + List resultList = runner.getResults(); + // get the expression which created the return + // this matches with the above by index + List pixelStrings = runner.getPixelExpressions(); + List isMeta = runner.isMeta(); + Map encodedTextToOriginal = runner.getEncodedTextToOriginal(); + boolean invalidSyntax = runner.isInvalidSyntax(); + + // start of the map + // and the insight id + ps.print("{\"insightID\":\"" + in.getInsightId() + "\","); + ps.flush(); + + // now flush array of pixel returns + ps.println("\"pixelReturn\":["); + int size = pixelStrings.size(); + + // THIS IS BECAUSE WE APPEND THE JOB PIXEL + // BUT FE DOENS'T RESPOND TO IT AND NEED TO REMOVE IT + // HOWEVER, IF THE SIZE IS JUST 1, IT MEANS THAT THERE WAS + // AN ERROR THAT OCCURED + // but when we run a saved insight within a pixel + // we do not want to shift the index + int startIndex = 0; + if(ignoreFirst) { + startIndex = 1; + } + if(size == 1) { + startIndex = 0; + } + for (int i = startIndex; i < size; i++) { + NounMetadata noun = resultList.get(i); + String expression = pixelStrings.get(i); + expression = PixelUtility.recreateOriginalPixelExpression(expression, encodedTextToOriginal); + boolean meta = isMeta.get(i); + processNounMetadata(ps, gson, noun, expression, meta); + + // update the pixel list to say this is routine is valid + // TODO: need to set this inside the translation directly!!! + if (!meta && !invalidSyntax) { + // update the insight recipe + in.getPixelRecipe().add(expression); + } + + // add a comma for the next item in the list + if( (i+1) != size) { + ps.print(","); + ps.flush(); + } + } + + // now close of the array and the map + ps.print("]}"); + ps.flush(); + } + + + /** + * Process the noun metadata for consumption on the FE + * @param noun + * @return + */ + private static void processNounMetadata(PrintStream ps, Gson gson, NounMetadata noun, String expression, Boolean isMeta) { + ps.print("{"); + + // add expression if there + if(expression != null) { + ps.print("\"pixelExpression\":" + gson.toJson(expression) + ","); + } + // add is meta if there + if(isMeta != null) { + ps.print("\"isMeta\":" + isMeta + ","); + } + + PixelDataType nounT = noun.getNounType(); + if(nounT == PixelDataType.FRAME) { + // if we have a frame + // return the table name of the frame + // FE needs this to create proper QS + // this has no meaning for graphs + Map frameData = new HashMap(); + ITableDataFrame frame = (ITableDataFrame) noun.getValue(); + frameData.put("type", FrameFactory.getFrameType(frame)); + String name = frame.getTableName(); + if(name != null) { + frameData.put("name", name); + } + + ps.print("\"output\":"); + ps.print(gson.toJson(frameData)); + ps.print(",\"operationType\":"); + ps.print(gson.toJson(noun.getOpType())); + + // add additional outputs + List addReturns = noun.getAdditionalReturn(); + int numOutputs = addReturns.size(); + if(numOutputs > 0) { + ps.print(",\"additionalOutput\":["); + for(int i = 0; i < numOutputs; i++) { + processNounMetadata(ps, gson, addReturns.get(i), null, null); + } + ps.print("]"); + } + + } else if(nounT == PixelDataType.CODE || nounT == PixelDataType.TASK_LIST) { + // code is a tough one to process + // since many operations could have been performed + // we need to loop through a set of noun meta datas to output + List codeOutputs = (List) noun.getValue(); + int numOutputs = codeOutputs.size(); + if(numOutputs > 0) { + ps.print("\"output\":["); + for(int i = 0; i < numOutputs; i++) { + processNounMetadata(ps, gson, codeOutputs.get(i), null, null); + } + ps.print("]"); + } + ps.print(",\"operationType\":"); + ps.print(gson.toJson(noun.getOpType())); + } + + else if(nounT == PixelDataType.FORMATTED_DATA_SET) { + // if we have a task + // we gotta iterate through it to return the data + ITask task = (ITask) noun.getValue(); + String formatType = task.getFormatter().getFormatType(); + Map taskMeta = task.getMeta(); + + if(formatType.equals("TABLE")) { + ps.print("\"output\":{"); + if(task instanceof ConstantDataTask) { + ps.print("\"data\":" + gson.toJson( ((ConstantDataTask) task).getOutputData())); + ps.flush(); + } else { + // right now, only grid will work + ps.print("\"data\":{" ); + + boolean first = true; + String[] headers = null; + while(task.hasNext()) { + IHeadersDataRow row = task.next(); + // need to set the headers + if(headers == null) { + headers = row.getHeaders(); + ps.print("\"values\":["); + } + + if(!first) { + ps.print(","); + } + ps.print(gson.toJson(row.getValues())); + ps.flush(); + + first = false; + } + // end the values and add the headers + ps.print("],\"headers\":" + gson.toJson(headers)); + ps.print("}" ); + } + + for(String taskMetaKey : taskMeta.keySet()) { + ps.print(",\"" + taskMetaKey + "\":" + gson.toJson(taskMeta.get(taskMetaKey))); + ps.flush(); + } + ps.print(",\"taskId\":\"" + task.getId() + "\""); + ps.print("}"); + ps.print(",\"operationType\":"); + ps.print(gson.toJson(noun.getOpType())); + + } else { + // TODO + // THIS IS TEMPORARY UNTIL I FIGURE OUT HOW TO DO + // GRAPHS OR OTHER TYPES OF FORMATS + ps.print("\"output\":"); + ps.print(gson.toJson(task.collect(500, true))); + ps.flush(); + ps.print(",\"operationType\":"); + ps.print(gson.toJson(noun.getOpType())); + ps.flush(); + } + } + + // running a saved insight + else if(nounT == PixelDataType.PIXEL_RUNNER) { + PixelRunner runner = (PixelRunner) noun.getValue(); + Insight in = runner.getInsight(); + ps.print("\"output\":{"); + ps.print("\"name\":" + gson.toJson(in.getInsightName())); + ps.print(",\"core_engine\":" + gson.toJson(in.getEngineName())); + ps.print(",\"core_engine_id\":" + gson.toJson(in.getRdbmsId())); + ps.flush(); + ps.print(",\"insightData\":"); + // process the inner recipe + processPixelRunner(ps, gson, runner, false); + ps.print("}"); + ps.print(",\"operationType\":"); + ps.print(gson.toJson(noun.getOpType())); + ps.flush(); + + //TODO: account for params!!!! + } + + // everything else is simple + else { + ps.print("\"output\":"); + ps.print(gson.toJson(noun.getValue())); + ps.print(",\"operationType\":"); + ps.print(gson.toJson(noun.getOpType())); + } + + // close the map + ps.print("}"); + ps.flush(); + } +} diff --git a/src/prerna/web/services/util/WebUtility.java b/src/prerna/web/services/util/WebUtility.java index 35d5b2b94..d304747a6 100644 --- a/src/prerna/web/services/util/WebUtility.java +++ b/src/prerna/web/services/util/WebUtility.java @@ -43,8 +43,6 @@ import com.google.gson.GsonBuilder; import prerna.date.SemossDate; -import prerna.sablecc2.PixelRunner; -import prerna.sablecc2.PixelStreamUtility; import prerna.util.gson.NumberAdapter; import prerna.util.gson.SemossDateAdapter; @@ -57,7 +55,7 @@ public class WebUtility { private static final String CLASS_NAME = WebUtility.class.getName(); private static final Logger LOGGER = Logger.getLogger(CLASS_NAME); - private static Gson getDefaultGson() { + protected static Gson getDefaultGson() { Gson gson = new GsonBuilder() .disableHtmlEscaping() .excludeFieldsWithModifiers(Modifier.STATIC, Modifier.TRANSIENT) @@ -126,28 +124,4 @@ public void write(OutputStream outputStream) throws IOException, WebApplicationE return null; } - /** - * Collect pixel data from the runner - * @param runner - * @return - */ - public static StreamingOutput collectPixelData(PixelRunner runner) { - // get the default gson object - Gson gson = getDefaultGson(); - - // now process everything - try { - return new StreamingOutput() { - public void write(OutputStream outputStream) throws IOException, WebApplicationException { - try(PrintStream ps = new PrintStream(outputStream)) { - // we want to ignore the first index since it will be a job - PixelStreamUtility.processPixelRunner(ps, gson, runner, true); - } - }}; - } catch (Exception e) { - LOGGER.error("Failed to write object to stream"); - } - return null; - } - } From ca0818bd1b465b052772fcdda3c0e867146d54a8 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 23 Apr 2018 19:49:38 +0000 Subject: [PATCH 0007/1906] UPDATE ::: Adding metadata to return for open insight git-svn-id: svn://107.170.10.188:8080/Monolith/dev@27525 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 4fac6f5528a7a759fe67fdfd4a82733f5d9642c0 --- src/prerna/web/services/util/PixelWebUtility.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/prerna/web/services/util/PixelWebUtility.java b/src/prerna/web/services/util/PixelWebUtility.java index b5a7c0dfc..3995e4fee 100644 --- a/src/prerna/web/services/util/PixelWebUtility.java +++ b/src/prerna/web/services/util/PixelWebUtility.java @@ -241,12 +241,18 @@ else if(nounT == PixelDataType.FORMATTED_DATA_SET) { // running a saved insight else if(nounT == PixelDataType.PIXEL_RUNNER) { - PixelRunner runner = (PixelRunner) noun.getValue(); + Map runnerWraper = (Map) noun.getValue(); + PixelRunner runner = (PixelRunner) runnerWraper.get("runner"); + Object params = runnerWraper.get("params"); + List additionalPixels = (List) runnerWraper.get("additionalPixels"); + Insight in = runner.getInsight(); ps.print("\"output\":{"); ps.print("\"name\":" + gson.toJson(in.getInsightName())); ps.print(",\"core_engine\":" + gson.toJson(in.getEngineName())); ps.print(",\"core_engine_id\":" + gson.toJson(in.getRdbmsId())); + ps.print(",\"params\":" + gson.toJson(params)); + ps.print(",\"additionalPixels\":" + gson.toJson(additionalPixels)); ps.flush(); ps.print(",\"insightData\":"); // process the inner recipe From 965b99a018c48ee15ac175555d810bcd09a145c9 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 24 Apr 2018 14:19:03 +0000 Subject: [PATCH 0008/1906] UPDATE ::: Storing number collected on the task since collect no longer pulls from the iterator git-svn-id: svn://107.170.10.188:8080/Monolith/dev@27548 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 5fcaf8e021008376c53a5ee4f6407401c6d60890 --- src/prerna/web/services/util/PixelWebUtility.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prerna/web/services/util/PixelWebUtility.java b/src/prerna/web/services/util/PixelWebUtility.java index 3995e4fee..0e8737f8e 100644 --- a/src/prerna/web/services/util/PixelWebUtility.java +++ b/src/prerna/web/services/util/PixelWebUtility.java @@ -231,7 +231,7 @@ else if(nounT == PixelDataType.FORMATTED_DATA_SET) { // THIS IS TEMPORARY UNTIL I FIGURE OUT HOW TO DO // GRAPHS OR OTHER TYPES OF FORMATS ps.print("\"output\":"); - ps.print(gson.toJson(task.collect(500, true))); + ps.print(gson.toJson(task.collect(true))); ps.flush(); ps.print(",\"operationType\":"); ps.print(gson.toJson(noun.getOpType())); From a1086f35e313915fbf0a3af16eb8fefa81eefc4c Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 24 Apr 2018 14:31:51 +0000 Subject: [PATCH 0009/1906] UPDATE ::: Using the num collected for flushing git-svn-id: svn://107.170.10.188:8080/Monolith/dev@27551 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 942639eb7a22340bb3e8f601057c43cb162fe926 --- src/prerna/web/services/util/PixelWebUtility.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/prerna/web/services/util/PixelWebUtility.java b/src/prerna/web/services/util/PixelWebUtility.java index 0e8737f8e..83edf5e3c 100644 --- a/src/prerna/web/services/util/PixelWebUtility.java +++ b/src/prerna/web/services/util/PixelWebUtility.java @@ -182,6 +182,8 @@ else if(nounT == PixelDataType.FORMATTED_DATA_SET) { // if we have a task // we gotta iterate through it to return the data ITask task = (ITask) noun.getValue(); + int numCollect = task.getNumCollect(); + boolean collectAll = numCollect == -1; String formatType = task.getFormatter().getFormatType(); Map taskMeta = task.getMeta(); @@ -196,7 +198,9 @@ else if(nounT == PixelDataType.FORMATTED_DATA_SET) { boolean first = true; String[] headers = null; - while(task.hasNext()) { + int count = 0; + // recall, a task is also an iterator! + while(task.hasNext() && (collectAll || count < numCollect)) { IHeadersDataRow row = task.next(); // need to set the headers if(headers == null) { @@ -211,6 +215,7 @@ else if(nounT == PixelDataType.FORMATTED_DATA_SET) { ps.flush(); first = false; + count++; } // end the values and add the headers ps.print("],\"headers\":" + gson.toJson(headers)); From 00716df9ec53fe12bda15e8189a3d9b173744c8d Mon Sep 17 00:00:00 2001 From: pkapaleeswaran Date: Tue, 24 Apr 2018 17:40:57 +0000 Subject: [PATCH 0010/1906] Update to perform google ops to add a sample method for twitter search. git-svn-id: svn://107.170.10.188:8080/Monolith/dev@27556 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 7d157279311e45a82108d616145c920a2356130e --- .../semoss/web/services/UserResource.java | 50 ++++++++++++------- 1 file changed, 31 insertions(+), 19 deletions(-) diff --git a/src/prerna/semoss/web/services/UserResource.java b/src/prerna/semoss/web/services/UserResource.java index 847702b0e..59ee32ab5 100644 --- a/src/prerna/semoss/web/services/UserResource.java +++ b/src/prerna/semoss/web/services/UserResource.java @@ -72,6 +72,8 @@ import javax.ws.rs.core.Response; import javax.ws.rs.core.StreamingOutput; +import jodd.util.URLDecoder; + import org.apache.http.HttpEntity; import org.apache.http.NameValuePair; import org.apache.http.client.ResponseHandler; @@ -85,25 +87,6 @@ import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; -import com.google.api.client.auth.oauth2.TokenResponseException; -import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeTokenRequest; -import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; -import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken; -import com.google.api.client.googleapis.auth.oauth2.GoogleTokenResponse; -import com.google.api.client.http.HttpTransport; -import com.google.api.client.http.javanet.NetHttpTransport; -import com.google.api.client.json.jackson2.JacksonFactory; -import com.google.api.services.oauth2.Oauth2; -import com.google.api.services.oauth2.model.Userinfoplus; -import com.google.gson.Gson; -import com.google.gson.internal.StringMap; -import com.restfb.DefaultFacebookClient; -import com.restfb.FacebookClient; -import com.restfb.Parameter; -import com.sun.jna.platform.win32.Secur32; -import com.sun.jna.platform.win32.Secur32Util; - -import jodd.util.URLDecoder; import prerna.auth.AccessToken; import prerna.auth.AuthProvider; import prerna.auth.CACReader; @@ -116,7 +99,9 @@ import prerna.io.connector.google.GoogleLatLongGetter; import prerna.io.connector.google.GoogleListFiles; import prerna.io.connector.google.GoogleProfile; +import prerna.io.connector.twitter.TwitterSearcher; import prerna.om.NLPDocumentInput; +import prerna.om.Viewpoint; import prerna.security.AbstractHttpHelper; import prerna.util.BeanFiller; import prerna.util.Constants; @@ -124,6 +109,24 @@ import prerna.web.services.util.WebUtility; import waffle.servlet.WindowsPrincipal; +import com.google.api.client.auth.oauth2.TokenResponseException; +import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeTokenRequest; +import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; +import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken; +import com.google.api.client.googleapis.auth.oauth2.GoogleTokenResponse; +import com.google.api.client.http.HttpTransport; +import com.google.api.client.http.javanet.NetHttpTransport; +import com.google.api.client.json.jackson2.JacksonFactory; +import com.google.api.services.oauth2.Oauth2; +import com.google.api.services.oauth2.model.Userinfoplus; +import com.google.gson.Gson; +import com.google.gson.internal.StringMap; +import com.restfb.DefaultFacebookClient; +import com.restfb.FacebookClient; +import com.restfb.Parameter; +import com.sun.jna.platform.win32.Secur32; +import com.sun.jna.platform.win32.Secur32Util; + @Path("/auth") public class UserResource { @@ -1084,6 +1087,15 @@ private void performGoogleOps(HttpServletRequest request, Hashtable ret) lat.execute((User2)request.getSession().getAttribute("semoss_user"), params2); + IConnectorIOp ts = new TwitterSearcher(); + params2 = new Hashtable(); + params2.put("q", "Anlaytics"); + params2.put("lang", "en"); + params2.put("count", "10"); + + Object vp = ts.execute((User2)request.getSession().getAttribute("semoss_user"), params2); + + } private String getGoogleRedirect(HttpServletRequest request) From c6fcbc4e47c2f1cb264cd6477b04885a71759df9 Mon Sep 17 00:00:00 2001 From: pkapaleeswaran Date: Tue, 24 Apr 2018 19:03:12 +0000 Subject: [PATCH 0011/1906] Checking in to say success is true. git-svn-id: svn://107.170.10.188:8080/Monolith/dev@27558 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 95858e42b81e3f4b57d1a62b0ab8782a4301dbd5 --- src/prerna/semoss/web/services/UserResource.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/prerna/semoss/web/services/UserResource.java b/src/prerna/semoss/web/services/UserResource.java index 59ee32ab5..4d92c8e5a 100644 --- a/src/prerna/semoss/web/services/UserResource.java +++ b/src/prerna/semoss/web/services/UserResource.java @@ -1001,10 +1001,10 @@ public Response loginGoogle2(@Context HttpServletRequest request, @Context HttpS User2 user = (User2)userObj; AccessToken accessToken = user.getAccessToken(AuthProvider.GOOGLE.name()); - performGoogleOps(request, ret); + //performGoogleOps(request, ret); ret.put("success", "true"); try { - ret.put("user", BeanFiller.getJson(accessToken)); + //ret.put("user", BeanFiller.getJson(accessToken)); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); @@ -1031,7 +1031,7 @@ else if(userObj != null && ((User2)userObj).getAccessToken(AuthProvider.GOOGLE.n performGoogleOps(request, ret); ret.put("success", "true"); try { - ret.put("user", BeanFiller.getJson(accessToken)); + //ret.put("user", BeanFiller.getJson(accessToken)); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); From c77ae8070228201cd1c66568a1212a9a48914d99 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 25 Apr 2018 01:55:11 +0000 Subject: [PATCH 0012/1906] UPDATE ::: Adding in logic to take delimiter git-svn-id: svn://107.170.10.188:8080/Monolith/dev@27579 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 8f24abaf21a00e4410e458594f44db359e3cf22b --- src/prerna/upload/DatabaseUploader.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/prerna/upload/DatabaseUploader.java b/src/prerna/upload/DatabaseUploader.java index be0ccfe55..4b874c3b2 100644 --- a/src/prerna/upload/DatabaseUploader.java +++ b/src/prerna/upload/DatabaseUploader.java @@ -396,6 +396,7 @@ public Response uploadCsvFileAndPredictMetamodel(@Context HttpServletRequest req // get the files String[] files = inputData.get("file").split(";"); + String[] delimiters = inputData.get("delimiter").split("\\+\\+\\+"); // get the property files if necessary String props = inputData.get("propFile"); String[] propFiles = null; @@ -420,6 +421,7 @@ public Response uploadCsvFileAndPredictMetamodel(@Context HttpServletRequest req // store the file location on server so FE can send that back into actual upload routine String filePath = files[i]; + char delimiter = delimiters[i].charAt(0); String file = filePath.substring(filePath.lastIndexOf("\\") + 1, filePath.lastIndexOf(".")); try { file = file.substring(0, file.length() - 24); //taking out the date added onto the original file name @@ -433,9 +435,7 @@ public Response uploadCsvFileAndPredictMetamodel(@Context HttpServletRequest req fileMetaModelData.put("fileName", file); CSVFileHelper helper = new CSVFileHelper(); - // TODO: should enable any kind of single char delimited file - // have FE pass this info - helper.setDelimiter(','); + helper.setDelimiter(delimiter); helper.parse(filePath); MetaModelCreator predictor; From 7660f809d4ed657de4676ac19b5114217b525e71 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 25 Apr 2018 17:05:38 +0000 Subject: [PATCH 0013/1906] UPDATE ::: Accounting for no data in pixel web utility git-svn-id: svn://107.170.10.188:8080/Monolith/dev@27596 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: c50360da15b76055d6e7e1fb5b9c8c510757ae92 --- src/prerna/web/services/util/PixelWebUtility.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/prerna/web/services/util/PixelWebUtility.java b/src/prerna/web/services/util/PixelWebUtility.java index 83edf5e3c..def83e29d 100644 --- a/src/prerna/web/services/util/PixelWebUtility.java +++ b/src/prerna/web/services/util/PixelWebUtility.java @@ -217,6 +217,16 @@ else if(nounT == PixelDataType.FORMATTED_DATA_SET) { first = false; count++; } + // this happens if there is no data to return + if(first == true) { + ps.print("\"values\":["); + // try to at least provide the headers + List> headerInfo = task.getHeaderInfo(); + headers = new String[headerInfo.size()]; + for(int i = 0; i < headers.length; i++) { + headers[i] = headerInfo.get(i).get("alias") + ""; + } + } // end the values and add the headers ps.print("],\"headers\":" + gson.toJson(headers)); ps.print("}" ); From ecdeb2b330c962b789ffaa74756fd5a23f1cf95c Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 26 Apr 2018 01:42:51 +0000 Subject: [PATCH 0014/1906] UPDATE ::: Fixing logic around GSON for full query struct git-svn-id: svn://107.170.10.188:8080/Monolith/dev@27622 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 8dd51776933c9b1d4c372d553adc97497238f3b4 --- src/prerna/web/services/util/WebUtility.java | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/src/prerna/web/services/util/WebUtility.java b/src/prerna/web/services/util/WebUtility.java index d304747a6..95db6941d 100644 --- a/src/prerna/web/services/util/WebUtility.java +++ b/src/prerna/web/services/util/WebUtility.java @@ -31,7 +31,6 @@ import java.io.OutputStream; import java.io.PrintStream; import java.io.UnsupportedEncodingException; -import java.lang.reflect.Modifier; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Response; @@ -40,11 +39,8 @@ import org.apache.log4j.Logger; import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import prerna.date.SemossDate; -import prerna.util.gson.NumberAdapter; -import prerna.util.gson.SemossDateAdapter; +import prerna.util.gson.GsonUtility; /** * The Utility class contains a variety of miscellaneous functions implemented extensively throughout SEMOSS. @@ -56,13 +52,7 @@ public class WebUtility { private static final Logger LOGGER = Logger.getLogger(CLASS_NAME); protected static Gson getDefaultGson() { - Gson gson = new GsonBuilder() - .disableHtmlEscaping() - .excludeFieldsWithModifiers(Modifier.STATIC, Modifier.TRANSIENT) - .registerTypeAdapter(Double.class, new NumberAdapter()) - .registerTypeAdapter(SemossDate.class, new SemossDateAdapter()) - .create(); - return gson; + return GsonUtility.getDefaultGson(); } public static StreamingOutput getSO(Object vec) From 8d329acad9ca645d06ac1c06663eb1f67d20c492 Mon Sep 17 00:00:00 2001 From: pkapaleeswaran Date: Thu, 26 Apr 2018 02:47:24 +0000 Subject: [PATCH 0015/1906] UserResource - Logout method and add to app tokens /logout/git etc. git-svn-id: svn://107.170.10.188:8080/Monolith/dev@27625 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 88c1831c7e7f12de639a5700982220868d54b1fc --- .../semoss/web/services/UserResource.java | 29 +++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/src/prerna/semoss/web/services/UserResource.java b/src/prerna/semoss/web/services/UserResource.java index 4d92c8e5a..c758f2664 100644 --- a/src/prerna/semoss/web/services/UserResource.java +++ b/src/prerna/semoss/web/services/UserResource.java @@ -65,6 +65,7 @@ import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; +import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.WebApplicationException; @@ -88,6 +89,7 @@ import org.apache.http.util.EntityUtils; import prerna.auth.AccessToken; +import prerna.auth.AppTokens; import prerna.auth.AuthProvider; import prerna.auth.CACReader; import prerna.auth.User; @@ -175,6 +177,8 @@ public static void loadConnectors() loginTwitterApp(); loginGoogleApp(); // also make the twit token and such + AppTokens.getInstance().setAccessToken(twitToken); + AppTokens.getInstance().setAccessToken(googAppToken); } } catch (FileNotFoundException e) { e.printStackTrace(); @@ -868,7 +872,7 @@ public Response loginDropBox(@Context HttpServletRequest request, @Context HttpS if(queryString != null && queryString.contains("code=")) { - if(userObj == null || ((User2)userObj).getAccessToken(AuthProvider.GOOGLE.name()) == null) + if(userObj == null || ((User2)userObj).getAccessToken(AuthProvider.DROPBOX.name()) == null) { String [] outputs = AbstractHttpHelper.getCodes(queryString); @@ -1539,7 +1543,28 @@ private static String toHexString(byte[] bytes) { return formatter.toString(); } - + @GET + @Produces("application/json") + @Path("/logout/{provider}") + public Response logout(@PathParam("provider") String provider, @Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException + { + if(provider.equalsIgnoreCase("ALL")) + { + // remove the user from session call it a day + request.getSession().removeAttribute("semoss_user"); + } + else + { + User2 thisUser = (User2)request.getSession().getAttribute("semoss_user"); + thisUser.dropAccessToken(provider.toUpperCase()); + request.getSession().setAttribute("semoss_user",thisUser); + } + + Hashtable ret = new Hashtable(); + ret.put("logout", "true"); + // return Response.status(200).entity(WebUtility.getSO(ret)).build(); + return WebUtility.getResponse(ret, 200); + } // /** From 71ea941103a695575da4b256f4dc28d501777b67 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 26 Apr 2018 13:50:07 +0000 Subject: [PATCH 0016/1906] UPDATE ::: Accounting for task so we do not break when flushing to FE git-svn-id: svn://107.170.10.188:8080/Monolith/dev@27631 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: c7e669f338b9045b750dc723117d4d65e46991c2 --- src/prerna/web/services/util/PixelWebUtility.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/prerna/web/services/util/PixelWebUtility.java b/src/prerna/web/services/util/PixelWebUtility.java index def83e29d..7e9216a46 100644 --- a/src/prerna/web/services/util/PixelWebUtility.java +++ b/src/prerna/web/services/util/PixelWebUtility.java @@ -176,9 +176,18 @@ private static void processNounMetadata(PrintStream ps, Gson gson, NounMetadata } ps.print(",\"operationType\":"); ps.print(gson.toJson(noun.getOpType())); - } - else if(nounT == PixelDataType.FORMATTED_DATA_SET) { + } else if(nounT == PixelDataType.TASK) { + // if we have a task + // we gotta iterate through it to return the data + ITask task = (ITask) noun.getValue(); + ps.print("\"output\":{"); + ps.print("\"taskId\":\"" + task.getId() + "\""); + ps.print("}"); + ps.print(",\"operationType\":"); + ps.print(gson.toJson(noun.getOpType())); + + } else if(nounT == PixelDataType.FORMATTED_DATA_SET) { // if we have a task // we gotta iterate through it to return the data ITask task = (ITask) noun.getValue(); From 6e406ba39859ecfabae63136ab46ef221288e97d Mon Sep 17 00:00:00 2001 From: davyzhang Date: Thu, 26 Apr 2018 16:06:08 +0000 Subject: [PATCH 0017/1906] UPDATE ::: removing old logout/google so it doesn't conflict with the new logout... git-svn-id: svn://107.170.10.188:8080/Monolith/dev@27642 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 0bab2f9b9d47ac1e694e0693fd94b02c04bd7cc6 --- .../semoss/web/services/UserResource.java | 27 +------------------ 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/src/prerna/semoss/web/services/UserResource.java b/src/prerna/semoss/web/services/UserResource.java index c758f2664..c03bd480b 100644 --- a/src/prerna/semoss/web/services/UserResource.java +++ b/src/prerna/semoss/web/services/UserResource.java @@ -295,31 +295,6 @@ public Response loginGoogle(@Context HttpServletRequest request) throws IOExcept return WebUtility.getResponse(ret, 200); } - /** - * Logs user out when authenticated through Google+. - */ - @GET - @Produces("application/json") - @Path("/logout/google") - public Response logoutGoogle(@Context HttpServletRequest request) throws IOException { - Hashtable ret = new Hashtable(); - - // Only disconnect a connected user. - String tokenData = (String) request.getSession().getAttribute("token"); - if (tokenData == null) { - ret.put("success", "false"); - ret.put("error", "User is not connected."); -// return Response.status(200).entity(WebUtility.getSO(ret)).build(); - return WebUtility.getResponse(ret, 200); - } - - request.getSession().invalidate(); - - ret.put("success", "true"); -// return Response.status(200).entity(WebUtility.getSO(ret)).build(); - return WebUtility.getResponse(ret, 200); - } - /** * Logs user in through Facebook. */ @@ -1032,7 +1007,7 @@ else if(userObj != null && ((User2)userObj).getAccessToken(AuthProvider.GOOGLE.n User2 user = (User2)userObj; AccessToken accessToken = user.getAccessToken(AuthProvider.GOOGLE.name()); - performGoogleOps(request, ret); + // performGoogleOps(request, ret); ret.put("success", "true"); try { //ret.put("user", BeanFiller.getJson(accessToken)); From 002477282c407d72c05a8300ff5aab6d0439d1e2 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 26 Apr 2018 16:25:16 +0000 Subject: [PATCH 0018/1906] UPDATE ::: Fix issue with casting incorrectly git-svn-id: svn://107.170.10.188:8080/Monolith/dev@27646 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: d4e33f52a45ae5218f5eed874f81c400b5fbe3d9 --- .../web/services/util/PixelWebUtility.java | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/prerna/web/services/util/PixelWebUtility.java b/src/prerna/web/services/util/PixelWebUtility.java index 7e9216a46..08904541c 100644 --- a/src/prerna/web/services/util/PixelWebUtility.java +++ b/src/prerna/web/services/util/PixelWebUtility.java @@ -180,13 +180,20 @@ private static void processNounMetadata(PrintStream ps, Gson gson, NounMetadata } else if(nounT == PixelDataType.TASK) { // if we have a task // we gotta iterate through it to return the data - ITask task = (ITask) noun.getValue(); - ps.print("\"output\":{"); - ps.print("\"taskId\":\"" + task.getId() + "\""); - ps.print("}"); - ps.print(",\"operationType\":"); - ps.print(gson.toJson(noun.getOpType())); - + if(noun.getValue() instanceof ITask) { + ITask task = (ITask) noun.getValue(); + ps.print("\"output\":{"); + ps.print("\"taskId\":\"" + task.getId() + "\""); + ps.print("}"); + ps.print(",\"operationType\":"); + ps.print(gson.toJson(noun.getOpType())); + } else { + // sometimes there is just data to sends + ps.print("\"output\":"); + ps.print(gson.toJson(noun.getValue())); + ps.print(",\"operationType\":"); + ps.print(gson.toJson(noun.getOpType())); + } } else if(nounT == PixelDataType.FORMATTED_DATA_SET) { // if we have a task // we gotta iterate through it to return the data From 7a545f1da1e647d8d4a2962d52fd8fbdb20ee3df Mon Sep 17 00:00:00 2001 From: kunalppatel9 Date: Thu, 26 Apr 2018 18:00:56 +0000 Subject: [PATCH 0019/1906] UPDATE ::: Added Rest Calls for User Profile Information. git-svn-id: svn://107.170.10.188:8080/Monolith/dev@27647 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 19986b0909c54dda90913c9b462ff5c812efc4f3 --- .../semoss/web/services/UserResource.java | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/src/prerna/semoss/web/services/UserResource.java b/src/prerna/semoss/web/services/UserResource.java index c03bd480b..68d5ab019 100644 --- a/src/prerna/semoss/web/services/UserResource.java +++ b/src/prerna/semoss/web/services/UserResource.java @@ -495,6 +495,79 @@ public Response getLoggedInUserInfo(@Context HttpServletRequest request) { // return Response.status(200).entity(WebUtility.getSO(ret)).build(); return WebUtility.getResponse(ret, 200); } + + /** + * Gets user info for OneDrive + */ + @GET + @Produces("application/json") + @Path("/userinfo/onedrive") + public Response userinfoOneDrive(@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException + { + String queryString = request.getQueryString(); + Object userObj = request.getSession().getAttribute("semoss_user"); + Hashtable ret = new Hashtable(); + + String objectName = "prerna.auth.AccessToken"; // it will fill this object and return the data + String [] beanProps = {"name"}; // add is done when you have a list + String jsonPattern = "[displayName]"; + + userObj = request.getSession().getAttribute("semoss_user"); + User2 user = (User2)userObj; + AccessToken accessToken = user.getAccessToken(AuthProvider.AZURE_GRAPH.name()); + String accessString = accessToken.getAccess_token(); + String url = "https://graph.microsoft.com/v1.0/me/"; + + + String output = AbstractHttpHelper.makeGetCall(url, accessString, null, true); + AccessToken accessToken2 = (AccessToken)BeanFiller.fillFromJson(output, jsonPattern, beanProps, new AccessToken()); + try { + ret.put("name", accessToken2.getName()); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return WebUtility.getResponse(ret, 200); + + } + + /** + * Gets user info for DropBox + */ + @GET + @Produces("application/json") + @Path("/userinfo/dropbox") + public Response userinfoDropbox(@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException + { + String queryString = request.getQueryString(); + Object userObj = request.getSession().getAttribute("semoss_user"); + Hashtable ret = new Hashtable(); + + String objectName = "prerna.auth.AccessToken"; // it will fill this object and return the data + String [] beanProps = {"name", "profile"}; // add is done when you have a list + String jsonPattern = "[name.display_name, profile_photo_url]"; + + userObj = request.getSession().getAttribute("semoss_user"); + User2 user = (User2)userObj; + AccessToken accessToken = user.getAccessToken(AuthProvider.DROPBOX.name()); + String accessString = accessToken.getAccess_token(); + String url = "https://api.dropboxapi.com/2/users/get_current_account"; + + + String output = AbstractHttpHelper.makePostCall(url, accessString, null, true); + AccessToken accessToken2 = (AccessToken)BeanFiller.fillFromJson(output, jsonPattern, beanProps, new AccessToken()); + try { + if(accessToken2.getProfile() != null) { + ret.put("picture", accessToken2.getProfile()); + } + ret.put("name", accessToken2.getName()); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return WebUtility.getResponse(ret, 200); + + } @GET @Produces("text/plain") From bb90e23c1d9888d3e3b5c3e349679d36c1018aa5 Mon Sep 17 00:00:00 2001 From: kunalppatel9 Date: Thu, 26 Apr 2018 18:35:52 +0000 Subject: [PATCH 0020/1906] UPDATE ::: Added log in checks for user profiles REST Calls. git-svn-id: svn://107.170.10.188:8080/Monolith/dev@27649 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 21487987512bacca68d2c00364d1e0966d698a93 --- .../semoss/web/services/UserResource.java | 92 ++++++++++++++++++- 1 file changed, 88 insertions(+), 4 deletions(-) diff --git a/src/prerna/semoss/web/services/UserResource.java b/src/prerna/semoss/web/services/UserResource.java index 68d5ab019..d1e87525e 100644 --- a/src/prerna/semoss/web/services/UserResource.java +++ b/src/prerna/semoss/web/services/UserResource.java @@ -50,6 +50,7 @@ import java.util.HashMap; import java.util.Hashtable; import java.util.List; +import java.util.Map; import java.util.Properties; import java.util.Scanner; import java.util.UUID; @@ -104,6 +105,10 @@ import prerna.io.connector.twitter.TwitterSearcher; import prerna.om.NLPDocumentInput; import prerna.om.Viewpoint; +import prerna.sablecc2.om.PixelDataType; +import prerna.sablecc2.om.PixelOperationType; +import prerna.sablecc2.om.execptions.SemossPixelException; +import prerna.sablecc2.om.nounmeta.NounMetadata; import prerna.security.AbstractHttpHelper; import prerna.util.BeanFiller; import prerna.util.Constants; @@ -496,6 +501,59 @@ public Response getLoggedInUserInfo(@Context HttpServletRequest request) { return WebUtility.getResponse(ret, 200); } + /** + * Gets user info for GoogleDrive + */ + @GET + @Produces("application/json") + @Path("/userinfo/google") + public Response userinfoGoogle(@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException + { + String queryString = request.getQueryString(); + Object userObj = request.getSession().getAttribute("semoss_user"); + Hashtable ret = new Hashtable(); + + String objectName = "prerna.auth.AccessToken"; // it will fill this object and return the data + String [] beanProps = {"name", "profile"}; // add is done when you have a list + String jsonPattern = "[name, picture]"; + + userObj = request.getSession().getAttribute("semoss_user"); + User2 user = (User2)userObj; + String accessString=null; + try{ + if(user==null){ + ret.put("ERROR", "Log into your Google account"); + return WebUtility.getResponse(ret, 200); + } + else if (user != null) { + AccessToken googleToken = user.getAccessToken(AuthProvider.GOOGLE.name()); + accessString=googleToken.getAccess_token(); + } + } + catch (Exception e) { + ret.put("ERROR", "Log into your Google account"); + return WebUtility.getResponse(ret, 200); + } + String url = "https://www.googleapis.com/oauth2/v3/userinfo"; + Hashtable params = new Hashtable(); + params.put("access_token", accessString); + params.put("alt", "json"); + + String output = AbstractHttpHelper.makeGetCall(url, accessString, params, true); + AccessToken accessToken2 = (AccessToken)BeanFiller.fillFromJson(output, jsonPattern, beanProps, new AccessToken()); + try { + if(accessToken2.getProfile() != null) { + ret.put("picture", accessToken2.getProfile()); + } + ret.put("name", accessToken2.getName()); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return WebUtility.getResponse(ret, 200); + + } + /** * Gets user info for OneDrive */ @@ -514,8 +572,21 @@ public Response userinfoOneDrive(@Context HttpServletRequest request, @Context H userObj = request.getSession().getAttribute("semoss_user"); User2 user = (User2)userObj; - AccessToken accessToken = user.getAccessToken(AuthProvider.AZURE_GRAPH.name()); - String accessString = accessToken.getAccess_token(); + String accessString=null; + try{ + if(user==null){ + ret.put("ERROR", "Log into your Microsoft account"); + return WebUtility.getResponse(ret, 200); + } + else if (user != null) { + AccessToken msToken = user.getAccessToken(AuthProvider.AZURE_GRAPH.name()); + accessString=msToken.getAccess_token(); + } + } + catch (Exception e) { + ret.put("ERROR", "Log into your Microsoft account"); + return WebUtility.getResponse(ret, 200); + } String url = "https://graph.microsoft.com/v1.0/me/"; @@ -549,8 +620,21 @@ public Response userinfoDropbox(@Context HttpServletRequest request, @Context Ht userObj = request.getSession().getAttribute("semoss_user"); User2 user = (User2)userObj; - AccessToken accessToken = user.getAccessToken(AuthProvider.DROPBOX.name()); - String accessString = accessToken.getAccess_token(); + String accessString=null; + try{ + if(user==null){ + ret.put("ERROR", "Log into your DropBox account"); + return WebUtility.getResponse(ret, 200); + } + else if (user != null) { + AccessToken dropToken = user.getAccessToken(AuthProvider.DROPBOX.name()); + accessString=dropToken.getAccess_token(); + } + } + catch (Exception e) { + ret.put("ERROR", "Log into your DropBox account"); + return WebUtility.getResponse(ret, 200); + } String url = "https://api.dropboxapi.com/2/users/get_current_account"; From cf250ab4119933817827e194a5097ddbc646eb6b Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 26 Apr 2018 19:22:27 +0000 Subject: [PATCH 0021/1906] UPDATE ::: Accounting for task error in stream git-svn-id: svn://107.170.10.188:8080/Monolith/dev@27652 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 2f6c0f28629a7085583235bb1b5d8f5326748bb1 --- .../web/services/util/PixelWebUtility.java | 61 +++++++++++++------ 1 file changed, 43 insertions(+), 18 deletions(-) diff --git a/src/prerna/web/services/util/PixelWebUtility.java b/src/prerna/web/services/util/PixelWebUtility.java index 08904541c..4213bed26 100644 --- a/src/prerna/web/services/util/PixelWebUtility.java +++ b/src/prerna/web/services/util/PixelWebUtility.java @@ -20,6 +20,7 @@ import prerna.sablecc2.PixelRunner; import prerna.sablecc2.PixelUtility; import prerna.sablecc2.om.PixelDataType; +import prerna.sablecc2.om.PixelOperationType; import prerna.sablecc2.om.nounmeta.NounMetadata; import prerna.sablecc2.om.task.ConstantDataTask; import prerna.sablecc2.om.task.ITask; @@ -188,7 +189,8 @@ private static void processNounMetadata(PrintStream ps, Gson gson, NounMetadata ps.print(",\"operationType\":"); ps.print(gson.toJson(noun.getOpType())); } else { - // sometimes there is just data to sends + // sometimes there is just data to send + // dont need to do anything special ps.print("\"output\":"); ps.print(gson.toJson(noun.getValue())); ps.print(",\"operationType\":"); @@ -204,37 +206,60 @@ private static void processNounMetadata(PrintStream ps, Gson gson, NounMetadata Map taskMeta = task.getMeta(); if(formatType.equals("TABLE")) { - ps.print("\"output\":{"); if(task instanceof ConstantDataTask) { + ps.print("\"output\":{"); ps.print("\"data\":" + gson.toJson( ((ConstantDataTask) task).getOutputData())); ps.flush(); } else { // right now, only grid will work - ps.print("\"data\":{" ); - boolean first = true; String[] headers = null; int count = 0; - // recall, a task is also an iterator! - while(task.hasNext() && (collectAll || count < numCollect)) { - IHeadersDataRow row = task.next(); - // need to set the headers - if(headers == null) { - headers = row.getHeaders(); - ps.print("\"values\":["); + + // we need to use a try catch + // in case there is an issue + // since we can get to this point + // without trying to execute or anything + try { + // recall, a task is also an iterator! + while(task.hasNext() && (collectAll || count < numCollect)) { + IHeadersDataRow row = task.next(); + // need to set the headers + if(headers == null) { + headers = row.getHeaders(); + ps.print("\"output\":{"); + ps.print("\"data\":{" ); + ps.print("\"values\":["); + } + + if(!first) { + ps.print(","); + } + ps.print(gson.toJson(row.getValues())); + ps.flush(); + + first = false; + count++; } + } catch(Exception e) { + // on no, this is not good + e.printStackTrace(); - if(!first) { - ps.print(","); - } - ps.print(gson.toJson(row.getValues())); + // let us send back an error + ps.print("\"output\":"); + ps.print(gson.toJson(e.getMessage())); + ps.print(",\"operationType\":"); + ps.print(gson.toJson(new PixelOperationType[]{PixelOperationType.ERROR})); + // close the map + ps.print("}"); ps.flush(); - - first = false; - count++; + return; } + // this happens if there is no data to return if(first == true) { + ps.print("\"output\":{"); + ps.print("\"data\":{" ); ps.print("\"values\":["); // try to at least provide the headers List> headerInfo = task.getHeaderInfo(); From 1404088129c3346c23bcb80a7984a418d657530b Mon Sep 17 00:00:00 2001 From: davyzhang Date: Thu, 26 Apr 2018 20:35:36 +0000 Subject: [PATCH 0022/1906] UPDATE ::: return success when user is already logged into onedrive, git, dropbox; return success with a true boolean rather than a string git-svn-id: svn://107.170.10.188:8080/Monolith/dev@27660 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: da391b875716e0e834e0cd43e50b8e7bfc488487 --- .../semoss/web/services/UserResource.java | 85 +++++++++++-------- 1 file changed, 51 insertions(+), 34 deletions(-) diff --git a/src/prerna/semoss/web/services/UserResource.java b/src/prerna/semoss/web/services/UserResource.java index d1e87525e..8a83eedd3 100644 --- a/src/prerna/semoss/web/services/UserResource.java +++ b/src/prerna/semoss/web/services/UserResource.java @@ -718,7 +718,7 @@ public Response loginSF(@Context HttpServletRequest request, @Context HttpServle // redirect if query string not there Object userObj = request.getSession().getAttribute("semoss_user"); - Hashtable ret = new Hashtable(); + Hashtable ret = new Hashtable(); String queryString = request.getQueryString(); @@ -754,14 +754,14 @@ public Response loginSF(@Context HttpServletRequest request, @Context HttpServle System.out.println("Access Token is.. " + accessToken.getAccess_token()); - ret.put("success", "true"); + ret.put("success", true); // return Response.status(200).entity(WebUtility.getSO(ret)).build(); return WebUtility.getResponse(ret, 200); } else { - ret.put("success", "true"); - ret.put("Already_Authenticated", "true"); + ret.put("success", true); + ret.put("Already_Authenticated", true); // return Response.status(200).entity(WebUtility.getSO(ret)).build(); return WebUtility.getResponse(ret, 200); @@ -809,7 +809,7 @@ public Response loginGit(@Context HttpServletRequest request, @Context HttpServl { // redirect if query string not there Object userObj = request.getSession().getAttribute("semoss_user"); - Hashtable ret = new Hashtable(); + Hashtable ret = new Hashtable(); //https://developer.github.com/apps/building-oauth-apps/authorization-options-for-oauth-apps/ String queryString = request.getQueryString(); @@ -844,14 +844,14 @@ public Response loginGit(@Context HttpServletRequest request, @Context HttpServl System.out.println("Access Token is.. " + accessToken.getAccess_token()); - ret.put("success", "true"); + ret.put("success", true); // return Response.status(200).entity(WebUtility.getSO(ret)).build(); return WebUtility.getResponse(ret, 200); } else { - ret.put("success", "true"); - ret.put("Already_Authenticated", "true"); + ret.put("success", true); + ret.put("Already_Authenticated", true); // return Response.status(200).entity(WebUtility.getSO(ret)).build(); return WebUtility.getResponse(ret, 200); @@ -864,6 +864,12 @@ else if(userObj == null || ((User2)userObj).getAccessToken(AuthProvider.GIT.name response.setStatus(302); response.sendRedirect(getGitRedirect(request)); } + // else if user object is there and git is there + else if(userObj != null && ((User2)userObj).getAccessToken(AuthProvider.GIT.name()) != null) + { + ret.put("success", true); + return WebUtility.getResponse(ret, 200); + } return null; } @@ -900,7 +906,7 @@ public Response loginMS(@Context HttpServletRequest request, @Context HttpServle // redirect if query string not there Object userObj = request.getSession().getAttribute("semoss_user"); - Hashtable ret = new Hashtable(); + Hashtable ret = new Hashtable(); String queryString = request.getQueryString(); @@ -938,14 +944,14 @@ public Response loginMS(@Context HttpServletRequest request, @Context HttpServle System.out.println("Access Token is.. " + accessToken.getAccess_token()); - ret.put("success", "true"); + ret.put("success", true); // return Response.status(200).entity(WebUtility.getSO(ret)).build(); return WebUtility.getResponse(ret, 200); } else { - ret.put("success", "true"); - ret.put("Already_Authenticated", "true"); + ret.put("success", true); + ret.put("Already_Authenticated", true); // return Response.status(200).entity(WebUtility.getSO(ret)).build(); return WebUtility.getResponse(ret, 200); @@ -957,6 +963,13 @@ else if(userObj == null || ((User2)userObj).getAccessToken(AuthProvider.AZURE_GR response.setStatus(302); response.sendRedirect(getMSRedirect(request)); } + // else if user object is there and ms is there + else if(userObj != null && ((User2)userObj).getAccessToken(AuthProvider.AZURE_GRAPH.name()) != null) + { + ret.put("success", true); + return WebUtility.getResponse(ret, 200); + } + return null; } @@ -997,7 +1010,7 @@ public Response loginDropBox(@Context HttpServletRequest request, @Context HttpS // redirect if query string not there Object userObj = request.getSession().getAttribute("semoss_user"); - Hashtable ret = new Hashtable(); + Hashtable ret = new Hashtable(); String queryString = request.getQueryString(); @@ -1032,14 +1045,14 @@ public Response loginDropBox(@Context HttpServletRequest request, @Context HttpS addAccessToken(accessToken, request); System.out.println("Access Token is.. " + accessToken.getAccess_token()); - ret.put("success", "true"); + ret.put("success", true); // return Response.status(200).entity(WebUtility.getSO(ret)).build(); return WebUtility.getResponse(ret, 200); } else { - ret.put("success", "true"); - ret.put("Already_Authenticated", "true"); + ret.put("success", true); + ret.put("Already_Authenticated", true); // return Response.status(200).entity(WebUtility.getSO(ret)).build(); return WebUtility.getResponse(ret, 200); @@ -1052,6 +1065,12 @@ else if(userObj == null || ((User2)userObj).getAccessToken(AuthProvider.DROPBOX. response.setStatus(302); response.sendRedirect(getDBRedirect(request)); } + // else if user object is there and dropbox is there + else if(userObj != null && ((User2)userObj).getAccessToken(AuthProvider.DROPBOX.name()) != null) + { + ret.put("success", true); + return WebUtility.getResponse(ret, 200); + } return null; } @@ -1093,7 +1112,7 @@ public Response loginGoogle2(@Context HttpServletRequest request, @Context HttpS String queryString = request.getQueryString(); Object userObj = request.getSession().getAttribute("semoss_user"); - Hashtable ret = new Hashtable(); + Hashtable ret = new Hashtable(); // if the code is there if(queryString != null && queryString.contains("code=")) @@ -1138,7 +1157,7 @@ public Response loginGoogle2(@Context HttpServletRequest request, @Context HttpS AccessToken accessToken = user.getAccessToken(AuthProvider.GOOGLE.name()); //performGoogleOps(request, ret); - ret.put("success", "true"); + ret.put("success", true); try { //ret.put("user", BeanFiller.getJson(accessToken)); } catch (Exception e) { @@ -1146,7 +1165,6 @@ public Response loginGoogle2(@Context HttpServletRequest request, @Context HttpS e.printStackTrace(); } - ret.put("success", "true"); // return Response.status(200).entity(WebUtility.getSO(ret)).build(); return WebUtility.getResponse(ret, 200); } @@ -1160,12 +1178,11 @@ else if(userObj == null || ((User2)userObj).getAccessToken(AuthProvider.GOOGLE.n // else if user object is there and google is there else if(userObj != null && ((User2)userObj).getAccessToken(AuthProvider.GOOGLE.name()) != null) { - ret.put("success", "true"); + ret.put("success", true); User2 user = (User2)userObj; AccessToken accessToken = user.getAccessToken(AuthProvider.GOOGLE.name()); // performGoogleOps(request, ret); - ret.put("success", "true"); try { //ret.put("user", BeanFiller.getJson(accessToken)); } catch (Exception e) { @@ -1291,7 +1308,7 @@ public Response loginProducthunt(@Context HttpServletRequest request, @Context H // redirect if query string not there Object userObj = request.getSession().getAttribute("semoss_user"); - Hashtable ret = new Hashtable(); + Hashtable ret = new Hashtable(); String queryString = request.getQueryString(); @@ -1326,14 +1343,14 @@ public Response loginProducthunt(@Context HttpServletRequest request, @Context H addAccessToken(accessToken, request); System.out.println("Access Token is.. " + accessToken.getAccess_token()); - ret.put("success", "true"); + ret.put("success", true); // return Response.status(200).entity(WebUtility.getSO(ret)).build(); return WebUtility.getResponse(ret, 200); } else { - ret.put("success", "true"); - ret.put("Already_Authenticated", "true"); + ret.put("success", true); + ret.put("Already_Authenticated", true); // return Response.status(200).entity(WebUtility.getSO(ret)).build(); return WebUtility.getResponse(ret, 200); @@ -1463,7 +1480,7 @@ public Response loginTwitter(@Context HttpServletRequest request, @Context HttpS { // redirect if query string not there Object userObj = request.getSession().getAttribute("semoss_user"); - Hashtable ret = new Hashtable(); + Hashtable ret = new Hashtable(); // getting the bearer token on twitter for app authentication is a lot simpler // need to just combine the id and secret @@ -1503,14 +1520,14 @@ public Response loginTwitter(@Context HttpServletRequest request, @Context HttpS System.out.println("Access Token is.. " + accessToken.getAccess_token()); - ret.put("success", "true"); + ret.put("success", true); // return Response.status(200).entity(WebUtility.getSO(ret)).build(); return WebUtility.getResponse(ret, 200); } else { - ret.put("success", "true"); - ret.put("Already_Authenticated", "true"); + ret.put("success", true); + ret.put("Already_Authenticated", true); // return Response.status(200).entity(WebUtility.getSO(ret)).build(); return WebUtility.getResponse(ret, 200); @@ -1575,7 +1592,7 @@ public Response loginIn(@Context HttpServletRequest request, @Context HttpServle { // redirect if query string not there Object userObj = request.getSession().getAttribute("semoss_user"); - Hashtable ret = new Hashtable(); + Hashtable ret = new Hashtable(); //https://developer.github.com/apps/building-oauth-apps/authorization-options-for-oauth-apps/ String queryString = request.getQueryString(); @@ -1610,14 +1627,14 @@ public Response loginIn(@Context HttpServletRequest request, @Context HttpServle System.out.println("Access Token is.. " + accessToken.getAccess_token()); - ret.put("success", "true"); + ret.put("success", true); // return Response.status(200).entity(WebUtility.getSO(ret)).build(); return WebUtility.getResponse(ret, 200); } else { - ret.put("success", "true"); - ret.put("Already_Authenticated", "true"); + ret.put("success", true); + ret.put("Already_Authenticated", true); // return Response.status(200).entity(WebUtility.getSO(ret)).build(); return WebUtility.getResponse(ret, 200); @@ -1693,7 +1710,7 @@ public Response logout(@PathParam("provider") String provider, @Context HttpServ } Hashtable ret = new Hashtable(); - ret.put("logout", "true"); + ret.put("success", true); // return Response.status(200).entity(WebUtility.getSO(ret)).build(); return WebUtility.getResponse(ret, 200); } From bedf1b632b6536f6a9a4c8bd94846007165f4d44 Mon Sep 17 00:00:00 2001 From: kunalppatel9 Date: Thu, 26 Apr 2018 22:15:56 +0000 Subject: [PATCH 0023/1906] UPDATE ::: Changed userinfo/onedrive to userinfo/ms git-svn-id: svn://107.170.10.188:8080/Monolith/dev@27667 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: dbd54d027a487ba8767ac9abcfac49575aa1667a --- src/prerna/semoss/web/services/UserResource.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prerna/semoss/web/services/UserResource.java b/src/prerna/semoss/web/services/UserResource.java index 8a83eedd3..d5ce0c136 100644 --- a/src/prerna/semoss/web/services/UserResource.java +++ b/src/prerna/semoss/web/services/UserResource.java @@ -559,7 +559,7 @@ else if (user != null) { */ @GET @Produces("application/json") - @Path("/userinfo/onedrive") + @Path("/userinfo/ms") public Response userinfoOneDrive(@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException { String queryString = request.getQueryString(); From 827d2e51dab45564377dde3d5f9ee989f53062e9 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 27 Apr 2018 14:12:04 +0000 Subject: [PATCH 0024/1906] UPDATE ::: Modification for constant task to be returned and then flushed in web utility UPDATE ::: Fixing error with sending collect graph data to FE git-svn-id: svn://107.170.10.188:8080/Monolith/dev@27681 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: ed67c370cdc88d1a910d0ff31f1f50fbb3fff59a --- .../web/services/util/PixelWebUtility.java | 111 ++++++++---------- 1 file changed, 52 insertions(+), 59 deletions(-) diff --git a/src/prerna/web/services/util/PixelWebUtility.java b/src/prerna/web/services/util/PixelWebUtility.java index 4213bed26..a5ebfd20a 100644 --- a/src/prerna/web/services/util/PixelWebUtility.java +++ b/src/prerna/web/services/util/PixelWebUtility.java @@ -30,7 +30,7 @@ public class PixelWebUtility extends WebUtility{ private static final String CLASS_NAME = PixelWebUtility.class.getName(); private static final Logger LOGGER = Logger.getLogger(CLASS_NAME); - + /** * Collect pixel data from the runner * @param runner @@ -54,7 +54,7 @@ public void write(OutputStream outputStream) throws IOException, WebApplicationE } return null; } - + private static void processPixelRunner(PrintStream ps, Gson gson, PixelRunner runner, boolean ignoreFirst) { // get the values we need from the runner Insight in = runner.getInsight(); @@ -65,16 +65,16 @@ private static void processPixelRunner(PrintStream ps, Gson gson, PixelRunner ru List isMeta = runner.isMeta(); Map encodedTextToOriginal = runner.getEncodedTextToOriginal(); boolean invalidSyntax = runner.isInvalidSyntax(); - + // start of the map // and the insight id ps.print("{\"insightID\":\"" + in.getInsightId() + "\","); ps.flush(); - + // now flush array of pixel returns ps.println("\"pixelReturn\":["); int size = pixelStrings.size(); - + // THIS IS BECAUSE WE APPEND THE JOB PIXEL // BUT FE DOENS'T RESPOND TO IT AND NEED TO REMOVE IT // HOWEVER, IF THE SIZE IS JUST 1, IT MEANS THAT THERE WAS @@ -94,27 +94,27 @@ private static void processPixelRunner(PrintStream ps, Gson gson, PixelRunner ru expression = PixelUtility.recreateOriginalPixelExpression(expression, encodedTextToOriginal); boolean meta = isMeta.get(i); processNounMetadata(ps, gson, noun, expression, meta); - + // update the pixel list to say this is routine is valid // TODO: need to set this inside the translation directly!!! if (!meta && !invalidSyntax) { // update the insight recipe in.getPixelRecipe().add(expression); } - + // add a comma for the next item in the list if( (i+1) != size) { ps.print(","); ps.flush(); } } - + // now close of the array and the map ps.print("]}"); ps.flush(); } - - + + /** * Process the noun metadata for consumption on the FE * @param noun @@ -122,7 +122,7 @@ private static void processPixelRunner(PrintStream ps, Gson gson, PixelRunner ru */ private static void processNounMetadata(PrintStream ps, Gson gson, NounMetadata noun, String expression, Boolean isMeta) { ps.print("{"); - + // add expression if there if(expression != null) { ps.print("\"pixelExpression\":" + gson.toJson(expression) + ","); @@ -131,7 +131,7 @@ private static void processNounMetadata(PrintStream ps, Gson gson, NounMetadata if(isMeta != null) { ps.print("\"isMeta\":" + isMeta + ","); } - + PixelDataType nounT = noun.getNounType(); if(nounT == PixelDataType.FRAME) { // if we have a frame @@ -145,12 +145,12 @@ private static void processNounMetadata(PrintStream ps, Gson gson, NounMetadata if(name != null) { frameData.put("name", name); } - + ps.print("\"output\":"); ps.print(gson.toJson(frameData)); ps.print(",\"operationType\":"); ps.print(gson.toJson(noun.getOpType())); - + // add additional outputs List addReturns = noun.getAdditionalReturn(); int numOutputs = addReturns.size(); @@ -161,7 +161,7 @@ private static void processNounMetadata(PrintStream ps, Gson gson, NounMetadata } ps.print("]"); } - + } else if(nounT == PixelDataType.CODE || nounT == PixelDataType.TASK_LIST) { // code is a tough one to process // since many operations could have been performed @@ -177,45 +177,38 @@ private static void processNounMetadata(PrintStream ps, Gson gson, NounMetadata } ps.print(",\"operationType\":"); ps.print(gson.toJson(noun.getOpType())); - + } else if(nounT == PixelDataType.TASK) { - // if we have a task - // we gotta iterate through it to return the data - if(noun.getValue() instanceof ITask) { - ITask task = (ITask) noun.getValue(); - ps.print("\"output\":{"); - ps.print("\"taskId\":\"" + task.getId() + "\""); - ps.print("}"); - ps.print(",\"operationType\":"); - ps.print(gson.toJson(noun.getOpType())); - } else { - // sometimes there is just data to send - // dont need to do anything special - ps.print("\"output\":"); - ps.print(gson.toJson(noun.getValue())); - ps.print(",\"operationType\":"); - ps.print(gson.toJson(noun.getOpType())); - } - } else if(nounT == PixelDataType.FORMATTED_DATA_SET) { // if we have a task // we gotta iterate through it to return the data ITask task = (ITask) noun.getValue(); - int numCollect = task.getNumCollect(); - boolean collectAll = numCollect == -1; - String formatType = task.getFormatter().getFormatType(); - Map taskMeta = task.getMeta(); + ps.print("\"output\":{"); + ps.print("\"taskId\":\"" + task.getId() + "\""); + ps.print("}"); + ps.print(",\"operationType\":"); + ps.print(gson.toJson(noun.getOpType())); + + } else if(nounT == PixelDataType.FORMATTED_DATA_SET) { + Object value = noun.getValue(); + if(value instanceof ITask) { + // if we have a task + // we gotta iterate through it to return the data + ITask task = (ITask) noun.getValue(); + int numCollect = task.getNumCollect(); + boolean collectAll = numCollect == -1; + String formatType = task.getFormatter().getFormatType(); + Map taskMeta = task.getMeta(); - if(formatType.equals("TABLE")) { if(task instanceof ConstantDataTask) { ps.print("\"output\":{"); ps.print("\"data\":" + gson.toJson( ((ConstantDataTask) task).getOutputData())); ps.flush(); - } else { + } else if(formatType.equals("TABLE")) { // right now, only grid will work boolean first = true; String[] headers = null; int count = 0; - + // we need to use a try catch // in case there is an issue // since we can get to this point @@ -231,20 +224,20 @@ private static void processNounMetadata(PrintStream ps, Gson gson, NounMetadata ps.print("\"data\":{" ); ps.print("\"values\":["); } - + if(!first) { ps.print(","); } ps.print(gson.toJson(row.getValues())); ps.flush(); - + first = false; count++; } } catch(Exception e) { // on no, this is not good e.printStackTrace(); - + // let us send back an error ps.print("\"output\":"); ps.print(gson.toJson(e.getMessage())); @@ -255,7 +248,7 @@ private static void processNounMetadata(PrintStream ps, Gson gson, NounMetadata ps.flush(); return; } - + // this happens if there is no data to return if(first == true) { ps.print("\"output\":{"); @@ -271,8 +264,9 @@ private static void processNounMetadata(PrintStream ps, Gson gson, NounMetadata // end the values and add the headers ps.print("],\"headers\":" + gson.toJson(headers)); ps.print("}" ); + } - + for(String taskMetaKey : taskMeta.keySet()) { ps.print(",\"" + taskMetaKey + "\":" + gson.toJson(taskMeta.get(taskMetaKey))); ps.flush(); @@ -281,20 +275,20 @@ private static void processNounMetadata(PrintStream ps, Gson gson, NounMetadata ps.print("}"); ps.print(",\"operationType\":"); ps.print(gson.toJson(noun.getOpType())); - - } else { - // TODO - // THIS IS TEMPORARY UNTIL I FIGURE OUT HOW TO DO - // GRAPHS OR OTHER TYPES OF FORMATS + + } + // if we do not have a task + // we just have data to send + else { + // sometimes there is just data to send + // dont need to do anything special ps.print("\"output\":"); - ps.print(gson.toJson(task.collect(true))); - ps.flush(); + ps.print(gson.toJson(noun.getValue())); ps.print(",\"operationType\":"); ps.print(gson.toJson(noun.getOpType())); - ps.flush(); } - } - + } + // running a saved insight else if(nounT == PixelDataType.PIXEL_RUNNER) { Map runnerWraper = (Map) noun.getValue(); @@ -317,10 +311,8 @@ else if(nounT == PixelDataType.PIXEL_RUNNER) { ps.print(",\"operationType\":"); ps.print(gson.toJson(noun.getOpType())); ps.flush(); - - //TODO: account for params!!!! } - + // everything else is simple else { ps.print("\"output\":"); @@ -333,4 +325,5 @@ else if(nounT == PixelDataType.PIXEL_RUNNER) { ps.print("}"); ps.flush(); } + } From e9d652c09c17ad963b8c9170c98d039906d75acf Mon Sep 17 00:00:00 2001 From: kunalppatel9 Date: Fri, 27 Apr 2018 18:00:57 +0000 Subject: [PATCH 0025/1906] UPDATE ::: Updated dropbox image path. if null, now returns empty string instead git-svn-id: svn://107.170.10.188:8080/Monolith/dev@27692 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 6e5d30bbfebc8593fdc8db19050829942bf9659a --- src/prerna/semoss/web/services/UserResource.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/prerna/semoss/web/services/UserResource.java b/src/prerna/semoss/web/services/UserResource.java index d5ce0c136..2a0c46118 100644 --- a/src/prerna/semoss/web/services/UserResource.java +++ b/src/prerna/semoss/web/services/UserResource.java @@ -641,10 +641,13 @@ else if (user != null) { String output = AbstractHttpHelper.makePostCall(url, accessString, null, true); AccessToken accessToken2 = (AccessToken)BeanFiller.fillFromJson(output, jsonPattern, beanProps, new AccessToken()); try { - if(accessToken2.getProfile() != null) { - ret.put("picture", accessToken2.getProfile()); - } - ret.put("name", accessToken2.getName()); + if(accessToken2.getProfile() == null||accessToken2.getProfile().equalsIgnoreCase("null")) { + ret.put("picture", ""); + } + else{ + ret.put("picture", accessToken2.getProfile()); + } + ret.put("name", accessToken2.getName()); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); From 44828ccafab9ed53ba721d14360b1ecaceb9ebb9 Mon Sep 17 00:00:00 2001 From: davyzhang Date: Fri, 27 Apr 2018 19:11:20 +0000 Subject: [PATCH 0026/1906] UPDATE ::: grab scope from social file for onedrive git-svn-id: svn://107.170.10.188:8080/Monolith/dev@27693 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 2f51fff1be221d0f40337ed5b0cad4e00fb82bc2 --- .../semoss/web/services/UserResource.java | 23 +++++++------------ 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/src/prerna/semoss/web/services/UserResource.java b/src/prerna/semoss/web/services/UserResource.java index 2a0c46118..2d7359656 100644 --- a/src/prerna/semoss/web/services/UserResource.java +++ b/src/prerna/semoss/web/services/UserResource.java @@ -576,30 +576,22 @@ public Response userinfoOneDrive(@Context HttpServletRequest request, @Context H try{ if(user==null){ ret.put("ERROR", "Log into your Microsoft account"); - return WebUtility.getResponse(ret, 200); } else if (user != null) { AccessToken msToken = user.getAccessToken(AuthProvider.AZURE_GRAPH.name()); accessString=msToken.getAccess_token(); + String url = "https://graph.microsoft.com/v1.0/me/"; + String output = AbstractHttpHelper.makeGetCall(url, accessString, null, true); + AccessToken accessToken2 = (AccessToken)BeanFiller.fillFromJson(output, jsonPattern, beanProps, new AccessToken()); + String name = accessToken2.getName(); + ret.put("name", name); } + return WebUtility.getResponse(ret, 200); } catch (Exception e) { ret.put("ERROR", "Log into your Microsoft account"); return WebUtility.getResponse(ret, 200); } - String url = "https://graph.microsoft.com/v1.0/me/"; - - - String output = AbstractHttpHelper.makeGetCall(url, accessString, null, true); - AccessToken accessToken2 = (AccessToken)BeanFiller.fillFromJson(output, jsonPattern, beanProps, new AccessToken()); - try { - ret.put("name", accessToken2.getName()); - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - return WebUtility.getResponse(ret, 200); - } /** @@ -926,13 +918,14 @@ public Response loginMS(@Context HttpServletRequest request, @Context HttpServle String clientSecret = (String)socialData.getProperty(prefix+"secret_key"); String redirectUri = (String)socialData.getProperty(prefix+"redirect_uri"); String tenant = (String)socialData.getProperty(prefix+"tenant"); + String scope = (String)socialData.getProperty(prefix+"scope"); System.out.println(">> " + request.getQueryString()); Hashtable params = new Hashtable(); params.put("client_id", clientId); - params.put("scope", "User.Read.All"); + params.put("scope", scope); params.put("redirect_uri", redirectUri); params.put("code", outputs[0]); params.put("grant_type", "authorization_code"); From a99d6284ad02cf52608d3fc6a6f9e654395215b1 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 27 Apr 2018 20:55:52 +0000 Subject: [PATCH 0027/1906] UPDATE ::: Fix for sending back graph format on non-tinker frames git-svn-id: svn://107.170.10.188:8080/Monolith/dev@27697 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: a6a018d3c8cb2413d91a30a42379de1ba405d5e4 --- src/prerna/web/services/util/PixelWebUtility.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/prerna/web/services/util/PixelWebUtility.java b/src/prerna/web/services/util/PixelWebUtility.java index a5ebfd20a..af9506926 100644 --- a/src/prerna/web/services/util/PixelWebUtility.java +++ b/src/prerna/web/services/util/PixelWebUtility.java @@ -22,6 +22,7 @@ import prerna.sablecc2.om.PixelDataType; import prerna.sablecc2.om.PixelOperationType; import prerna.sablecc2.om.nounmeta.NounMetadata; +import prerna.sablecc2.om.task.AbstractTask; import prerna.sablecc2.om.task.ConstantDataTask; import prerna.sablecc2.om.task.ITask; import prerna.sablecc2.reactor.frame.FrameFactory; @@ -265,6 +266,12 @@ private static void processNounMetadata(PrintStream ps, Gson gson, NounMetadata ps.print("],\"headers\":" + gson.toJson(headers)); ps.print("}" ); + } else if(formatType.equals("GRAPH")){ + // format type is probably graph + ps.print("\"output\":{"); + ps.print("\"data\":" ); + // this is a map return + ps.print(gson.toJson( ((AbstractTask) task).getData())); } for(String taskMetaKey : taskMeta.keySet()) { From d85e2d26533a54ba3c428ffc6e291918447510aa Mon Sep 17 00:00:00 2001 From: kunalppatel9 Date: Fri, 27 Apr 2018 21:14:20 +0000 Subject: [PATCH 0028/1906] UPDATE ::: Added userinfo/git git-svn-id: svn://107.170.10.188:8080/Monolith/dev@27698 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 767965bab2c7fa683b52bcd51e05efdf04c68fcf --- .../semoss/web/services/UserResource.java | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/src/prerna/semoss/web/services/UserResource.java b/src/prerna/semoss/web/services/UserResource.java index 2d7359656..fd70f091c 100644 --- a/src/prerna/semoss/web/services/UserResource.java +++ b/src/prerna/semoss/web/services/UserResource.java @@ -647,6 +647,56 @@ else if (user != null) { return WebUtility.getResponse(ret, 200); } + + /** + * Gets user info for Github + */ + @GET + @Produces("application/json") + @Path("/userinfo/git") + public Response userinfoGithub(@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException + { + String queryString = request.getQueryString(); + Object userObj = request.getSession().getAttribute("semoss_user"); + Hashtable ret = new Hashtable(); + + String objectName = "prerna.auth.AccessToken"; // it will fill this object and return the data + String [] beanProps = {"name", "profile"}; // add is done when you have a list + String jsonPattern = "[name,login]"; + + userObj = request.getSession().getAttribute("semoss_user"); + User2 user = (User2)userObj; + String accessString=null; + try{ + if(user==null){ + ret.put("ERROR", "Log into your Github account"); + return WebUtility.getResponse(ret, 200); + } + else if (user != null) { + AccessToken gitToken = user.getAccessToken(AuthProvider.GIT.name()); + accessString=gitToken.getAccess_token(); + } + } + catch (Exception e) { + ret.put("ERROR", "Log into your Github account"); + return WebUtility.getResponse(ret, 200); + } + String url = "https://api.github.com/user/"; + Hashtable params = new Hashtable(); + params.put("access_token", accessString); + + String output = AbstractHttpHelper.makePostCall(url, accessString, null, false); + AccessToken accessToken2 = (AccessToken)BeanFiller.fillFromJson(output, jsonPattern, beanProps, new AccessToken()); + try { + ret.put("name", accessToken2.getName()); + ret.put("username", accessToken2.getProfile()); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return WebUtility.getResponse(ret, 200); + + } @GET @Produces("text/plain") From 3917564cfc567366c9cce5120c1b95f0ed6b8bb3 Mon Sep 17 00:00:00 2001 From: kunalppatel9 Date: Fri, 27 Apr 2018 21:20:45 +0000 Subject: [PATCH 0029/1906] UPDATE ::: Added userinfo/git. Edited to get call git-svn-id: svn://107.170.10.188:8080/Monolith/dev@27699 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: f1448940e22bc3347da5f75b82c5bc8506c39e84 --- src/prerna/semoss/web/services/UserResource.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prerna/semoss/web/services/UserResource.java b/src/prerna/semoss/web/services/UserResource.java index fd70f091c..7f1b2913c 100644 --- a/src/prerna/semoss/web/services/UserResource.java +++ b/src/prerna/semoss/web/services/UserResource.java @@ -685,7 +685,7 @@ else if (user != null) { Hashtable params = new Hashtable(); params.put("access_token", accessString); - String output = AbstractHttpHelper.makePostCall(url, accessString, null, false); + String output = AbstractHttpHelper.makeGetCall(url, accessString, null, false); AccessToken accessToken2 = (AccessToken)BeanFiller.fillFromJson(output, jsonPattern, beanProps, new AccessToken()); try { ret.put("name", accessToken2.getName()); From d5e501fb50b16e963f46b087694c1ba597756596 Mon Sep 17 00:00:00 2001 From: pkapaleeswaran Date: Sat, 28 Apr 2018 02:53:50 +0000 Subject: [PATCH 0030/1906] the user info was breaking everything. Quick Fix. Need to talk on monday, what it is supposed to be doing. git-svn-id: svn://107.170.10.188:8080/Monolith/dev@27708 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 8a600a55562417b78d97a202ac7140baab98d847 --- src/prerna/semoss/web/services/UserResource.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prerna/semoss/web/services/UserResource.java b/src/prerna/semoss/web/services/UserResource.java index 7f1b2913c..df52c17c9 100644 --- a/src/prerna/semoss/web/services/UserResource.java +++ b/src/prerna/semoss/web/services/UserResource.java @@ -483,7 +483,7 @@ public Response isUserLoggedIn(@Context HttpServletRequest request) { @GET @Produces("application/json") - @Path("userInfo") + @Path("userinfo") public Response getLoggedInUserInfo(@Context HttpServletRequest request) { Hashtable ret = new Hashtable(); From ff1cea31f09240eac5b843874ec6dc09d21c9d17 Mon Sep 17 00:00:00 2001 From: kunalppatel9 Date: Mon, 30 Apr 2018 13:42:10 +0000 Subject: [PATCH 0031/1906] UPDATE ::: Added userinfo/git. Edited to get call to be correct url. MUST HAVE NETSCOPE OFF TO USE. git-svn-id: svn://107.170.10.188:8080/Monolith/dev@27711 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: de14fd52beb332f14681950ede0a45384a39b5dd --- src/prerna/semoss/web/services/UserResource.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/prerna/semoss/web/services/UserResource.java b/src/prerna/semoss/web/services/UserResource.java index df52c17c9..26930052d 100644 --- a/src/prerna/semoss/web/services/UserResource.java +++ b/src/prerna/semoss/web/services/UserResource.java @@ -681,14 +681,14 @@ else if (user != null) { ret.put("ERROR", "Log into your Github account"); return WebUtility.getResponse(ret, 200); } - String url = "https://api.github.com/user/"; + String url = "https://api.github.com/user"; Hashtable params = new Hashtable(); params.put("access_token", accessString); - String output = AbstractHttpHelper.makeGetCall(url, accessString, null, false); + String output = AbstractHttpHelper.makeGetCall(url, accessString, params, false); AccessToken accessToken2 = (AccessToken)BeanFiller.fillFromJson(output, jsonPattern, beanProps, new AccessToken()); try { - ret.put("name", accessToken2.getName()); + //ret.put("name", accessToken2.getName()); ret.put("username", accessToken2.getProfile()); } catch (Exception e) { // TODO Auto-generated catch block From e3bbc81cb13e29d32b08ca6f92362e73a95155be Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 1 May 2018 14:00:05 +0000 Subject: [PATCH 0032/1906] UPDATE ::: Splitting delimiter by ";" git-svn-id: svn://107.170.10.188:8080/Monolith/dev@27758 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: ff9cb3dbd4d54c3db08149de59b08b6ba913692b --- src/prerna/upload/DatabaseUploader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prerna/upload/DatabaseUploader.java b/src/prerna/upload/DatabaseUploader.java index 4b874c3b2..ebd24d2a8 100644 --- a/src/prerna/upload/DatabaseUploader.java +++ b/src/prerna/upload/DatabaseUploader.java @@ -396,7 +396,7 @@ public Response uploadCsvFileAndPredictMetamodel(@Context HttpServletRequest req // get the files String[] files = inputData.get("file").split(";"); - String[] delimiters = inputData.get("delimiter").split("\\+\\+\\+"); + String[] delimiters = inputData.get("delimiter").split(";"); // get the property files if necessary String props = inputData.get("propFile"); String[] propFiles = null; From d8d8029126f6f062dbd97d7aeb0356ff0df4af6e Mon Sep 17 00:00:00 2001 From: davyzhang Date: Tue, 1 May 2018 14:31:06 +0000 Subject: [PATCH 0033/1906] UPDATE ::: using consistent name for userinfo git-svn-id: svn://107.170.10.188:8080/Monolith/dev@27763 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: ca905cd3147fb13c8d8e4f57d25cddb634789bfe --- src/prerna/semoss/web/services/UserResource.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prerna/semoss/web/services/UserResource.java b/src/prerna/semoss/web/services/UserResource.java index 26930052d..647e7607e 100644 --- a/src/prerna/semoss/web/services/UserResource.java +++ b/src/prerna/semoss/web/services/UserResource.java @@ -689,7 +689,7 @@ else if (user != null) { AccessToken accessToken2 = (AccessToken)BeanFiller.fillFromJson(output, jsonPattern, beanProps, new AccessToken()); try { //ret.put("name", accessToken2.getName()); - ret.put("username", accessToken2.getProfile()); + ret.put("name", accessToken2.getProfile()); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); From 6aa6fae10b847dcd5a8af20b3c65c22d45c86659 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 3 May 2018 20:21:11 +0000 Subject: [PATCH 0034/1906] UPDATE ::: Only removing variables when we flush to FE since we might remove a frame before we flush out a task that is running on it git-svn-id: svn://107.170.10.188:8080/Monolith/dev@27877 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 6295b88ab974df9e4e0b4ddeca071eb8a2e4b8c2 --- .../web/services/DataframeResource.java | 13 -------- .../semoss/web/services/NameServer.java | 2 +- .../web/services/util/PixelWebUtility.java | 31 ++++++++++++++----- 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/src/prerna/semoss/web/services/DataframeResource.java b/src/prerna/semoss/web/services/DataframeResource.java index 85f29c879..314afb3a5 100644 --- a/src/prerna/semoss/web/services/DataframeResource.java +++ b/src/prerna/semoss/web/services/DataframeResource.java @@ -80,19 +80,6 @@ public Response applyCalculation(MultivaluedMap form, @Context H return WebUtility.getResponse(stupidFEObj, 200); } - @POST - @Path("/runPksl2") - @Produces("application/json") - public Response runPixel(MultivaluedMap form, @Context HttpServletRequest request){ - String pixelCmd = form.getFirst("expression"); - Map resultHash = null; - synchronized(insight) { - resultHash = insight.runPixel(pixelCmd); - } - - return WebUtility.getResponse(resultHash, 200); - } - //for handling playsheet specific tool calls @POST @Path("do-{method}") diff --git a/src/prerna/semoss/web/services/NameServer.java b/src/prerna/semoss/web/services/NameServer.java index 039d00558..f7db2a339 100644 --- a/src/prerna/semoss/web/services/NameServer.java +++ b/src/prerna/semoss/web/services/NameServer.java @@ -1232,7 +1232,7 @@ public Response runPixelSync(MultivaluedMap form, @Context HttpS jt.setInsight(insight); jt.addPixel(expression); - jt.run2(); + jt.run(); PixelRunner pixelRunner = jt.getRunner(); manager.flushJob(jobId); diff --git a/src/prerna/web/services/util/PixelWebUtility.java b/src/prerna/web/services/util/PixelWebUtility.java index af9506926..b1a714641 100644 --- a/src/prerna/web/services/util/PixelWebUtility.java +++ b/src/prerna/web/services/util/PixelWebUtility.java @@ -26,6 +26,7 @@ import prerna.sablecc2.om.task.ConstantDataTask; import prerna.sablecc2.om.task.ITask; import prerna.sablecc2.reactor.frame.FrameFactory; +import prerna.util.insight.InsightUtility; public class PixelWebUtility extends WebUtility{ @@ -94,7 +95,7 @@ private static void processPixelRunner(PrintStream ps, Gson gson, PixelRunner ru String expression = pixelStrings.get(i); expression = PixelUtility.recreateOriginalPixelExpression(expression, encodedTextToOriginal); boolean meta = isMeta.get(i); - processNounMetadata(ps, gson, noun, expression, meta); + processNounMetadata(in, ps, gson, noun, expression, meta); // update the pixel list to say this is routine is valid // TODO: need to set this inside the translation directly!!! @@ -121,7 +122,7 @@ private static void processPixelRunner(PrintStream ps, Gson gson, PixelRunner ru * @param noun * @return */ - private static void processNounMetadata(PrintStream ps, Gson gson, NounMetadata noun, String expression, Boolean isMeta) { + private static void processNounMetadata(Insight in, PrintStream ps, Gson gson, NounMetadata noun, String expression, Boolean isMeta) { ps.print("{"); // add expression if there @@ -158,7 +159,7 @@ private static void processNounMetadata(PrintStream ps, Gson gson, NounMetadata if(numOutputs > 0) { ps.print(",\"additionalOutput\":["); for(int i = 0; i < numOutputs; i++) { - processNounMetadata(ps, gson, addReturns.get(i), null, null); + processNounMetadata(in, ps, gson, addReturns.get(i), null, null); } ps.print("]"); } @@ -172,7 +173,7 @@ private static void processNounMetadata(PrintStream ps, Gson gson, NounMetadata if(numOutputs > 0) { ps.print("\"output\":["); for(int i = 0; i < numOutputs; i++) { - processNounMetadata(ps, gson, codeOutputs.get(i), null, null); + processNounMetadata(in, ps, gson, codeOutputs.get(i), null, null); } ps.print("]"); } @@ -303,11 +304,11 @@ else if(nounT == PixelDataType.PIXEL_RUNNER) { Object params = runnerWraper.get("params"); List additionalPixels = (List) runnerWraper.get("additionalPixels"); - Insight in = runner.getInsight(); + Insight innerInsight = runner.getInsight(); ps.print("\"output\":{"); - ps.print("\"name\":" + gson.toJson(in.getInsightName())); - ps.print(",\"core_engine\":" + gson.toJson(in.getEngineName())); - ps.print(",\"core_engine_id\":" + gson.toJson(in.getRdbmsId())); + ps.print("\"name\":" + gson.toJson(innerInsight.getInsightName())); + ps.print(",\"core_engine\":" + gson.toJson(innerInsight.getEngineName())); + ps.print(",\"core_engine_id\":" + gson.toJson(innerInsight.getRdbmsId())); ps.print(",\"params\":" + gson.toJson(params)); ps.print(",\"additionalPixels\":" + gson.toJson(additionalPixels)); ps.flush(); @@ -319,6 +320,20 @@ else if(nounT == PixelDataType.PIXEL_RUNNER) { ps.print(gson.toJson(noun.getOpType())); ps.flush(); } + + // remove variable + else if(nounT == PixelDataType.REMOVE_VARIABLE) { + // we only remove variables at the end + // because the user may want to get the task and then + // remove teh frame right after + // so we need to remove only at the end + NounMetadata newNoun = InsightUtility.removeVaraible(in.getVarStore(), noun.getValue().toString()); + ps.print("\"output\":"); + ps.print(gson.toJson(newNoun.getValue())); + ps.print(",\"operationType\":"); + ps.print(gson.toJson(newNoun.getOpType())); + + } // everything else is simple else { From af007d70c953ec660a7f5d372a5e7ab65233a408 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 3 May 2018 20:26:36 +0000 Subject: [PATCH 0035/1906] UPDATE ::: Adding fix to remove task only at end git-svn-id: svn://107.170.10.188:8080/Monolith/dev@27879 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: bfbfd29649e43af37252636f615b6bfe8910478f --- .../web/services/util/PixelWebUtility.java | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/prerna/web/services/util/PixelWebUtility.java b/src/prerna/web/services/util/PixelWebUtility.java index b1a714641..9bb9a7fed 100644 --- a/src/prerna/web/services/util/PixelWebUtility.java +++ b/src/prerna/web/services/util/PixelWebUtility.java @@ -325,7 +325,7 @@ else if(nounT == PixelDataType.PIXEL_RUNNER) { else if(nounT == PixelDataType.REMOVE_VARIABLE) { // we only remove variables at the end // because the user may want to get the task and then - // remove teh frame right after + // remove the frame right after // so we need to remove only at the end NounMetadata newNoun = InsightUtility.removeVaraible(in.getVarStore(), noun.getValue().toString()); ps.print("\"output\":"); @@ -334,6 +334,20 @@ else if(nounT == PixelDataType.REMOVE_VARIABLE) { ps.print(gson.toJson(newNoun.getOpType())); } + + else if(nounT == PixelDataType.REMOVE_TASK) { + // we only remove variables at the end + // because the user may want to get the task and then + // remove the frame right after + // so we need to remove only at the end + ITask task = InsightUtility.removeTask(in, noun.getValue().toString()); + ps.print("\"output\":{"); + ps.print("\"taskId\":\"" + task.getId() + "\""); + ps.print("}"); + ps.print(",\"operationType\":"); + ps.print(gson.toJson(noun.getOpType())); + + } // everything else is simple else { From 4227ff9680d0e02f5dd0b8a0391e973cffac234f Mon Sep 17 00:00:00 2001 From: pkapaleeswaran Date: Fri, 4 May 2018 17:01:27 +0000 Subject: [PATCH 0036/1906] Added a call to pull all the logins. auth/logins git-svn-id: svn://107.170.10.188:8080/Monolith/dev@27893 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 8d746039cbf853d8af6af8331e50d7c69de2e374 --- .../semoss/web/services/UserResource.java | 34 ++++++++++++++++--- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/src/prerna/semoss/web/services/UserResource.java b/src/prerna/semoss/web/services/UserResource.java index 647e7607e..46f884cd5 100644 --- a/src/prerna/semoss/web/services/UserResource.java +++ b/src/prerna/semoss/web/services/UserResource.java @@ -481,6 +481,29 @@ public Response isUserLoggedIn(@Context HttpServletRequest request) { return WebUtility.getResponse(false, 200); } + + @GET + @Path("logins") + public Response getAllLogins(@Context HttpServletRequest request) { + + User2 semossUser = null; + Object user = request.getSession().getAttribute("semoss_user"); + + List logins = new ArrayList(); + + if(user != null) + { + semossUser = (User2)user; +// return Response.status(200).entity(WebUtility.getSO(true)).build(); + logins = semossUser.getLogins(); + } + Hashtable params = new Hashtable(); + params.put("logins", logins); + return WebUtility.getResponse(params, 200); + } + + + @GET @Produces("application/json") @Path("userinfo") @@ -1202,7 +1225,7 @@ public Response loginGoogle2(@Context HttpServletRequest request, @Context HttpS User2 user = (User2)userObj; AccessToken accessToken = user.getAccessToken(AuthProvider.GOOGLE.name()); - //performGoogleOps(request, ret); + performGoogleOps(request, ret); ret.put("success", true); try { //ret.put("user", BeanFiller.getJson(accessToken)); @@ -1264,13 +1287,14 @@ private void performGoogleOps(HttpServletRequest request, Hashtable ret) NLPDocumentInput docInput = new NLPDocumentInput(); docInput.setContent("Obama is staying in the whitehouse !!"); + params2 = new Hashtable(); - Hashtable docInputShell = new Hashtable(); - docInputShell.put("encodingType", "UTF8"); - docInputShell.put("document", docInput); + //Hashtable docInputShell = new Hashtable(); + params2.put("encodingType", "UTF8"); + params2.put("document", docInput); - params2.put("input", docInputShell); + //params2.put("input", docInputShell); ner.execute((User2)request.getSession().getAttribute("semoss_user"), params2); try { From 42e6d7dae040a43b6517287945e3ff81f4f1dc52 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 7 May 2018 17:10:06 +0000 Subject: [PATCH 0037/1906] UPDATE ::: Returning true/false correctly when attempting to logout of a specific provider git-svn-id: svn://107.170.10.188:8080/Monolith/dev@27912 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 8023d4f72239b10c6431e4da0c32e0eb85cc9b8a --- .../semoss/web/services/UserResource.java | 61 ++++++++----------- 1 file changed, 26 insertions(+), 35 deletions(-) diff --git a/src/prerna/semoss/web/services/UserResource.java b/src/prerna/semoss/web/services/UserResource.java index 46f884cd5..ba957d721 100644 --- a/src/prerna/semoss/web/services/UserResource.java +++ b/src/prerna/semoss/web/services/UserResource.java @@ -50,7 +50,6 @@ import java.util.HashMap; import java.util.Hashtable; import java.util.List; -import java.util.Map; import java.util.Properties; import java.util.Scanner; import java.util.UUID; @@ -74,8 +73,6 @@ import javax.ws.rs.core.Response; import javax.ws.rs.core.StreamingOutput; -import jodd.util.URLDecoder; - import org.apache.http.HttpEntity; import org.apache.http.NameValuePair; import org.apache.http.client.ResponseHandler; @@ -89,6 +86,25 @@ import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; +import com.google.api.client.auth.oauth2.TokenResponseException; +import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeTokenRequest; +import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; +import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken; +import com.google.api.client.googleapis.auth.oauth2.GoogleTokenResponse; +import com.google.api.client.http.HttpTransport; +import com.google.api.client.http.javanet.NetHttpTransport; +import com.google.api.client.json.jackson2.JacksonFactory; +import com.google.api.services.oauth2.Oauth2; +import com.google.api.services.oauth2.model.Userinfoplus; +import com.google.gson.Gson; +import com.google.gson.internal.StringMap; +import com.restfb.DefaultFacebookClient; +import com.restfb.FacebookClient; +import com.restfb.Parameter; +import com.sun.jna.platform.win32.Secur32; +import com.sun.jna.platform.win32.Secur32Util; + +import jodd.util.URLDecoder; import prerna.auth.AccessToken; import prerna.auth.AppTokens; import prerna.auth.AuthProvider; @@ -104,11 +120,6 @@ import prerna.io.connector.google.GoogleProfile; import prerna.io.connector.twitter.TwitterSearcher; import prerna.om.NLPDocumentInput; -import prerna.om.Viewpoint; -import prerna.sablecc2.om.PixelDataType; -import prerna.sablecc2.om.PixelOperationType; -import prerna.sablecc2.om.execptions.SemossPixelException; -import prerna.sablecc2.om.nounmeta.NounMetadata; import prerna.security.AbstractHttpHelper; import prerna.util.BeanFiller; import prerna.util.Constants; @@ -116,24 +127,6 @@ import prerna.web.services.util.WebUtility; import waffle.servlet.WindowsPrincipal; -import com.google.api.client.auth.oauth2.TokenResponseException; -import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeTokenRequest; -import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; -import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken; -import com.google.api.client.googleapis.auth.oauth2.GoogleTokenResponse; -import com.google.api.client.http.HttpTransport; -import com.google.api.client.http.javanet.NetHttpTransport; -import com.google.api.client.json.jackson2.JacksonFactory; -import com.google.api.services.oauth2.Oauth2; -import com.google.api.services.oauth2.model.Userinfoplus; -import com.google.gson.Gson; -import com.google.gson.internal.StringMap; -import com.restfb.DefaultFacebookClient; -import com.restfb.FacebookClient; -import com.restfb.Parameter; -import com.sun.jna.platform.win32.Secur32; -import com.sun.jna.platform.win32.Secur32Util; - @Path("/auth") public class UserResource { @@ -1767,21 +1760,19 @@ private static String toHexString(byte[] bytes) { @Path("/logout/{provider}") public Response logout(@PathParam("provider") String provider, @Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException { - if(provider.equalsIgnoreCase("ALL")) - { + boolean removed = false; + if(provider.equalsIgnoreCase("ALL")) { // remove the user from session call it a day request.getSession().removeAttribute("semoss_user"); - } - else - { + removed = true; + } else { User2 thisUser = (User2)request.getSession().getAttribute("semoss_user"); - thisUser.dropAccessToken(provider.toUpperCase()); - request.getSession().setAttribute("semoss_user",thisUser); + removed = thisUser.dropAccessToken(provider.toUpperCase()); + request.getSession().setAttribute("semoss_user", thisUser); } Hashtable ret = new Hashtable(); - ret.put("success", true); - // return Response.status(200).entity(WebUtility.getSO(ret)).build(); + ret.put("success", removed); return WebUtility.getResponse(ret, 200); } From af982385924333570a80c9aca35aaa7ce49ed1fa Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 8 May 2018 16:28:52 +0000 Subject: [PATCH 0038/1906] UPDATE ::: Catching exceptions when trying to remove a task that doesn't exist git-svn-id: svn://107.170.10.188:8080/Monolith/dev@27924 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 34a026db4da4f764493ab2433bb7742bd63cbbe8 --- .../web/services/util/PixelWebUtility.java | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/prerna/web/services/util/PixelWebUtility.java b/src/prerna/web/services/util/PixelWebUtility.java index 9bb9a7fed..ba2e7e1dc 100644 --- a/src/prerna/web/services/util/PixelWebUtility.java +++ b/src/prerna/web/services/util/PixelWebUtility.java @@ -342,11 +342,17 @@ else if(nounT == PixelDataType.REMOVE_TASK) { // so we need to remove only at the end ITask task = InsightUtility.removeTask(in, noun.getValue().toString()); ps.print("\"output\":{"); - ps.print("\"taskId\":\"" + task.getId() + "\""); - ps.print("}"); - ps.print(",\"operationType\":"); - ps.print(gson.toJson(noun.getOpType())); - + if(task == null) { + ps.print("\"taskId\":\"Could not find task id = " + noun.getValue().toString() + "\""); + ps.print("}"); + ps.print(",\"operationType\":"); + ps.print(gson.toJson(new PixelOperationType[]{PixelOperationType.ERROR})); + } else { + ps.print("\"taskId\":\"" + task.getId() + "\""); + ps.print("}"); + ps.print(",\"operationType\":"); + ps.print(gson.toJson(noun.getOpType())); + } } // everything else is simple From a16c60c41c8fdb42b3ba2d73e9f276551e9e997b Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 14 May 2018 19:32:27 +0000 Subject: [PATCH 0039/1906] UPDATE ::: Adding cac filter git-svn-id: svn://107.170.10.188:8080/Monolith/dev@27992 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 235724fb4ce3f3a918c926a88ed78f2488eafcb9 --- src/prerna/web/conf/CACFilter.java | 58 ++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 src/prerna/web/conf/CACFilter.java diff --git a/src/prerna/web/conf/CACFilter.java b/src/prerna/web/conf/CACFilter.java new file mode 100644 index 000000000..445d9efd7 --- /dev/null +++ b/src/prerna/web/conf/CACFilter.java @@ -0,0 +1,58 @@ +package prerna.web.conf; + +import java.io.IOException; +import java.security.cert.X509Certificate; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +public class CACFilter implements Filter { + + @Override + public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { + X509Certificate[] certs = (X509Certificate[]) arg0.getAttribute("javax.servlet.request.X509Certificate"); + HttpSession session = ((HttpServletRequest)arg0).getSession(false); + + if(session != null) { + + if(certs != null) { + for(int i = 0; i < certs.length; i++) { + X509Certificate cert = certs[i]; + + System.out.println(" Client certificate " + (i + 1) + ":"); + System.out.println(" Subject DN: " + cert.getSubjectDN()); + System.out.println(" Subject Name: " + cert.getSubjectX500Principal().getName()); + + System.out.println(" Signature Algorithm: " + cert.getSigAlgName()); + System.out.println(" Valid from: " + cert.getNotBefore()); + System.out.println(" Valid until: " + cert.getNotAfter()); + System.out.println(" Issuer: " + cert.getIssuerDN()); + } + } + + } + + arg2.doFilter(arg0, arg1); + } + + @Override + public void destroy() { + // TODO Auto-generated method stub + + } + + + + @Override + public void init(FilterConfig arg0) throws ServletException { + // TODO Auto-generated method stub + + } + +} From f084840111087a6639de912f60eae5189ed01f00 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 14 May 2018 20:45:37 +0000 Subject: [PATCH 0040/1906] UPDATE ::: Building out logic for cac filter git-svn-id: svn://107.170.10.188:8080/Monolith/dev@27996 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 80861c233e1441de67e22134ffb5e44a23bd98b5 --- WebContent/WEB-INF/web.xml | 36 ++++++-------------- src/prerna/web/conf/CACFilter.java | 54 ++++++++++++++++++++---------- 2 files changed, 48 insertions(+), 42 deletions(-) diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index b95ed9c3d..75f80c101 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -4,6 +4,16 @@ index.html + UserDBFilter prerna.web.conf.UserDBFilter @@ -109,31 +119,7 @@ The place where the core RDF Map gets picked from RDF-MAP C:\\workspace\\Semoss_Dev\\RDF_Map.prop - - - - - - google_client_id - placeholder - - - google_secret_key - placeholder - - - google_redirect_uri - http://localhost:8080/Monolith_Dev/api/auth/login/google2 - - - google_scope - https://www.googleapis.com/auth/forms https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/drive.metadata https://www.googleapis.com/auth/cloud-language - - - google_access_type - offline - - + prerna.web.conf.DBLoader diff --git a/src/prerna/web/conf/CACFilter.java b/src/prerna/web/conf/CACFilter.java index 445d9efd7..a83e321bd 100644 --- a/src/prerna/web/conf/CACFilter.java +++ b/src/prerna/web/conf/CACFilter.java @@ -3,6 +3,9 @@ import java.io.IOException; import java.security.cert.X509Certificate; +import javax.naming.InvalidNameException; +import javax.naming.ldap.LdapName; +import javax.naming.ldap.Rdn; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; @@ -12,6 +15,10 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; +import prerna.auth.AccessToken; +import prerna.auth.AuthProvider; +import prerna.auth.User2; + public class CACFilter implements Filter { @Override @@ -19,23 +26,38 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 X509Certificate[] certs = (X509Certificate[]) arg0.getAttribute("javax.servlet.request.X509Certificate"); HttpSession session = ((HttpServletRequest)arg0).getSession(false); - if(session != null) { - - if(certs != null) { - for(int i = 0; i < certs.length; i++) { - X509Certificate cert = certs[i]; - - System.out.println(" Client certificate " + (i + 1) + ":"); - System.out.println(" Subject DN: " + cert.getSubjectDN()); - System.out.println(" Subject Name: " + cert.getSubjectX500Principal().getName()); - - System.out.println(" Signature Algorithm: " + cert.getSigAlgName()); - System.out.println(" Valid from: " + cert.getNotBefore()); - System.out.println(" Valid until: " + cert.getNotAfter()); - System.out.println(" Issuer: " + cert.getIssuerDN()); + if(session != null && certs != null) { + User2 user = (User2) session.getAttribute("semoss_user"); + if(user == null) { + user = new User2(); + } + + AccessToken token = new AccessToken(); + + for(int i = 0; i < certs.length; i++) { + X509Certificate cert = certs[i]; + + token.setToken_type(AuthProvider.CAC.toString()); + token.setProvider(cert.getIssuerDN().getName()); + token.setExpires_in((int) cert.getNotAfter().getTime()); + + String fullName = cert.getSubjectX500Principal().getName(); + LdapName ldapDN; + try { + ldapDN = new LdapName(fullName); + for(Rdn rdn: ldapDN.getRdns()) { + if(rdn.getType().equals("CN")) { + token.setName(rdn.getValue().toString()); + } + } + } catch (InvalidNameException e) { + token.setName(fullName); + e.printStackTrace(); } } - + + user.setAccessToken(token); + session.setAttribute("semoss-user", user); } arg2.doFilter(arg0, arg1); @@ -47,8 +69,6 @@ public void destroy() { } - - @Override public void init(FilterConfig arg0) throws ServletException { // TODO Auto-generated method stub From e1b6fdae17243df2f0a59cb84d351785ffe4ea37 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 15 May 2018 15:52:57 +0000 Subject: [PATCH 0041/1906] UPDATE ::: Adding content type to say we are returning an image in the content type git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28010 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: ac2258db0cf78221e8f93a1f78e51448bcd1a3c4 --- src/prerna/semoss/web/services/AppResource.java | 10 +++++----- src/prerna/semoss/web/services/NameServer.java | 13 ++++++------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/prerna/semoss/web/services/AppResource.java b/src/prerna/semoss/web/services/AppResource.java index a8d2bd03d..bbf43c0cd 100644 --- a/src/prerna/semoss/web/services/AppResource.java +++ b/src/prerna/semoss/web/services/AppResource.java @@ -46,7 +46,7 @@ public Response getAppImage(@PathParam("appName") String app) { try { fis = new FileInputStream(f); byte[] byteArray = IOUtils.toByteArray(fis); - return Response.status(200).entity(byteArray).build(); + return Response.status(200).entity(byteArray).header("Content-Type", "image/*").build(); } catch (IOException e) { e.printStackTrace(); } finally { @@ -65,7 +65,7 @@ public Response getAppImage(@PathParam("appName") String app) { f = new File(fileLocation); fis = new FileInputStream(f); byte[] byteArray = IOUtils.toByteArray(fis); - return Response.status(200).entity(byteArray).build(); + return Response.status(200).entity(byteArray).header("Content-Type", "image/*").build(); } catch (IOException e) { Map errorMap = new HashMap(); errorMap.put("errorMessage", "error sending image file"); @@ -88,7 +88,7 @@ public Response getInsightImage(@Context HttpServletRequest request, @PathParam( try { fis = new FileInputStream(f); byte[] byteArray = IOUtils.toByteArray(fis); - return Response.status(200).entity(byteArray).build(); + return Response.status(200).entity(byteArray).header("Content-Type", "image/*").build(); } catch (IOException e) { e.printStackTrace(); } finally { @@ -105,7 +105,7 @@ public Response getInsightImage(@Context HttpServletRequest request, @PathParam( try { fis = new FileInputStream(f); byte[] byteArray = IOUtils.toByteArray(fis); - return Response.status(200).entity(byteArray).build(); + return Response.status(200).entity(byteArray).header("Content-Type", "image/*").build(); } catch (IOException e) { e.printStackTrace(); } finally { @@ -119,7 +119,7 @@ public Response getInsightImage(@Context HttpServletRequest request, @PathParam( try { fis = new FileInputStream(f); byte[] byteArray = IOUtils.toByteArray(fis); - return Response.status(200).entity(byteArray).build(); + return Response.status(200).entity(byteArray).header("Content-Type", "image/*").build(); } catch (IOException e) { Map errorMap = new HashMap(); errorMap.put("errorMessage", "error sending image file"); diff --git a/src/prerna/semoss/web/services/NameServer.java b/src/prerna/semoss/web/services/NameServer.java index f7db2a339..9171e84de 100644 --- a/src/prerna/semoss/web/services/NameServer.java +++ b/src/prerna/semoss/web/services/NameServer.java @@ -1020,8 +1020,7 @@ public Response downloadFile(@QueryParam("insightId") String insightId, @QueryPa String modifiedDate = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_SSSS").format(date); String exportName = "SEMOSS_Export_" + modifiedDate + "." + FilenameUtils.getExtension(filePath); - return Response.status(200).entity(exportFile) - .header("Content-Disposition", "attachment; filename=" + exportName).build(); + return Response.status(200).entity(exportFile).header("Content-Disposition", "attachment; filename=" + exportName).build(); } @GET @@ -1036,7 +1035,7 @@ public Response getAppImage(@QueryParam("app") String app) { try { fis = new FileInputStream(f); byte[] byteArray = IOUtils.toByteArray(fis); - return Response.status(200).entity(byteArray).build(); + return Response.status(200).entity(byteArray).header("Content-Type", "image/*").build(); } catch (IOException e) { e.printStackTrace(); } finally { @@ -1055,7 +1054,7 @@ public Response getAppImage(@QueryParam("app") String app) { f = new File(fileLocation); fis = new FileInputStream(f); byte[] byteArray = IOUtils.toByteArray(fis); - return Response.status(200).entity(byteArray).build(); + return Response.status(200).entity(byteArray).header("Content-Type", "image/*").build(); } catch (IOException e) { Map errorMap = new HashMap(); errorMap.put("errorMessage", "error sending image file"); @@ -1099,7 +1098,7 @@ public Response getInsightImage(@Context HttpServletRequest request, @QueryParam try { fis = new FileInputStream(f); byte[] byteArray = IOUtils.toByteArray(fis); - return Response.status(200).entity(byteArray).build(); + return Response.status(200).entity(byteArray).header("Content-Type", "image/*").build(); } catch (IOException e) { e.printStackTrace(); } finally { @@ -1116,7 +1115,7 @@ public Response getInsightImage(@Context HttpServletRequest request, @QueryParam try { fis = new FileInputStream(f); byte[] byteArray = IOUtils.toByteArray(fis); - return Response.status(200).entity(byteArray).build(); + return Response.status(200).entity(byteArray).header("Content-Type", "image/*").build(); } catch (IOException e) { e.printStackTrace(); } finally { @@ -1130,7 +1129,7 @@ public Response getInsightImage(@Context HttpServletRequest request, @QueryParam try { fis = new FileInputStream(f); byte[] byteArray = IOUtils.toByteArray(fis); - return Response.status(200).entity(byteArray).build(); + return Response.status(200).entity(byteArray).header("Content-Type", "image/*").build(); } catch (IOException e) { Map errorMap = new HashMap(); errorMap.put("errorMessage", "error sending image file"); From 5248defaeb63a10695f5aa833480b504cb3956ad Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 15 May 2018 16:54:53 +0000 Subject: [PATCH 0042/1906] UPDATE ::: Consolidating methods from NameServer and AppResource UPDATE ::: Sending file directly instead of flushing to byte[] first git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28011 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 9b4ff843ebe52caf38e586882c587abaedec4c10 --- .../semoss/web/services/AppResource.java | 123 +++++++-------- .../semoss/web/services/NameServer.java | 142 ++---------------- 2 files changed, 69 insertions(+), 196 deletions(-) diff --git a/src/prerna/semoss/web/services/AppResource.java b/src/prerna/semoss/web/services/AppResource.java index bbf43c0cd..3cb54b704 100644 --- a/src/prerna/semoss/web/services/AppResource.java +++ b/src/prerna/semoss/web/services/AppResource.java @@ -19,6 +19,7 @@ import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; +import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.io.filefilter.WildcardFileFilter; @@ -35,104 +36,86 @@ public class AppResource { private static final String DIR_SEPARATOR = java.nio.file.FileSystems.getDefault().getSeparator(); @GET - @Path("/appImage") - @Produces("image/*") - public Response getAppImage(@PathParam("appName") String app) { + @Path("/appImage/download") + @Produces(MediaType.APPLICATION_OCTET_STREAM) + public Response downloadAppImage(@PathParam("appName") String app) { + File exportFile = getAppImageFile(app); + if(exportFile.exists()) { + String exportName = app + "_Image." + FilenameUtils.getExtension(exportFile.getAbsolutePath()); + return Response.status(200).entity(exportFile).header("Content-Disposition", "attachment; filename=" + exportName).build(); + } else { + Map errorMap = new HashMap(); + errorMap.put("errorMessage", "error sending image file"); + return Response.status(400).entity(errorMap).build(); + } + } + + /** + * Use to find the file for the image + * @param app + * @return + */ + private File getAppImageFile(String app) { String baseFolder = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER); String fileLocation = baseFolder + DIR_SEPARATOR + "db" + DIR_SEPARATOR + app + DIR_SEPARATOR + "version"; File f = findImageFile(fileLocation); - FileInputStream fis = null; if(f != null) { - try { - fis = new FileInputStream(f); - byte[] byteArray = IOUtils.toByteArray(fis); - return Response.status(200).entity(byteArray).header("Content-Type", "image/*").build(); - } catch (IOException e) { - e.printStackTrace(); - } finally { - closeStream(fis); - } - Map errorMap = new HashMap(); - errorMap.put("errorMessage", "error sending image file"); - return Response.status(400).entity(errorMap).build(); + return f; } else { // make the image f = new File(fileLocation); f.mkdirs(); fileLocation = fileLocation + DIR_SEPARATOR + "image.png"; TextToGraphic.makeImage(app, fileLocation); - try { - f = new File(fileLocation); - fis = new FileInputStream(f); - byte[] byteArray = IOUtils.toByteArray(fis); - return Response.status(200).entity(byteArray).header("Content-Type", "image/*").build(); - } catch (IOException e) { - Map errorMap = new HashMap(); - errorMap.put("errorMessage", "error sending image file"); - return Response.status(400).entity(errorMap).build(); - } finally { - closeStream(fis); - } + f = new File(fileLocation); + return f; } } @GET - @Path("/insightImage") - @Produces("image/*") - public Response getInsightImage(@Context HttpServletRequest request, @PathParam("appName") String app, @QueryParam("rdbmsId") String insightId) { + @Path("/insightImage/download") + @Produces(MediaType.APPLICATION_OCTET_STREAM) + public Response downloadInsightImage(@Context HttpServletRequest request, @PathParam("appName") String app, @QueryParam("rdbmsId") String insightId) { + File exportFile = getInsightImageFile(app, insightId, request.getHeader("Referer")); + if(exportFile.exists()) { + String exportName = app + "_Image." + FilenameUtils.getExtension(exportFile.getAbsolutePath()); + return Response.status(200).entity(exportFile).header("Content-Disposition", "attachment; filename=" + exportName).build(); + } else { + Map errorMap = new HashMap(); + errorMap.put("errorMessage", "error sending image file"); + return Response.status(400).entity(errorMap).build(); + } + } + + /** + * Use to find the file for the image + * @param app + * @return + */ + private File getInsightImageFile(String app, String insightId, String feUrl) { String baseFolder = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER); String fileLocation = baseFolder + DIR_SEPARATOR + "db" + DIR_SEPARATOR + app + DIR_SEPARATOR + "version" + DIR_SEPARATOR + insightId + DIR_SEPARATOR + "image.png"; File f = new File(fileLocation); - FileInputStream fis = null; if(f.exists()) { - try { - fis = new FileInputStream(f); - byte[] byteArray = IOUtils.toByteArray(fis); - return Response.status(200).entity(byteArray).header("Content-Type", "image/*").build(); - } catch (IOException e) { - e.printStackTrace(); - } finally { - closeStream(fis); - } - Map errorMap = new HashMap(); - errorMap.put("errorMessage", "error sending image file"); - return Response.status(400).entity(errorMap).build(); + return f; } else { - String feUrl = request.getHeader("Referer"); // try making the image ImageCaptureReactor.runImageCapture(feUrl, app, insightId); if(f.exists()) { - try { - fis = new FileInputStream(f); - byte[] byteArray = IOUtils.toByteArray(fis); - return Response.status(200).entity(byteArray).header("Content-Type", "image/*").build(); - } catch (IOException e) { - e.printStackTrace(); - } finally { - closeStream(fis); - } - Map errorMap = new HashMap(); - errorMap.put("errorMessage", "error sending image file"); - return Response.status(400).entity(errorMap).build(); + return f; } else { + // return stock image f = SolrUtility.getStockImage(app, insightId); - try { - fis = new FileInputStream(f); - byte[] byteArray = IOUtils.toByteArray(fis); - return Response.status(200).entity(byteArray).header("Content-Type", "image/*").build(); - } catch (IOException e) { - Map errorMap = new HashMap(); - errorMap.put("errorMessage", "error sending image file"); - return Response.status(400).entity(errorMap).build(); - } finally { - closeStream(fis); - } + return f; } } - - } + + /* + * Currently not used below... + */ + @GET @Path("/appWidget") @Produces(MediaType.APPLICATION_OCTET_STREAM) diff --git a/src/prerna/semoss/web/services/NameServer.java b/src/prerna/semoss/web/services/NameServer.java index 9171e84de..e0ba5112b 100644 --- a/src/prerna/semoss/web/services/NameServer.java +++ b/src/prerna/semoss/web/services/NameServer.java @@ -28,8 +28,6 @@ package prerna.semoss.web.services; import java.io.File; -import java.io.FileFilter; -import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -47,7 +45,6 @@ import java.util.Hashtable; import java.util.List; import java.util.Map; -import java.util.Vector; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; @@ -68,8 +65,6 @@ import javax.ws.rs.core.StreamingOutput; import org.apache.commons.io.FilenameUtils; -import org.apache.commons.io.IOUtils; -import org.apache.commons.io.filefilter.WildcardFileFilter; import org.apache.http.HttpEntity; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.methods.CloseableHttpResponse; @@ -100,11 +95,9 @@ import prerna.sablecc2.PixelRunner; import prerna.sablecc2.comm.JobManager; import prerna.sablecc2.comm.JobThread; -import prerna.sablecc2.reactor.utils.ImageCaptureReactor; import prerna.solr.SolrIndexEngine; import prerna.solr.SolrIndexEngine.SOLR_PATHS; import prerna.solr.SolrIndexEngineQueryBuilder; -import prerna.solr.SolrUtility; import prerna.upload.DatabaseUploader; import prerna.upload.FileUploader; import prerna.upload.ImageUploader; @@ -114,7 +107,6 @@ import prerna.util.PlaySheetRDFMapBasedEnum; import prerna.util.Utility; import prerna.util.insight.InsightScreenshot; -import prerna.util.insight.TextToGraphic; import prerna.web.services.util.PixelWebUtility; import prerna.web.services.util.ResponseHashSingleton; import prerna.web.services.util.SemossExecutorSingleton; @@ -127,9 +119,6 @@ public class NameServer { @Context private ServletContext context; - // get the directory separator - private static final String DIR_SEPARATOR = java.nio.file.FileSystems.getDefault().getSeparator(); - private static final Logger logger = Logger.getLogger(NameServer.class.getName()); private Hashtable helpHash = null; UserPermissionsMasterDB permissions = new UserPermissionsMasterDB(); @@ -1023,133 +1012,34 @@ public Response downloadFile(@QueryParam("insightId") String insightId, @QueryPa return Response.status(200).entity(exportFile).header("Content-Disposition", "attachment; filename=" + exportName).build(); } + /////////////////////////////////////////////// + /////////////////////////////////////////////// + /////////////////////////////////////////////// + + /* + * TODO: move FE to use app resource calls + */ + @GET @Path("/appImage") @Produces("image/*") public Response getAppImage(@QueryParam("app") String app) { - String baseFolder = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER); - String fileLocation = baseFolder + DIR_SEPARATOR + "db" + DIR_SEPARATOR + app + DIR_SEPARATOR + "version"; - File f = findImageFile(fileLocation); - FileInputStream fis = null; - if(f != null) { - try { - fis = new FileInputStream(f); - byte[] byteArray = IOUtils.toByteArray(fis); - return Response.status(200).entity(byteArray).header("Content-Type", "image/*").build(); - } catch (IOException e) { - e.printStackTrace(); - } finally { - closeStream(fis); - } - Map errorMap = new HashMap(); - errorMap.put("errorMessage", "error sending image file"); - return Response.status(400).entity(errorMap).build(); - } else { - // make the image - f = new File(fileLocation); - f.mkdirs(); - fileLocation = fileLocation + DIR_SEPARATOR + "image.png"; - TextToGraphic.makeImage(app, fileLocation); - try { - f = new File(fileLocation); - fis = new FileInputStream(f); - byte[] byteArray = IOUtils.toByteArray(fis); - return Response.status(200).entity(byteArray).header("Content-Type", "image/*").build(); - } catch (IOException e) { - Map errorMap = new HashMap(); - errorMap.put("errorMessage", "error sending image file"); - return Response.status(400).entity(errorMap).build(); - } finally { - closeStream(fis); - } - } - } - - /** - * Find an image in the directory - * @param baseDir - * @return - */ - private File findImageFile(String baseDir) { - List extensions = new Vector(); - extensions.add("image.png"); - extensions.add("image.jpeg"); - extensions.add("image.jpg"); - extensions.add("image.gif"); - extensions.add("image.svg"); - FileFilter imageExtensionFilter = new WildcardFileFilter(extensions); - File baseFolder = new File(baseDir); - File[] imageFiles = baseFolder.listFiles(imageExtensionFilter); - if(imageFiles != null && imageFiles.length > 0) { - return imageFiles[0]; - } - return null; + AppResource r = new AppResource(); + return r.downloadAppImage(app); } @GET @Path("/insightImage") @Produces("image/*") public Response getInsightImage(@Context HttpServletRequest request, @QueryParam("app") String app, @QueryParam("rdbmsId") String insightId) { - String baseFolder = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER); - String fileLocation = baseFolder + DIR_SEPARATOR + "db" + DIR_SEPARATOR + app + DIR_SEPARATOR + "version" + DIR_SEPARATOR + insightId + DIR_SEPARATOR + "image.png"; - File f = new File(fileLocation); - FileInputStream fis = null; - if(f.exists()) { - try { - fis = new FileInputStream(f); - byte[] byteArray = IOUtils.toByteArray(fis); - return Response.status(200).entity(byteArray).header("Content-Type", "image/*").build(); - } catch (IOException e) { - e.printStackTrace(); - } finally { - closeStream(fis); - } - Map errorMap = new HashMap(); - errorMap.put("errorMessage", "error sending image file"); - return Response.status(400).entity(errorMap).build(); - } else { - String feUrl = request.getHeader("Referer"); - // try making the image - ImageCaptureReactor.runImageCapture(feUrl, app, insightId); - if(f.exists()) { - try { - fis = new FileInputStream(f); - byte[] byteArray = IOUtils.toByteArray(fis); - return Response.status(200).entity(byteArray).header("Content-Type", "image/*").build(); - } catch (IOException e) { - e.printStackTrace(); - } finally { - closeStream(fis); - } - Map errorMap = new HashMap(); - errorMap.put("errorMessage", "error sending image file"); - return Response.status(400).entity(errorMap).build(); - } else { - f = SolrUtility.getStockImage(app, insightId); - try { - fis = new FileInputStream(f); - byte[] byteArray = IOUtils.toByteArray(fis); - return Response.status(200).entity(byteArray).header("Content-Type", "image/*").build(); - } catch (IOException e) { - Map errorMap = new HashMap(); - errorMap.put("errorMessage", "error sending image file"); - return Response.status(400).entity(errorMap).build(); - } finally { - closeStream(fis); - } - } - } + AppResource r = new AppResource(); + return r.downloadInsightImage(request, app, insightId); } - private void closeStream(FileInputStream fis) { - if(fis != null) { - try { - fis.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } + /////////////////////////////////////////////// + /////////////////////////////////////////////// + /////////////////////////////////////////////// + @POST @Path("/runPixel") From b3d24c494563de283d23da93f7141ef8e8be1011 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 16 May 2018 21:37:24 +0000 Subject: [PATCH 0043/1906] UPDATE ::: Logic to take in parameters for image capture / download git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28037 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: e79573a112008dc72a9f040a6166ccddaef35f8b --- src/prerna/semoss/web/services/AppResource.java | 15 ++++++++++----- src/prerna/semoss/web/services/NameServer.java | 4 ++-- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/src/prerna/semoss/web/services/AppResource.java b/src/prerna/semoss/web/services/AppResource.java index 3cb54b704..13c99ee9d 100644 --- a/src/prerna/semoss/web/services/AppResource.java +++ b/src/prerna/semoss/web/services/AppResource.java @@ -75,8 +75,8 @@ private File getAppImageFile(String app) { @GET @Path("/insightImage/download") @Produces(MediaType.APPLICATION_OCTET_STREAM) - public Response downloadInsightImage(@Context HttpServletRequest request, @PathParam("appName") String app, @QueryParam("rdbmsId") String insightId) { - File exportFile = getInsightImageFile(app, insightId, request.getHeader("Referer")); + public Response downloadInsightImage(@Context HttpServletRequest request, @PathParam("appName") String app, @QueryParam("rdbmsId") String insightId, @QueryParam("params") String params) { + File exportFile = getInsightImageFile(app, insightId, request.getHeader("Referer"), params); if(exportFile.exists()) { String exportName = app + "_Image." + FilenameUtils.getExtension(exportFile.getAbsolutePath()); return Response.status(200).entity(exportFile).header("Content-Disposition", "attachment; filename=" + exportName).build(); @@ -92,15 +92,20 @@ public Response downloadInsightImage(@Context HttpServletRequest request, @PathP * @param app * @return */ - private File getInsightImageFile(String app, String insightId, String feUrl) { + private File getInsightImageFile(String app, String insightId, String feUrl, String params) { String baseFolder = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER); - String fileLocation = baseFolder + DIR_SEPARATOR + "db" + DIR_SEPARATOR + app + DIR_SEPARATOR + "version" + DIR_SEPARATOR + insightId + DIR_SEPARATOR + "image.png"; + String fileLocation = ""; + if(params != null && !params.isEmpty() && !params.equals("undefined")) { + fileLocation = baseFolder + DIR_SEPARATOR + "db" + DIR_SEPARATOR + app + DIR_SEPARATOR + "version" + DIR_SEPARATOR + insightId + params + DIR_SEPARATOR + "image.png"; + } else { + fileLocation = baseFolder + DIR_SEPARATOR + "db" + DIR_SEPARATOR + app + DIR_SEPARATOR + "version" + DIR_SEPARATOR + insightId + DIR_SEPARATOR + "image.png"; + } File f = new File(fileLocation); if(f.exists()) { return f; } else { // try making the image - ImageCaptureReactor.runImageCapture(feUrl, app, insightId); + ImageCaptureReactor.runImageCapture(feUrl, app, insightId, params); if(f.exists()) { return f; } else { diff --git a/src/prerna/semoss/web/services/NameServer.java b/src/prerna/semoss/web/services/NameServer.java index e0ba5112b..fbd3ade8c 100644 --- a/src/prerna/semoss/web/services/NameServer.java +++ b/src/prerna/semoss/web/services/NameServer.java @@ -1031,9 +1031,9 @@ public Response getAppImage(@QueryParam("app") String app) { @GET @Path("/insightImage") @Produces("image/*") - public Response getInsightImage(@Context HttpServletRequest request, @QueryParam("app") String app, @QueryParam("rdbmsId") String insightId) { + public Response getInsightImage(@Context HttpServletRequest request, @QueryParam("app") String app, @QueryParam("rdbmsId") String insightId, @QueryParam("params") String params) { AppResource r = new AppResource(); - return r.downloadInsightImage(request, app, insightId); + return r.downloadInsightImage(request, app, insightId, params); } /////////////////////////////////////////////// From e48fde7824a3b92b1dc732da806464a6c114f7c9 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 16 May 2018 21:49:48 +0000 Subject: [PATCH 0044/1906] UPDATE :::: Encoding the params to find the image git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28039 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 438d8ce644981b83379e956c031a62708094abf9 --- src/prerna/semoss/web/services/AppResource.java | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/prerna/semoss/web/services/AppResource.java b/src/prerna/semoss/web/services/AppResource.java index 13c99ee9d..c6e5631e5 100644 --- a/src/prerna/semoss/web/services/AppResource.java +++ b/src/prerna/semoss/web/services/AppResource.java @@ -27,6 +27,7 @@ import prerna.solr.SolrUtility; import prerna.util.Constants; import prerna.util.DIHelper; +import prerna.util.Utility; import prerna.util.insight.TextToGraphic; import prerna.web.services.util.WebUtility; @@ -75,8 +76,8 @@ private File getAppImageFile(String app) { @GET @Path("/insightImage/download") @Produces(MediaType.APPLICATION_OCTET_STREAM) - public Response downloadInsightImage(@Context HttpServletRequest request, @PathParam("appName") String app, @QueryParam("rdbmsId") String insightId, @QueryParam("params") String params) { - File exportFile = getInsightImageFile(app, insightId, request.getHeader("Referer"), params); + public Response downloadInsightImage(@Context HttpServletRequest request, @PathParam("appName") String app, @QueryParam("rdbmsId") String id, @QueryParam("params") String params) { + File exportFile = getInsightImageFile(app, id, request.getHeader("Referer"), params); if(exportFile.exists()) { String exportName = app + "_Image." + FilenameUtils.getExtension(exportFile.getAbsolutePath()); return Response.status(200).entity(exportFile).header("Content-Disposition", "attachment; filename=" + exportName).build(); @@ -92,25 +93,26 @@ public Response downloadInsightImage(@Context HttpServletRequest request, @PathP * @param app * @return */ - private File getInsightImageFile(String app, String insightId, String feUrl, String params) { + private File getInsightImageFile(String app, String id, String feUrl, String params) { String baseFolder = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER); String fileLocation = ""; if(params != null && !params.isEmpty() && !params.equals("undefined")) { - fileLocation = baseFolder + DIR_SEPARATOR + "db" + DIR_SEPARATOR + app + DIR_SEPARATOR + "version" + DIR_SEPARATOR + insightId + params + DIR_SEPARATOR + "image.png"; + String encodedParams = Utility.encodeURIComponent(params); + fileLocation = baseFolder + DIR_SEPARATOR + "db" + DIR_SEPARATOR + app + DIR_SEPARATOR + "version" + DIR_SEPARATOR + id + encodedParams + DIR_SEPARATOR + "image.png"; } else { - fileLocation = baseFolder + DIR_SEPARATOR + "db" + DIR_SEPARATOR + app + DIR_SEPARATOR + "version" + DIR_SEPARATOR + insightId + DIR_SEPARATOR + "image.png"; + fileLocation = baseFolder + DIR_SEPARATOR + "db" + DIR_SEPARATOR + app + DIR_SEPARATOR + "version" + DIR_SEPARATOR + id + DIR_SEPARATOR + "image.png"; } File f = new File(fileLocation); if(f.exists()) { return f; } else { // try making the image - ImageCaptureReactor.runImageCapture(feUrl, app, insightId, params); + ImageCaptureReactor.runImageCapture(feUrl, app, id, params); if(f.exists()) { return f; } else { // return stock image - f = SolrUtility.getStockImage(app, insightId); + f = SolrUtility.getStockImage(app, id); return f; } } From 1e72ab664507b8468be0e7ca6fc5ee0c04ae7ae6 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 16 May 2018 22:34:32 +0000 Subject: [PATCH 0045/1906] UPDATE ::: Adding null check for feUrl which is required to create the image git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28040 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: b6686b2b00afbb0aac5e07a49c4851e4fa1854b2 --- src/prerna/semoss/web/services/AppResource.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/prerna/semoss/web/services/AppResource.java b/src/prerna/semoss/web/services/AppResource.java index c6e5631e5..f9e3962d4 100644 --- a/src/prerna/semoss/web/services/AppResource.java +++ b/src/prerna/semoss/web/services/AppResource.java @@ -107,7 +107,9 @@ private File getInsightImageFile(String app, String id, String feUrl, String par return f; } else { // try making the image - ImageCaptureReactor.runImageCapture(feUrl, app, id, params); + if(feUrl != null) { + ImageCaptureReactor.runImageCapture(feUrl, app, id, params); + } if(f.exists()) { return f; } else { From 16f62c0ddaf9a37067227c7ebca1825d6b56f57c Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 18 May 2018 19:46:50 +0000 Subject: [PATCH 0046/1906] UPDATE ::: Fixing compilation error git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28096 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 57d6f85d2cf90d5c8d4f4d497415f27e4ea2f22f --- src/prerna/semoss/web/services/NameServer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prerna/semoss/web/services/NameServer.java b/src/prerna/semoss/web/services/NameServer.java index fbd3ade8c..4ee3db9f5 100644 --- a/src/prerna/semoss/web/services/NameServer.java +++ b/src/prerna/semoss/web/services/NameServer.java @@ -697,7 +697,7 @@ public Response getAllLogicalNamesFromConceptual(MultivaluedMap // parentConceptualName = cleanParentConceptualName; // } // return Response.status(200).entity(WebUtility.getSO(DatabasePkqlService.getAllLogicalNamesFromConceptual(conceptualName, parentConceptualName))).build(); - return WebUtility.getResponse(MasterDatabaseUtility.getAllLogicalNamesFromConceptualRDBMS(conceptualName), 200); + return WebUtility.getResponse(MasterDatabaseUtility.getAllLogicalNamesFromConceptualRDBMS(conceptualName, null), 200); } @GET From 3971458cd39f9ad1ebf8c45f4024979399062a1a Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 21 May 2018 16:23:57 +0000 Subject: [PATCH 0047/1906] UPDATE ::: Consolidate of getting dir separators git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28110 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: aa60c260342a2f1296286c32b6d38bf8a50c35a3 --- src/prerna/upload/DatabaseUploader.java | 6 +++--- src/prerna/upload/ImageUploader.java | 3 --- src/prerna/upload/Uploader.java | 16 ++++++++++++---- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/prerna/upload/DatabaseUploader.java b/src/prerna/upload/DatabaseUploader.java index ebd24d2a8..6de57f6ed 100644 --- a/src/prerna/upload/DatabaseUploader.java +++ b/src/prerna/upload/DatabaseUploader.java @@ -61,7 +61,7 @@ public class DatabaseUploader extends Uploader { // we will control the adding of the engine into local master and solr // such that we dont send a success before those processes are complete boolean autoLoad = false; - + ///////////////////////////////////////////// SET DEFAULT OPTIONS /////////////////////////////////////////////// /* @@ -422,12 +422,12 @@ public Response uploadCsvFileAndPredictMetamodel(@Context HttpServletRequest req // store the file location on server so FE can send that back into actual upload routine String filePath = files[i]; char delimiter = delimiters[i].charAt(0); - String file = filePath.substring(filePath.lastIndexOf("\\") + 1, filePath.lastIndexOf(".")); + String file = filePath.substring(filePath.lastIndexOf(DIR_SEPARATOR) + DIR_SEPARATOR.length(), filePath.lastIndexOf(".")); try { file = file.substring(0, file.length() - 24); //taking out the date added onto the original file name } catch(Exception e) { //just in case that fails, this shouldnt because if its a filename it should have a "." - file = filePath.substring(filePath.lastIndexOf("\\") + 1, filePath.lastIndexOf(".")); + file = filePath.substring(filePath.lastIndexOf(DIR_SEPARATOR) + DIR_SEPARATOR.length(), filePath.lastIndexOf(".")); } // store file path and file name to send to FE diff --git a/src/prerna/upload/ImageUploader.java b/src/prerna/upload/ImageUploader.java index 03ef3a201..c5f4250e8 100644 --- a/src/prerna/upload/ImageUploader.java +++ b/src/prerna/upload/ImageUploader.java @@ -16,9 +16,6 @@ public class ImageUploader extends Uploader { - // get the directory separator - private static final String DIR_SEPARATOR = java.nio.file.FileSystems.getDefault().getSeparator(); - @POST @Path("/appImage") @Produces("application/json") diff --git a/src/prerna/upload/Uploader.java b/src/prerna/upload/Uploader.java index c6b6a6bb0..ed276d34a 100644 --- a/src/prerna/upload/Uploader.java +++ b/src/prerna/upload/Uploader.java @@ -66,6 +66,10 @@ public abstract class Uploader extends HttpServlet { private static final Logger LOGGER = LogManager.getLogger(FileUploader.class); + + // get the directory separator + protected static final String DIR_SEPARATOR = java.nio.file.FileSystems.getDefault().getSeparator(); + public static final String CSV_FILE_KEY = "CSV"; public static final String CSV_HELPER_MESSAGE = "HTML_RESPONSE"; @@ -79,8 +83,12 @@ public abstract class Uploader extends HttpServlet { // such that we dont send a success before those processes are complete boolean autoLoad = false; - public void setFilePath(String filePath){ - this.filePath = filePath; + public void setFilePath(String filePath) { + if(filePath.endsWith(DIR_SEPARATOR)) { + this.filePath = filePath; + } else { + this.filePath = filePath + DIR_SEPARATOR; + } } public void setTempFilePath(String tempFilePath){ @@ -151,12 +159,12 @@ protected Hashtable getInputData(List fileItems) continue; } else { - if(fieldName.equals("file") || fieldName.equals("mapFile") || fieldName.equals("questionFile") || fieldName.equals("propFile")) { + if(fieldName.equals("file") || fieldName.equals("propFile")) { // need to clean the fileName to not have ";" since we split on that in upload data fileName = fileName.replace(";", ""); Date date = new Date(); String modifiedDate = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_SSSS").format(date); - value = filePath + "\\" + fileName.substring(fileName.lastIndexOf("\\") + 1, fileName.lastIndexOf(".")).trim().replace(" ", "_") + modifiedDate + fileName.substring(fileName.lastIndexOf(".")); + value = this.filePath + fileName.substring(fileName.lastIndexOf(DIR_SEPARATOR) + 1, fileName.lastIndexOf(".")).trim().replace(" ", "_") + modifiedDate + fileName.substring(fileName.lastIndexOf(".")); file = new File(value); writeFile(fi, file); LOGGER.info("File item is the actual data. Saved Filename: " + fileName + " to "+ file); From 5f5479ff6692f4a24c32eb14998be653f771733c Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 30 May 2018 12:14:59 +0000 Subject: [PATCH 0048/1906] UPDATE ::: Initial push for switch to use engine id instead of engine name git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28263 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 8292301f1b8d46ccd3a5d361fc2aacc4a571e549 --- .../semoss/web/services/AppResource.java | 30 +++- .../semoss/web/services/NameServer.java | 134 ++++++++++-------- src/prerna/upload/ImageUploader.java | 8 +- .../web/services/util/PixelWebUtility.java | 2 +- 4 files changed, 110 insertions(+), 64 deletions(-) diff --git a/src/prerna/semoss/web/services/AppResource.java b/src/prerna/semoss/web/services/AppResource.java index f9e3962d4..f9f2d94ab 100644 --- a/src/prerna/semoss/web/services/AppResource.java +++ b/src/prerna/semoss/web/services/AppResource.java @@ -23,6 +23,8 @@ import org.apache.commons.io.IOUtils; import org.apache.commons.io.filefilter.WildcardFileFilter; +import prerna.engine.impl.SmssUtilities; +import prerna.nameserver.utility.MasterDatabaseUtility; import prerna.sablecc2.reactor.utils.ImageCaptureReactor; import prerna.solr.SolrUtility; import prerna.util.Constants; @@ -39,7 +41,7 @@ public class AppResource { @GET @Path("/appImage/download") @Produces(MediaType.APPLICATION_OCTET_STREAM) - public Response downloadAppImage(@PathParam("appName") String app) { + public Response downloadAppImage(@Context HttpServletRequest request, @PathParam("appName") String app) { File exportFile = getAppImageFile(app); if(exportFile.exists()) { String exportName = app + "_Image." + FilenameUtils.getExtension(exportFile.getAbsolutePath()); @@ -57,8 +59,18 @@ public Response downloadAppImage(@PathParam("appName") String app) { * @return */ private File getAppImageFile(String app) { + //TODO: account for user here + String appId = null; + List appIds = MasterDatabaseUtility.getEngineIdsForAlias(app); + if(!appIds.isEmpty()) { + appId = appIds.get(0); + } else { + appId = app; + app = null; + } + String baseFolder = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER); - String fileLocation = baseFolder + DIR_SEPARATOR + "db" + DIR_SEPARATOR + app + DIR_SEPARATOR + "version"; + String fileLocation = baseFolder + DIR_SEPARATOR + "db" + DIR_SEPARATOR + SmssUtilities.getUniqueName(app, appId) + DIR_SEPARATOR + "version"; File f = findImageFile(fileLocation); if(f != null) { return f; @@ -94,13 +106,23 @@ public Response downloadInsightImage(@Context HttpServletRequest request, @PathP * @return */ private File getInsightImageFile(String app, String id, String feUrl, String params) { + //TODO: account for user here + String appId = null; + List appIds = MasterDatabaseUtility.getEngineIdsForAlias(app); + if(!appIds.isEmpty()) { + appId = appIds.get(0); + } else { + appId = app; + app = null; + } + String baseFolder = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER); String fileLocation = ""; if(params != null && !params.isEmpty() && !params.equals("undefined")) { String encodedParams = Utility.encodeURIComponent(params); - fileLocation = baseFolder + DIR_SEPARATOR + "db" + DIR_SEPARATOR + app + DIR_SEPARATOR + "version" + DIR_SEPARATOR + id + encodedParams + DIR_SEPARATOR + "image.png"; + fileLocation = baseFolder + DIR_SEPARATOR + "db" + DIR_SEPARATOR + SmssUtilities.getUniqueName(app, appId) + DIR_SEPARATOR + "version" + DIR_SEPARATOR + id + encodedParams + DIR_SEPARATOR + "image.png"; } else { - fileLocation = baseFolder + DIR_SEPARATOR + "db" + DIR_SEPARATOR + app + DIR_SEPARATOR + "version" + DIR_SEPARATOR + id + DIR_SEPARATOR + "image.png"; + fileLocation = baseFolder + DIR_SEPARATOR + "db" + DIR_SEPARATOR + SmssUtilities.getUniqueName(app, appId) + DIR_SEPARATOR + "version" + DIR_SEPARATOR + id + DIR_SEPARATOR + "image.png"; } File f = new File(fileLocation); if(f.exists()) { diff --git a/src/prerna/semoss/web/services/NameServer.java b/src/prerna/semoss/web/services/NameServer.java index 4ee3db9f5..574565a72 100644 --- a/src/prerna/semoss/web/services/NameServer.java +++ b/src/prerna/semoss/web/services/NameServer.java @@ -82,6 +82,7 @@ import com.google.gson.internal.StringMap; import com.google.gson.reflect.TypeToken; +import prerna.auth.AuthProvider; import prerna.auth.User; import prerna.auth.User2; import prerna.auth.UserPermissionsMasterDB; @@ -227,18 +228,24 @@ public StreamingOutput getInsight(@QueryParam("insight") String uniqueId) { return WebUtility.getSO(results); } - // gets a particular insight + /** + * Get the basic information of all engines from solr. + * @param request + * @return all engines. + */ @GET @Path("all") @Produces("application/json") public StreamingOutput printEngines(@Context HttpServletRequest request) { - // would be cool to give this as an HTML - Map>> hashTable = new Hashtable>>(); - // ArrayList enginesList = new ArrayList(); - HttpSession session = request.getSession(); - List> engines = (ArrayList>) session.getAttribute(Constants.ENGINES); - hashTable.put("engines", engines); - return WebUtility.getSO(hashTable); + List> engines = null; + try { +// engines = SolrUtility.getAllEgnines(); + } catch (Exception e1) { + e1.printStackTrace(); + return WebUtility.getSO("Error executing solr query"); + } + + return WebUtility.getSO(engines); } @GET @@ -427,26 +434,27 @@ public StreamingOutput getSearchInsightsResults(MultivaluedMap f String userId = ""; if(securityEnabled) { - HttpSession session = request.getSession(true); - User user = ((User) session.getAttribute(Constants.SESSION_USER)); + HttpSession session = request.getSession(false); + User2 user = ((User2) session.getAttribute("semoss_user")); if(user!= null) { - userId = user.getId(); + userId = user.getAccessToken(AuthProvider.NATIVE.name()).getId(); } HashSet userEngines = permissions.getUserAccessibleEngines(userId); - if(filterData.get("core_engine") != null) { + if(filterData.get(SolrIndexEngine.APP_ID) != null) { filterEngines.addAll(filterData.get("core_engine")); } if(filterEngines.size() > 0) { for(String s : filterEngines) { if(!userEngines.contains(s)) { - filterData.get("core_engine").remove(s); + filterData.get(SolrIndexEngine.APP_ID).remove(s); } } } else { filterEngines.addAll(userEngines); - if(filterEngines.size() > 0) - filterData.put("core_engine", filterEngines); + if(filterEngines.size() > 0) { + filterData.put(SolrIndexEngine.APP_ID, filterEngines); + } } } @@ -535,7 +543,7 @@ public StreamingOutput getFacetInsightsResults(@QueryParam("searchTerm") String logger.info("Searching based on input: " + searchString); List facetList = new ArrayList<>(); - facetList.add(SolrIndexEngine.CORE_ENGINE); + facetList.add(SolrIndexEngine.APP_ID); facetList.add(SolrIndexEngine.LAYOUT); facetList.add(SolrIndexEngine.TAGS); @@ -594,7 +602,7 @@ public StreamingOutput getGroupInsightsResults(MultivaluedMap fo //If security is enabled, remove the engines in the filters that aren't accessible - if none in filters, add all accessible engines to filter list if(Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED))) { - HttpSession session = request.getSession(true); + HttpSession session = request.getSession(false); User user = ((User) session.getAttribute(Constants.SESSION_USER)); String userId = ""; if(user!= null) { @@ -603,19 +611,20 @@ public StreamingOutput getGroupInsightsResults(MultivaluedMap fo HashSet userEngines = permissions.getUserAccessibleEngines(userId); ArrayList filterEngines = new ArrayList(); - if(filterData.get("core_engine") != null) { - filterEngines.addAll(filterData.get("core_engine")); + if(filterData.get(SolrIndexEngine.APP_ID) != null) { + filterEngines.addAll(filterData.get(SolrIndexEngine.APP_ID)); } if(filterEngines.size() > 0) { for(String s : filterEngines) { if(!userEngines.contains(s)) { - filterData.get("core_engine").remove(s); + filterData.get(SolrIndexEngine.APP_ID).remove(s); } } } else { filterEngines.addAll(userEngines); - if(filterEngines.size() > 0) - filterData.put("core_engine", filterEngines); + if(filterEngines.size() > 0) { + filterData.put(SolrIndexEngine.APP_ID, filterEngines); + } } } @@ -712,7 +721,8 @@ public Response getMetamodel(@Context HttpServletRequest request, @QueryParam("e Map ret = new HashMap(); if(Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED))) { - String userId = ((User) request.getSession().getAttribute(Constants.SESSION_USER)).getId(); + User2 user = (User2) request.getSession().getAttribute("semoss_user"); + String userId = user.getAccessToken(AuthProvider.NATIVE.name()).getId(); HashMap> metamodelFilter = new HashMap>(); if(permissions.getMetamodelSeedsForUser(userId).get(engineName) != null) { metamodelFilter = permissions.getMetamodelSeedsForUser(userId).get(engineName); @@ -768,7 +778,7 @@ public Response getCentralContextInsights(MultivaluedMap form, @ queryBuilder.setDefaultSearchField(SolrIndexEngine.INDEX_NAME); List facetList = new ArrayList<>(); - facetList.add(SolrIndexEngine.CORE_ENGINE); + facetList.add(SolrIndexEngine.APP_ID); facetList.add(SolrIndexEngine.LAYOUT); facetList.add(SolrIndexEngine.TAGS); queryBuilder.setFacetField(facetList); @@ -1023,9 +1033,9 @@ public Response downloadFile(@QueryParam("insightId") String insightId, @QueryPa @GET @Path("/appImage") @Produces("image/*") - public Response getAppImage(@QueryParam("app") String app) { + public Response getAppImage(@Context HttpServletRequest request, @QueryParam("app") String app) { AppResource r = new AppResource(); - return r.downloadAppImage(app); + return r.downloadAppImage(request, app); } @GET @@ -1059,15 +1069,33 @@ public Response runPixelSync(MultivaluedMap form, @Context HttpS // there is a jobID status Hash - this can eventually be zookeeper // Then there is a jobID to message if the user has turned on the stdout, then it has a stack of messages // once the job is done, the stack is also cleared + + HttpSession session; + String sessionId; + User2 user2; - HttpSession session = request.getSession(true); - String sessionId = session.getId(); - User user = ((User) session.getAttribute(Constants.SESSION_USER)); - User2 user2 = ((User2) session.getAttribute("semoss_user")); - + boolean securityEnabled = Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED)); + //If security is enabled try to get an existing session. + //Otherwise get a session with the default user. + if(securityEnabled){ + session = request.getSession(false); + if(session != null){ + sessionId = session.getId(); + user2 = ((User2) session.getAttribute("semoss_user")); + } else { + Map errorMap = new HashMap(); + errorMap.put("error", "User session is invalid"); + System.out.println("User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + } else { + session = request.getSession(true); + user2 = ((User2) session.getAttribute("semoss_user")); + sessionId = session.getId(); + } + String jobId = ""; final String tempInsightId = "TempInsightNotStored"; - Map dataReturn = null; String insightId = form.getFirst("insightId"); String expression = form.getFirst("expression"); @@ -1079,8 +1107,10 @@ public Response runPixelSync(MultivaluedMap form, @Context HttpS insightId = tempInsightId; insight = new Insight(); insight.setInsightId(tempInsightId); - } else if(insightId.equals("new")) { // need to make a new insight here + //insight.setUser(user); + } else if (insightId.equals("new")) { // need to make a new insight here insight = new Insight(); + //insight.setUser(user); InsightStore.getInstance().put(insight); insightId = insight.getInsightId(); InsightStore.getInstance().addToSessionHash(sessionId, insightId); @@ -1088,7 +1118,8 @@ public Response runPixelSync(MultivaluedMap form, @Context HttpS // the session id needs to be checked // you better have a valid id... or else... O_O insight = InsightStore.getInstance().get(insightId); - if(insight == null) { + //insight.setUser(user); + if (insight == null) { Map errorMap = new HashMap(); errorMap.put("errorMessage", "Could not find the insight id"); return WebUtility.getResponse(errorMap, 400); @@ -1103,9 +1134,7 @@ public Response runPixelSync(MultivaluedMap form, @Context HttpS // } } synchronized(insight) { - insight.setUser(user); - - // set the other user + // set the user insight.setUser2(user2); JobManager manager = JobManager.getManager(); JobThread jt = null; @@ -1126,24 +1155,6 @@ public Response runPixelSync(MultivaluedMap form, @Context HttpS manager.flushJob(jobId); return Response.status(200).entity(PixelWebUtility.collectPixelData(pixelRunner)).build(); - - // jt.run(); - // dataReturn = jt.getOutput(); - // Vector pixelReturnVector = (Vector)dataReturn.get("pixelReturn"); - // // TODO: need FE to not react based on the size ... - // // but basically want to return an error - // // but dont want to show the implicit Job reactor we are adding - // if(pixelReturnVector.size() > 1) { - // pixelReturnVector.remove(0); - // } else { - // // this is most likely due to an error with compiling the expression being sent - // String newExp = (String) ((Map) pixelReturnVector.get(0)).get("pixelExpression"); - // newExp = newExp.replace(job, ""); - // ((Map) pixelReturnVector.get(0)).put("pixelExpression", newExp); - // } - // dataReturn.put("pixelReturn", pixelReturnVector); - // // i need to kill this job - // manager.flushJob(jobId); } } @@ -1151,9 +1162,16 @@ public Response runPixelSync(MultivaluedMap form, @Context HttpS @Path("runPixelAsync") @Produces("application/json") public Response runPixelAsync(MultivaluedMap form, @Context HttpServletRequest request) { - HttpSession session = request.getSession(true); + boolean securityEnabled = Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED)); + HttpSession session = null; + User2 user2 = null; + if(securityEnabled){ + session = request.getSession(false); + user2 = ((User2) session.getAttribute("semoss_user")); + } else { + session = request.getSession(true); + } String sessionId = session.getId(); - User user = ((User) session.getAttribute(Constants.SESSION_USER)); String jobId = ""; Map dataReturn = new HashMap(); @@ -1192,7 +1210,7 @@ public Response runPixelAsync(MultivaluedMap form, @Context Http if(insight != null) { synchronized(insight) { - insight.setUser(user); + insight.setUser2(user2); JobManager manager = JobManager.getManager(); JobThread jt = manager.makeJob(); jobId = jt.getJobId(); diff --git a/src/prerna/upload/ImageUploader.java b/src/prerna/upload/ImageUploader.java index c5f4250e8..5a2b05bfe 100644 --- a/src/prerna/upload/ImageUploader.java +++ b/src/prerna/upload/ImageUploader.java @@ -14,6 +14,9 @@ import org.apache.commons.fileupload.FileItem; import org.apache.commons.io.filefilter.WildcardFileFilter; +import prerna.engine.impl.SmssUtilities; +import prerna.nameserver.utility.MasterDatabaseUtility; + public class ImageUploader extends Uploader { @POST @@ -36,10 +39,13 @@ public void uploadAppImage(@Context HttpServletRequest request) { } } + //TODO: account for user here + String appId = MasterDatabaseUtility.getEngineIdsForAlias(appName).get(0); + // now that we have the app name // and the image file // we want to write it into the app location - String imageDir = filePath + DIR_SEPARATOR + appName + DIR_SEPARATOR + "version"; + String imageDir = filePath + DIR_SEPARATOR + SmssUtilities.getUniqueName(appName, appId) + DIR_SEPARATOR + "version"; File f = new File(imageDir); if(!f.exists()) { f.mkdirs(); diff --git a/src/prerna/web/services/util/PixelWebUtility.java b/src/prerna/web/services/util/PixelWebUtility.java index ba2e7e1dc..bd3facd65 100644 --- a/src/prerna/web/services/util/PixelWebUtility.java +++ b/src/prerna/web/services/util/PixelWebUtility.java @@ -307,7 +307,7 @@ else if(nounT == PixelDataType.PIXEL_RUNNER) { Insight innerInsight = runner.getInsight(); ps.print("\"output\":{"); ps.print("\"name\":" + gson.toJson(innerInsight.getInsightName())); - ps.print(",\"core_engine\":" + gson.toJson(innerInsight.getEngineName())); + ps.print(",\"core_engine\":" + gson.toJson(innerInsight.getEngineId())); ps.print(",\"core_engine_id\":" + gson.toJson(innerInsight.getRdbmsId())); ps.print(",\"params\":" + gson.toJson(params)); ps.print(",\"additionalPixels\":" + gson.toJson(additionalPixels)); From e6979e2da42ac454008aa067cb173ff2509d4bf8 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 30 May 2018 12:20:11 +0000 Subject: [PATCH 0049/1906] UPDATE ::: Resolving compilation issues git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28265 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 4234bd70b3e5ae977ce692c60c9ed137676312e1 --- .../insights/admin/DBAdminResource.java | 6 +- src/prerna/insights/admin/QuestionAdmin.java | 2 +- .../web/services/AuthorizationResource.java | 446 ++++++++++++++++-- .../web/services/EngineRemoteResource.java | 6 +- .../semoss/web/services/EngineResource.java | 8 +- 5 files changed, 405 insertions(+), 63 deletions(-) diff --git a/src/prerna/insights/admin/DBAdminResource.java b/src/prerna/insights/admin/DBAdminResource.java index f0974e609..f7af4d4ca 100644 --- a/src/prerna/insights/admin/DBAdminResource.java +++ b/src/prerna/insights/admin/DBAdminResource.java @@ -193,7 +193,7 @@ public Object delete(MultivaluedMap form, @Context HttpServletRe InsightAdministrator admin = new InsightAdministrator(engine.getInsightDatabase()); try { admin.dropInsight(questionIds.toArray(new String[questionIds.size()])); - questionIds = SolrIndexEngine.getSolrIdFromInsightEngineId(engine.getEngineName(), questionIds); + questionIds = SolrIndexEngine.getSolrIdFromInsightEngineId(engine.getEngineId(), questionIds); } catch (RuntimeException e) { // reload question xml from file if it errored // otherwise xml gets corrupted @@ -309,7 +309,7 @@ public Object insight(@PathParam("engine") String engineString, @Context HttpSer } private boolean deleteEngine(IEngine coreEngine, HttpServletRequest request) { - String engineName = coreEngine.getEngineName(); + String engineName = coreEngine.getEngineId(); coreEngine.deleteDB(); // remove from session HttpSession session = request.getSession(); @@ -368,7 +368,7 @@ public Response deleteDbCache(MultivaluedMap form, @Context Http String dbName = form.getFirst("engine"); String insightID = form.getFirst("insightID"); String questionName = form.getFirst("questionName"); - Insight in = new Insight(getEngine(dbName, request).getEngineName(), insightID); + Insight in = new Insight(getEngine(dbName, request).getEngineId(), insightID); in.setInsightName(questionName); CacheFactory.getInsightCache(CacheFactory.CACHE_TYPE.DB_INSIGHT_CACHE).deleteInsightCache(in); diff --git a/src/prerna/insights/admin/QuestionAdmin.java b/src/prerna/insights/admin/QuestionAdmin.java index f63d7acf3..db776fcc2 100644 --- a/src/prerna/insights/admin/QuestionAdmin.java +++ b/src/prerna/insights/admin/QuestionAdmin.java @@ -72,7 +72,7 @@ public Response deleteInsight(MultivaluedMap form, @Context Http try { List removeList = new ArrayList(); - removeList.add(coreEngine.getEngineName() + "_" + insightID); + removeList.add(coreEngine.getEngineId() + "_" + insightID); SolrIndexEngine.getInstance().removeInsight(removeList); } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException | SolrServerException | IOException e) { e.printStackTrace(); diff --git a/src/prerna/semoss/web/services/AuthorizationResource.java b/src/prerna/semoss/web/services/AuthorizationResource.java index 44d40addf..bd6c3283d 100644 --- a/src/prerna/semoss/web/services/AuthorizationResource.java +++ b/src/prerna/semoss/web/services/AuthorizationResource.java @@ -32,9 +32,11 @@ import java.util.Arrays; import java.util.HashMap; import java.util.Hashtable; +import java.util.Map; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; @@ -48,8 +50,10 @@ import com.google.gson.Gson; import com.google.gson.internal.StringMap; +import prerna.auth.AuthProvider; import prerna.auth.EngineAccessRequest; import prerna.auth.User; +import prerna.auth.User2; import prerna.auth.UserPermissionsMasterDB; import prerna.auth.EnginePermission; import prerna.util.Constants; @@ -63,6 +67,10 @@ public class AuthorizationResource String output = ""; UserPermissionsMasterDB permissions = new UserPermissionsMasterDB(); + /** + * Check if the security is enabled in the application. + * @return true or false + */ @GET @Produces("application/json") @Path("securityEnabled") @@ -187,13 +195,27 @@ public Response approveEngineAccessRequest(@Context HttpServletRequest request, return WebUtility.getResponse(ret, 200); } + /** + * Get all the grous the user is part of. + * @param request + * @return get all groups the user is part of + */ @GET - @Produces("application/json")//DONE + @Produces("application/json") @Path("getGroups") - public StreamingOutput getGroupsAndMembers(@Context HttpServletRequest request) { - StringMap>> ret = permissions.getGroupsAndMembersForUser(((User) request.getSession().getAttribute(Constants.SESSION_USER)).getId()); + public Response getGroupsAndMembers(@Context HttpServletRequest request) { + HttpSession session = request.getSession(false); + if(session == null){ + Map errorMap = new HashMap(); + errorMap.put("error", "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } - return WebUtility.getSO(ret); + User2 user = (User2) request.getSession().getAttribute("semoss_user"); + String userId = user.getAccessToken(AuthProvider.NATIVE.name()).getId(); + ArrayList> ret = permissions.getGroupsAndMembersForUser(userId); + + return WebUtility.getResponse(ret, 200); } @GET @@ -224,6 +246,123 @@ public StreamingOutput searchForUser(@Context HttpServletRequest request, @Query return WebUtility.getSO(ret); } + /** + * Get databases the user has access to + * @param request + * @return Databases the user has access to + */ + @GET + @Produces("application/json") + @Path("getDatabases") + public Response getDatabases(@Context HttpServletRequest request) { + Hashtable errorRet = new Hashtable(); + ArrayList> ret = new ArrayList<>(); + HttpSession session = request.getSession(false); + if(session == null){ + Map errorMap = new HashMap(); + errorMap.put("error", "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + try{ + User2 user = (User2) request.getSession().getAttribute("semoss_user"); + String userId = user.getAccessToken(AuthProvider.NATIVE.name()).getId(); + ret = permissions.getUserDatabases(userId, false); + return WebUtility.getResponse(ret, 200); + } catch (IllegalArgumentException e){ + e.printStackTrace(); + errorRet.put("error", e.getMessage()); + return WebUtility.getResponse(errorRet, 500); + } catch (Exception e){ + e.printStackTrace(); + errorRet.put("error", "An unexpected error happened. Please try again."); + return WebUtility.getResponse(errorRet, 500); + } + } + + /** + * Get databases the user has access to + * @param request + * @return Databases the user has access to + */ + @GET + @Produces("application/json") + @Path("/admin/getDatabases") + public Response getAdminDatabases(@Context HttpServletRequest request) { + Hashtable errorRet = new Hashtable(); + ArrayList> ret = new ArrayList<>(); + try{ + User2 user = (User2) request.getSession().getAttribute("semoss_user"); + String userId = user.getAccessToken(AuthProvider.NATIVE.name()).getId(); + ret = permissions.getUserDatabases(userId, true); + return WebUtility.getResponse(ret, 200); + } catch (IllegalArgumentException e){ + e.printStackTrace(); + errorRet.put("error", e.getMessage()); + return WebUtility.getResponse(errorRet, 500); + } catch (Exception e){ + e.printStackTrace(); + errorRet.put("error", "An unexpected error happened. Please try again."); + return WebUtility.getResponse(errorRet, 500); + } + } + + /** + * Get groups and user of database + * @param request + * @return Groups and user of a specific database + */ + @POST + @Produces("application/json") + @Path("/admin/getDatabaseUsersAndGroups") + public Response getAdminDatabaseUsersAndGroups(@Context HttpServletRequest request, MultivaluedMap form) { + Hashtable errorRet = new Hashtable(); + StringMap>> ret = new StringMap<>(); + try{ + User2 user = (User2) request.getSession().getAttribute("semoss_user"); + String userId = user.getAccessToken(AuthProvider.NATIVE.name()).getId(); + String engineId = form.getFirst("engineId"); + ret = permissions.getDatabaseUsersAndGroups(userId, engineId, true); + return WebUtility.getResponse(ret, 200); + } catch (IllegalArgumentException e){ + e.printStackTrace(); + errorRet.put("error", e.getMessage()); + return WebUtility.getResponse(errorRet, 500); + } catch (Exception e){ + e.printStackTrace(); + errorRet.put("error", "An unexpected error happened. Please try again."); + return WebUtility.getResponse(errorRet, 500); + } + } + + /** + * Get the groups and users directly associated with + * the database requested that the user has access to. + * @param request + * @return Groups and user of a specific database + */ + @POST + @Produces("application/json") + @Path("getDatabaseUsersAndGroups") + public Response getDatabaseUsersAndGroups(@Context HttpServletRequest request, MultivaluedMap form) { + Hashtable errorRet = new Hashtable(); + StringMap>> ret = new StringMap<>(); + try{ + String engineId = form.getFirst("engineId"); + User2 user = (User2) request.getSession().getAttribute("semoss_user"); + String userId = user.getAccessToken(AuthProvider.NATIVE.name()).getId(); + ret = permissions.getDatabaseUsersAndGroups(userId, engineId, false); + return WebUtility.getResponse(ret, 200); + } catch (IllegalArgumentException e){ + e.printStackTrace(); + errorRet.put("error", e.getMessage()); + return WebUtility.getResponse(errorRet, 500); + } catch (Exception e){ + e.printStackTrace(); + errorRet.put("error", "An unexpected error happened. Please try again."); + return WebUtility.getResponse(errorRet, 500); + } + } + @GET @Produces("application/json") @Path("getAllDatabasesAndPermissions")//DONE @@ -239,13 +378,13 @@ public StreamingOutput getAllDatabasesAndPermissions(@Context HttpServletRequest public Response addNewGroup(@Context HttpServletRequest request, MultivaluedMap form) { Gson gson = new Gson(); ArrayList users = gson.fromJson(form.getFirst("users"), ArrayList.class); - Boolean success = permissions.addGroup(((User) request.getSession().getAttribute(Constants.SESSION_USER)).getId(), form.getFirst("groupName").trim(), users); + User2 user = (User2) request.getSession().getAttribute("semoss_user"); + String userId = user.getAccessToken(AuthProvider.NATIVE.name()).getId(); + Boolean success = permissions.addGroup(userId, form.getFirst("groupName").trim(), users); if(success) { -// return Response.status(200).entity(WebUtility.getSO(success)).build(); return WebUtility.getResponse(success, 200); } else { -// return Response.status(400).entity(WebUtility.getSO(success)).build(); return WebUtility.getResponse(success, 200); } } @@ -254,14 +393,14 @@ public Response addNewGroup(@Context HttpServletRequest request, MultivaluedMap< @Produces("application/json") @Path("removeGroup") public Response removeGroup(@Context HttpServletRequest request, MultivaluedMap form) { - String groupName = form.getFirst("groupName").trim(); - Boolean success = permissions.removeGroup(((User) request.getSession().getAttribute(Constants.SESSION_USER)).getId(), groupName); + String groupId = form.getFirst("groupId").trim(); + User2 user = (User2) request.getSession().getAttribute("semoss_user"); + String userId = user.getAccessToken(AuthProvider.NATIVE.name()).getId(); + Boolean success = permissions.removeGroup(userId, groupId); if(success) { -// return Response.status(200).entity(WebUtility.getSO(success)).build(); return WebUtility.getResponse(success, 200); } else { -// return Response.status(400).entity(WebUtility.getSO(success)).build(); return WebUtility.getResponse(success, 400); } } @@ -272,19 +411,20 @@ public Response removeGroup(@Context HttpServletRequest request, MultivaluedMap< public Response editGroup(@Context HttpServletRequest request, MultivaluedMap form) { Gson gson = new Gson(); - String groupName = form.getFirst("groupName").trim(); + String groupId = form.getFirst("groupId").trim(); ArrayList toAdd = gson.fromJson(form.getFirst("add"), ArrayList.class); ArrayList toRemove = gson.fromJson(form.getFirst("remove"), ArrayList.class); + User2 user = (User2) request.getSession().getAttribute("semoss_user"); + String userId = user.getAccessToken(AuthProvider.NATIVE.name()).getId(); + for(String add : toAdd) { - permissions.addUserToGroup(((User) request.getSession().getAttribute(Constants.SESSION_USER)).getId(), groupName, add); + permissions.addUserToGroup(userId, groupId, add); } for(String remove : toRemove) { - permissions.removeUserFromGroup(((User) request.getSession().getAttribute(Constants.SESSION_USER)).getId(), groupName, remove); + permissions.removeUserFromGroup(userId, groupId, remove); } - -// return Response.status(200).entity(WebUtility.getSO(true)).build(); return WebUtility.getResponse(true, 200); } @@ -293,42 +433,92 @@ public Response editGroup(@Context HttpServletRequest request, MultivaluedMap form) { Gson gson = new Gson(); - String userId = ((User) request.getSession().getAttribute(Constants.SESSION_USER)).getId(); - - String engineName = form.getFirst("databaseName").trim(); - StringMap>> groups = gson.fromJson(form.getFirst("groups"), StringMap.class); - ArrayList> groupsToAdd = groups.get("add"); - ArrayList> groupsToRemove = groups.get("remove"); - - for(StringMap map : groupsToRemove) { - permissions.removeAllPermissionsForGroup(userId, map.get("name"), engineName); - } - - for(StringMap map : groupsToAdd) { - String perm = map.get("permission"); - EnginePermission[] permArray = new EnginePermission[] { EnginePermission.getPermissionByValue(perm) }; - permissions.setPermissionsForGroup(userId, map.get("name"), engineName, permArray); - } - - StringMap>> users = gson.fromJson(form.getFirst("users"), StringMap.class); - ArrayList> usersToAdd = users.get("add"); - ArrayList> usersToRemove = users.get("remove"); - - for(StringMap map : usersToRemove) { - permissions.removeAllPermissionsForUser(userId, engineName, map.get("id")); + Hashtable errorRet = new Hashtable(); + try{ + User2 user = (User2) request.getSession().getAttribute("semoss_user"); + String userId = user.getAccessToken(AuthProvider.NATIVE.name()).getId(); + String engineId = form.getFirst("engineId").trim(); + StringMap>> groups = gson.fromJson(form.getFirst("groups"), StringMap.class); + StringMap>> users = gson.fromJson(form.getFirst("users"), StringMap.class); + permissions.savePermissions(userId, false, engineId, groups, users); + } catch(IllegalArgumentException e){ + errorRet.put("error", e.getMessage()); + return WebUtility.getResponse(errorRet, 400); + } catch(Exception e){ + e.printStackTrace(); + errorRet.put("error", "An unexpected error happened. Please try again."); + return WebUtility.getResponse(errorRet, 500); } - for(StringMap map : usersToAdd) { - String perm = map.get("permission"); - EnginePermission[] permArray = new EnginePermission[] { EnginePermission.getPermissionByValue(perm) }; - permissions.setPermissionsForUser(userId, engineName, map.get("id"), permArray); - } - - -// return Response.status(200).entity(WebUtility.getSO(true)).build(); return WebUtility.getResponse(true, 200); } + @POST + @Produces("application/json") + @Path("isUserGroupAddedValid") + public Response isUserGroupAddedValid(@Context HttpServletRequest request, MultivaluedMap form) { + Gson gson = new Gson(); + try { + User2 user = (User2) request.getSession().getAttribute("semoss_user"); + String userId = user.getAccessToken(AuthProvider.NATIVE.name()).getId(); + String ret = "true"; + + userId = form.getFirst("userIdAdd").trim(); + String groupId = form.getFirst("groupIdAdd").trim(); + String engineId = form.getFirst("engineId").trim(); + + StringMap> groups = gson.fromJson(form.getFirst("groups"), StringMap.class); + ArrayList groupsToAdd = groups.get("add"); + ArrayList groupsToRemove = groups.get("remove"); + + StringMap> users = gson.fromJson(form.getFirst("users"), StringMap.class); + ArrayList usersToAdd = users.get("add"); + ArrayList usersToRemove = users.get("remove"); + + ArrayList groupsFinal = permissions.getAllDbGroupsById(engineId, groupsToAdd, groupsToRemove); + ArrayList usersFinal = permissions.getAllDbUsersById(engineId, usersToAdd, usersToRemove); + + if(!userId.isEmpty()){ + ret = permissions.isUserWithDatabasePermissionAlready(userId, groupsFinal, usersFinal); + } else if(!groupId.isEmpty()){ + ret = permissions.isGroupUsersWithDatabasePermissionAlready(groupId, groupsFinal, usersFinal); + } + + if(ret.equals("true")){ + return WebUtility.getResponse(ret, 200); + } else { + return WebUtility.getResponse(ret, 400); + } + } catch(Exception ex) { + return WebUtility.getResponse("An unexpected error happened. Please try again.", 500); + } + } + + @POST + @Produces("application/json") + @Path("isUserAddedToGroupValid") + public Response isUserAddedToGroupValid(@Context HttpServletRequest request, MultivaluedMap form) { + Gson gson = new Gson(); + try { + User2 user = (User2) request.getSession().getAttribute("semoss_user"); + String userId = user.getAccessToken(AuthProvider.NATIVE.name()).getId(); + String ret = ""; + + String userIdAdd = form.getFirst("userIdAdd").trim(); + String groupId = form.getFirst("groupId").trim(); + + ret += permissions.isUserAddedToGroupValid(userIdAdd, groupId); + + if(ret.equals("true")){ + return WebUtility.getResponse(ret, 200); + } else { + return WebUtility.getResponse(ret, 400); + } + } catch(Exception ex) { + return WebUtility.getResponse("An unexpected error happened. Please try again.", 500); + } + } + @GET @Produces("application/json") @Path("getInsightPermissions") @@ -426,15 +616,22 @@ public Response deleteSeedForUser(@Context HttpServletRequest request, @QueryPar @GET @Path("/admin/isAdminUser") public Response isAdminUser(@Context HttpServletRequest request) { - if(request.getSession().getAttribute(Constants.SESSION_USER) != null) { - User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - if(!user.getId().equals(Constants.ANONYMOUS_USER_ID) && permissions.isUserAdmin(user.getId())) { -// return Response.status(200).entity(WebUtility.getSO(true)).build(); + + HttpSession session = request.getSession(false); + if(session == null){ + Map errorMap = new HashMap(); + errorMap.put("error", "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + + if(session.getAttribute("semoss_user") != null) { + User2 user = (User2) request.getSession().getAttribute("semoss_user"); + String userId = user.getAccessToken(AuthProvider.NATIVE.name()).getId(); + if(!userId.equals(Constants.ANONYMOUS_USER_ID) && permissions.isUserAdmin(userId)) { return WebUtility.getResponse(true, 200); } } -// return Response.status(200).entity(WebUtility.getSO(false)).build(); return WebUtility.getResponse(false, 200); } @@ -495,4 +692,149 @@ public Response endTeamSession(@Context HttpServletRequest request, @QueryParam( // return Response.status(200).entity(WebUtility.getSO(retData)).build(); return WebUtility.getResponse(retData, 200); } + + @GET + @Path("/getAllDbUsers") + @Produces("application/json") + public Response getAllDbUsers(@Context HttpServletRequest request) { + ArrayList> ret = new ArrayList<>(); + Hashtable errorRet = new Hashtable(); + User2 user = (User2) request.getSession().getAttribute("semoss_user"); + String userId = user.getAccessToken(AuthProvider.NATIVE.name()).getId(); + try{ + ret = permissions.getAllDbUsers(userId); + } catch (IllegalArgumentException e){ + e.printStackTrace(); + errorRet.put("error", e.getMessage()); + } catch (Exception e){ + e.printStackTrace(); + errorRet.put("error", "An unexpected error happened. Please try again."); + } + return WebUtility.getResponse(ret, 200); + } + + @POST + @Path("/removeDatabaseAccess") + @Produces("application/json") + public Response removeUserPermissionsbyDbId(@Context HttpServletRequest request, MultivaluedMap form) { + boolean ret = false; + Hashtable errorRet = new Hashtable(); + User2 user = (User2) request.getSession().getAttribute("semoss_user"); + String userId = user.getAccessToken(AuthProvider.NATIVE.name()).getId(); + String engineId = form.getFirst("engineId"); + try{ + ret = permissions.removeUserPermissionsbyDbId(userId, engineId); + } catch (IllegalArgumentException e){ + e.printStackTrace(); + errorRet.put("error", e.getMessage()); + } catch (Exception e){ + e.printStackTrace(); + errorRet.put("error", "An unexpected error happened. Please try again."); + } + return WebUtility.getResponse(ret, 200); + } + + /** + * Edit user properties + * @param request + * @param form + * @return true if the edition was performed + */ + @POST + @Path("/editUser") + @Produces("application/json") + public Response editUser(@Context HttpServletRequest request, MultivaluedMap form) { + boolean ret = false; + Gson gson = new Gson(); + Hashtable errorRet = new Hashtable(); + try{ + User2 user = (User2) request.getSession().getAttribute("semoss_user"); + String userId = user.getAccessToken(AuthProvider.NATIVE.name()).getId(); + StringMap userInfo = gson.fromJson(form.getFirst("user"), StringMap.class); + ret = permissions.editUser(userId, userInfo); + } catch (IllegalArgumentException e){ + e.printStackTrace(); + errorRet.put("error", e.getMessage()); + return WebUtility.getResponse(errorRet, 400); + } catch (Exception e){ + e.printStackTrace(); + errorRet.put("error", "An unexpected error happened. Please try again."); + return WebUtility.getResponse(errorRet, 500); + } + return WebUtility.getResponse(ret, 200); + } + + @POST + @Produces("application/json") + @Path("/admin/savePermissions") + public Response savePermissionsAdmin(@Context HttpServletRequest request, MultivaluedMap form) { + Gson gson = new Gson(); + Hashtable errorRet = new Hashtable(); + + try{ + User2 user = (User2) request.getSession().getAttribute("semoss_user"); + String userId = user.getAccessToken(AuthProvider.NATIVE.name()).getId(); + String engineId = form.getFirst("engineId").trim(); + StringMap>> groups = gson.fromJson(form.getFirst("groups"), StringMap.class); + StringMap>> users = gson.fromJson(form.getFirst("users"), StringMap.class); + permissions.savePermissions(userId, true, engineId, groups, users); + } catch(IllegalArgumentException e){ + errorRet.put("error", e.getMessage()); + return WebUtility.getResponse(errorRet, 400); + } catch(Exception e){ + e.printStackTrace(); + errorRet.put("error", "An unexpected error happened. Please try again."); + return WebUtility.getResponse(errorRet, 500); + } + + return WebUtility.getResponse(true, 200); + } + + @POST + @Produces("application/json") + @Path("setDbVisibility") + public Response setDbVisibility(@Context HttpServletRequest request, MultivaluedMap form) { + Hashtable errorRet = new Hashtable(); + try{ + User2 user = (User2) request.getSession().getAttribute("semoss_user"); + String userId = user.getAccessToken(AuthProvider.NATIVE.name()).getId(); + String engineId = form.getFirst("engineId"); + String visibility = form.getFirst("visibility"); + permissions.setDbVisibility(userId, engineId, visibility); + } catch (IllegalArgumentException e){ + e.printStackTrace(); + errorRet.put("error", e.getMessage()); + return WebUtility.getResponse(errorRet, 400); + } catch (Exception e){ + e.printStackTrace(); + errorRet.put("error", "An unexpected error happened. Please try again."); + return WebUtility.getResponse(errorRet, 500); + } + return WebUtility.getResponse(true, 200); + } + + @POST + @Produces("application/json") + @Path("/admin/deleteUser") + public Response deleteUser(@Context HttpServletRequest request, MultivaluedMap form) { + Hashtable errorRet = new Hashtable(); + try{ + User2 user = (User2) request.getSession().getAttribute("semoss_user"); + String adminId = user.getAccessToken(AuthProvider.NATIVE.name()).getId(); + String userId = form.getFirst("userId"); + permissions.deleteUser(adminId, userId); + if(adminId.equals(userId)){ + request.getSession().invalidate(); + } + } catch (IllegalArgumentException e){ + e.printStackTrace(); + errorRet.put("error", e.getMessage()); + return WebUtility.getResponse(errorRet, 400); + } catch (Exception e){ + e.printStackTrace(); + errorRet.put("error", "An unexpected error happened. Please try again."); + return WebUtility.getResponse(errorRet, 500); + } + return WebUtility.getResponse(true, 200); + } } \ No newline at end of file diff --git a/src/prerna/semoss/web/services/EngineRemoteResource.java b/src/prerna/semoss/web/services/EngineRemoteResource.java index e689d8f15..cae29d9fa 100644 --- a/src/prerna/semoss/web/services/EngineRemoteResource.java +++ b/src/prerna/semoss/web/services/EngineRemoteResource.java @@ -118,7 +118,7 @@ public Object execGraphQuery(@FormParam("query") String query) { sjw.execute(); */ // need someway to get an indirection for now hardcoded - ((IRemoteQueryable)sjw).setRemoteAPI(uriBase + coreEngine.getEngineName()); + ((IRemoteQueryable)sjw).setRemoteAPI(uriBase + coreEngine.getEngineId()); QueryResultHash.getInstance().addObject((SesameConstructWrapper)sjw); return WebUtility.getSO(sjw); @@ -133,7 +133,7 @@ public Object execSelectQuery(@FormParam("query") String query) { AbstractWrapper sjsw = (AbstractWrapper) WrapperManager.getInstance().getSWrapper(coreEngine, query); sjsw.setRemote(true); // need someway to get an indirection for now hardcoded - ((IRemoteQueryable)sjsw).setRemoteAPI(uriBase + coreEngine.getEngineName()); + ((IRemoteQueryable)sjsw).setRemoteAPI(uriBase + coreEngine.getEngineId()); QueryResultHash.getInstance().addObject(sjsw); return WebUtility.getSO(sjsw); @@ -149,7 +149,7 @@ public Object execCheaterQuery(@FormParam("query") String query) { AbstractWrapper sjsw = (AbstractWrapper) WrapperManager.getInstance().getChWrapper(coreEngine, query); sjsw.setRemote(true); // need someway to get an indirection for now hardcoded - ((IRemoteQueryable)sjsw).setRemoteAPI(uriBase + coreEngine.getEngineName()); + ((IRemoteQueryable)sjsw).setRemoteAPI(uriBase + coreEngine.getEngineId()); QueryResultHash.getInstance().addObject(sjsw); return WebUtility.getSO(sjsw); diff --git a/src/prerna/semoss/web/services/EngineResource.java b/src/prerna/semoss/web/services/EngineResource.java index 9efe551ab..fdd00e96c 100644 --- a/src/prerna/semoss/web/services/EngineResource.java +++ b/src/prerna/semoss/web/services/EngineResource.java @@ -166,7 +166,7 @@ public Response getInsightParams(@QueryParam("insight") String insightId) GetPlaysheetParamsReactor paramR = new GetPlaysheetParamsReactor(); paramR.In(); GenRowStruct grs1 = new GenRowStruct(); - grs1.add(new NounMetadata(coreEngine.getEngineName(), PixelDataType.CONST_STRING)); + grs1.add(new NounMetadata(coreEngine.getEngineId(), PixelDataType.CONST_STRING)); paramR.getNounStore().addNoun(ReactorKeysEnum.APP.getKey(), grs1); GenRowStruct grs2 = new GenRowStruct(); grs2.add(new NounMetadata(insightId, PixelDataType.CONST_STRING)); @@ -209,7 +209,7 @@ public Response createOutput(MultivaluedMap form, @Context HttpS dummyIn.setUser(user); playsheetRunReactor.setInsight(dummyIn); GenRowStruct grs1 = new GenRowStruct(); - grs1.add(new NounMetadata(coreEngine.getEngineName(), PixelDataType.CONST_STRING)); + grs1.add(new NounMetadata(coreEngine.getEngineId(), PixelDataType.CONST_STRING)); playsheetRunReactor.getNounStore().addNoun(ReactorKeysEnum.APP.getKey(), grs1); GenRowStruct grs2 = new GenRowStruct(); grs2.add(new NounMetadata(insightId, PixelDataType.CONST_STRING)); @@ -260,7 +260,7 @@ public Response getAuditLogForEngine(MultivaluedMap form, @Conte Gson gson = new Gson(); Map auditInfo = null; try { - auditInfo = FormBuilder.getAuditDataForEngine(this.coreEngine.getEngineName()); + auditInfo = FormBuilder.getAuditDataForEngine(this.coreEngine.getEngineId()); } catch(Exception e) { e.printStackTrace(); return WebUtility.getResponse(gson.toJson(e.getMessage()), 400); @@ -274,7 +274,7 @@ public Response getAuditLogForEngine(MultivaluedMap form, @Conte @Produces("application/zip") public Response exportDatabase(@Context HttpServletRequest request) { HttpSession session = request.getSession(); - String engineName = coreEngine.getEngineName(); + String engineName = coreEngine.getEngineId(); // we want to start exporting the solr documents as well // since we want to move away from using the rdbms insights for that From bf21b8f15d2975b20f39143011ed6d3350db816a Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 30 May 2018 15:22:40 +0000 Subject: [PATCH 0050/1906] BUGFIX ::: Fix for grabbing the insight id when creating the image git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28282 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: b555a97c9abf5ee47ac922bbd7b2d6372c2d62d1 --- src/prerna/semoss/web/services/AppResource.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/prerna/semoss/web/services/AppResource.java b/src/prerna/semoss/web/services/AppResource.java index f9f2d94ab..c471fa883 100644 --- a/src/prerna/semoss/web/services/AppResource.java +++ b/src/prerna/semoss/web/services/AppResource.java @@ -79,7 +79,7 @@ private File getAppImageFile(String app) { f = new File(fileLocation); f.mkdirs(); fileLocation = fileLocation + DIR_SEPARATOR + "image.png"; - TextToGraphic.makeImage(app, fileLocation); + TextToGraphic.makeImage(appId, fileLocation); f = new File(fileLocation); return f; } @@ -130,13 +130,13 @@ private File getInsightImageFile(String app, String id, String feUrl, String par } else { // try making the image if(feUrl != null) { - ImageCaptureReactor.runImageCapture(feUrl, app, id, params); + ImageCaptureReactor.runImageCapture(feUrl, appId, id, params); } if(f.exists()) { return f; } else { // return stock image - f = SolrUtility.getStockImage(app, id); + f = SolrUtility.getStockImage(appId, id); return f; } } From 4d4aafcc60daae028ec9ffe73f8ddcf369e37b29 Mon Sep 17 00:00:00 2001 From: rramirezjimenez Date: Wed, 30 May 2018 16:10:58 +0000 Subject: [PATCH 0051/1906] UPDATE ::: Importing rdbms to include app unique name git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28287 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 8506ec2268f304f8da7262d4a4a877f6fb9ae763 --- src/prerna/upload/DatabaseUploader.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/prerna/upload/DatabaseUploader.java b/src/prerna/upload/DatabaseUploader.java index 6de57f6ed..f16fbb64d 100644 --- a/src/prerna/upload/DatabaseUploader.java +++ b/src/prerna/upload/DatabaseUploader.java @@ -15,6 +15,7 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.UUID; import java.util.Vector; import javax.servlet.http.HttpServletRequest; @@ -35,8 +36,12 @@ import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; +import prerna.auth.AccessToken; +import prerna.auth.AuthProvider; import prerna.auth.User; +import prerna.auth.User2; import prerna.auth.UserPermissionsMasterDB; +import prerna.engine.impl.SmssUtilities; import prerna.engine.impl.solr.SolrEngine; import prerna.nameserver.AddToMasterDB; import prerna.poi.main.CSVPropFileBuilder; @@ -197,6 +202,7 @@ private void setDefaultOptions(ImportOptions options, MultivaluedMap form, @Context Http String dbName = options.getDbName(); String[] fileNames = options.getFileLocations().split(";"); + String dbLocation = SmssUtilities.getUniqueName(Utility.cleanString(dbName, true).toString(), options.getEngineID()); for(int i = 0; i < propFileArr.length; i++) { String fileName = new File(fileNames[i]).getName().replace(".csv", ""); FileUtils.writeStringToFile(new File( DIHelper.getInstance().getProperty("BaseFolder") .concat(File.separator).concat("db").concat(File.separator) - .concat(Utility.cleanString(dbName, true).toString()).concat(File.separator) + .concat(dbLocation).concat(File.separator) .concat(dbName.toString()).concat("_").concat(fileName) .concat("_").concat(dateName).concat("_PROP.prop")), propFileArr[i]); } From 5db899b1284714b0963e8f3a4fec8016433b4812 Mon Sep 17 00:00:00 2001 From: rramirezjimenez Date: Wed, 30 May 2018 16:59:54 +0000 Subject: [PATCH 0052/1906] UPDATE ::: Set engine id for import git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28294 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 6c641e8cfeb33a2580076ff462318641306e03a1 --- src/prerna/upload/DatabaseUploader.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/prerna/upload/DatabaseUploader.java b/src/prerna/upload/DatabaseUploader.java index f16fbb64d..9ec1be034 100644 --- a/src/prerna/upload/DatabaseUploader.java +++ b/src/prerna/upload/DatabaseUploader.java @@ -127,6 +127,7 @@ private void setDefaultOptions(ImportOptions options, Map inputD throw new IOException(errorMessage); } options.setDbName(Utility.makeAlphaNumeric(dbName)); + options.setEngineID(UUID.randomUUID().toString()); // determine the db type String dbType = inputData.get("dataOutputType"); From 44cf4385e6fd76e1fa8a2d3942f98f7e08207eff Mon Sep 17 00:00:00 2001 From: rramirezjimenez Date: Wed, 30 May 2018 18:14:12 +0000 Subject: [PATCH 0053/1906] UPDATE ::: Set engine ID for upload git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28302 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: d586f20bc4ea83904f2dbf4e8b1da82f8484a7ef --- src/prerna/upload/DatabaseUploader.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/prerna/upload/DatabaseUploader.java b/src/prerna/upload/DatabaseUploader.java index 9ec1be034..f301de707 100644 --- a/src/prerna/upload/DatabaseUploader.java +++ b/src/prerna/upload/DatabaseUploader.java @@ -36,10 +36,7 @@ import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; -import prerna.auth.AccessToken; -import prerna.auth.AuthProvider; import prerna.auth.User; -import prerna.auth.User2; import prerna.auth.UserPermissionsMasterDB; import prerna.engine.impl.SmssUtilities; import prerna.engine.impl.solr.SolrEngine; @@ -1340,12 +1337,14 @@ public Response loadSolrEngine(@Context HttpServletRequest request, MultivaluedM String solrURL = form.getFirst("solrURL"); String coreName = form.getFirst("coreName"); boolean isValid = SolrEngine.ping(solrURL, coreName); - String dbName = form.getFirst("dbName"); + String appName = form.getFirst("dbName"); + String appID = UUID.randomUUID().toString(); + if(isValid) { - dbName = Utility.makeAlphaNumeric(dbName); + appName = Utility.makeAlphaNumeric(appName); SolrEngineConnector connector = new SolrEngineConnector(); try { - connector.processExistingSolrConnection(dbName, solrURL, coreName); + connector.processExistingSolrConnection(appName, appID, solrURL, coreName ); } catch (IOException e) { e.printStackTrace(); Map errorMap = new HashMap(); @@ -1442,7 +1441,9 @@ public Response connectExistingRDBMS(@Context HttpServletRequest request, Multiv return Response.status(400).entity(gson.toJson(errorHash)).build(); } } - + String appID = UUID.randomUUID().toString(); + importOptions.setEngineID(appID); + boolean success = true; try { importer.runProcessor(importOptions); From 3c9cc96a3ce89d6235aa603b971619c93465f74d Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 30 May 2018 18:45:10 +0000 Subject: [PATCH 0054/1906] BUGFIX ::: Fixing error with using app id for the auto app image git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28304 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 4303b0b4dff66bd0c889f63d9c6f38f989f66fbf --- .../semoss/web/services/AppResource.java | 33 ++++++++----------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/src/prerna/semoss/web/services/AppResource.java b/src/prerna/semoss/web/services/AppResource.java index c471fa883..1d46b1c3b 100644 --- a/src/prerna/semoss/web/services/AppResource.java +++ b/src/prerna/semoss/web/services/AppResource.java @@ -7,6 +7,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Properties; import java.util.Vector; import javax.servlet.http.HttpServletRequest; @@ -59,15 +60,10 @@ public Response downloadAppImage(@Context HttpServletRequest request, @PathParam * @return */ private File getAppImageFile(String app) { - //TODO: account for user here - String appId = null; - List appIds = MasterDatabaseUtility.getEngineIdsForAlias(app); - if(!appIds.isEmpty()) { - appId = appIds.get(0); - } else { - appId = app; - app = null; - } + String appId = MasterDatabaseUtility.testEngineIdIfAlias(app); + String propFileLoc = DIHelper.getInstance().getProperty(appId + "_" + Constants.STORE); + Properties prop = Utility.loadProperties(propFileLoc); + app = prop.getProperty(Constants.ENGINE_ALIAS); String baseFolder = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER); String fileLocation = baseFolder + DIR_SEPARATOR + "db" + DIR_SEPARATOR + SmssUtilities.getUniqueName(app, appId) + DIR_SEPARATOR + "version"; @@ -79,7 +75,11 @@ private File getAppImageFile(String app) { f = new File(fileLocation); f.mkdirs(); fileLocation = fileLocation + DIR_SEPARATOR + "image.png"; - TextToGraphic.makeImage(appId, fileLocation); + if(app != null) { + TextToGraphic.makeImage(app, fileLocation); + } else { + TextToGraphic.makeImage(appId, fileLocation); + } f = new File(fileLocation); return f; } @@ -106,15 +106,10 @@ public Response downloadInsightImage(@Context HttpServletRequest request, @PathP * @return */ private File getInsightImageFile(String app, String id, String feUrl, String params) { - //TODO: account for user here - String appId = null; - List appIds = MasterDatabaseUtility.getEngineIdsForAlias(app); - if(!appIds.isEmpty()) { - appId = appIds.get(0); - } else { - appId = app; - app = null; - } + String appId = MasterDatabaseUtility.testEngineIdIfAlias(app); + String propFileLoc = DIHelper.getInstance().getProperty(appId + "_" + Constants.STORE); + Properties prop = Utility.loadProperties(propFileLoc); + app = prop.getProperty(Constants.ENGINE_ALIAS); String baseFolder = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER); String fileLocation = ""; From 9484b92e85f66af7b8970a8c71ee20b8ab13ce94 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 30 May 2018 19:00:49 +0000 Subject: [PATCH 0055/1906] BUGFIX ::: Fixing error with exporting app git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28309 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 580e16d63e5e8f5ad7837bfbec5b478570887471 --- .../semoss/web/services/EngineResource.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/prerna/semoss/web/services/EngineResource.java b/src/prerna/semoss/web/services/EngineResource.java index fdd00e96c..8e3957b09 100644 --- a/src/prerna/semoss/web/services/EngineResource.java +++ b/src/prerna/semoss/web/services/EngineResource.java @@ -34,7 +34,6 @@ import java.util.Vector; import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import javax.ws.rs.GET; import javax.ws.rs.POST; @@ -274,22 +273,23 @@ public Response getAuditLogForEngine(MultivaluedMap form, @Conte @Produces("application/zip") public Response exportDatabase(@Context HttpServletRequest request) { HttpSession session = request.getSession(); - String engineName = coreEngine.getEngineId(); - + String engineId = coreEngine.getEngineId(); + String engineName = coreEngine.getEngineName(); + // we want to start exporting the solr documents as well // since we want to move away from using the rdbms insights for that DBAdminResource dbAdmin = new DBAdminResource(); MultivaluedMap form = new MultivaluedHashMap(); - form.putSingle("engineName", engineName); + form.putSingle("engineName", engineId); dbAdmin.exportDbSolrInfo(form , request); // close the engine so we can export it - session.removeAttribute(engineName); - DIHelper.getInstance().removeLocalProperty(engineName); + session.removeAttribute(engineId); + DIHelper.getInstance().removeLocalProperty(engineId); coreEngine.closeDB(); - LOGGER.info("Attending to export engine = " + engineName); - File zip = ZipDatabase.zipEngine(engineName); + LOGGER.info("Attending to export engine = " + engineId); + File zip = ZipDatabase.zipEngine(engineId, engineName); Response resp = Response.ok(zip) .header("x-filename", zip.getName()) From db7cc56c672a8abacd23ae10f085077a55ae8b74 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 30 May 2018 19:53:41 +0000 Subject: [PATCH 0056/1906] BUGFIX ::: Sending app name as well in return for facet search git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28312 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 919272b085dc88bbd994871216473095b546e772 --- src/prerna/semoss/web/services/NameServer.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/prerna/semoss/web/services/NameServer.java b/src/prerna/semoss/web/services/NameServer.java index 574565a72..74d48421b 100644 --- a/src/prerna/semoss/web/services/NameServer.java +++ b/src/prerna/semoss/web/services/NameServer.java @@ -544,6 +544,7 @@ public StreamingOutput getFacetInsightsResults(@QueryParam("searchTerm") String List facetList = new ArrayList<>(); facetList.add(SolrIndexEngine.APP_ID); + facetList.add(SolrIndexEngine.APP_NAME); facetList.add(SolrIndexEngine.LAYOUT); facetList.add(SolrIndexEngine.TAGS); From f0ccd29e42fbe830b5dab1d3a593c102cdfffe7f Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 30 May 2018 22:11:05 +0000 Subject: [PATCH 0057/1906] UPDATE ::: Shifting from sending engine name to engine id for connected concepts + properties git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28321 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 85d615713861b07be0c4679764671601b4ef8778 --- src/prerna/semoss/web/services/NameServer.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/prerna/semoss/web/services/NameServer.java b/src/prerna/semoss/web/services/NameServer.java index 74d48421b..b89242cd9 100644 --- a/src/prerna/semoss/web/services/NameServer.java +++ b/src/prerna/semoss/web/services/NameServer.java @@ -738,13 +738,6 @@ public Response getMetamodel(@Context HttpServletRequest request, @QueryParam("e return WebUtility.getResponse(ret, 200); } - @POST - @Path("central/context/getAllConcepts") - @Produces("application/json") - public Response getAllConceptsFromEngines(@Context HttpServletRequest request) { - return Response.status(200).entity(WebUtility.getSO(MasterDatabaseUtility.getAllConceptsFromEnginesRDBMS())).build(); - } - // get all insights related to a specific uri // preferably we would also pass vert store and edge store... the more // context the better. Don't have any of that for now though. From f14c8cd0c8cdd9e96828179785854fd3147980a7 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 30 May 2018 23:13:02 +0000 Subject: [PATCH 0058/1906] BUGFIX ::: Fixing errors with capturing the CAC user git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28326 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 742dc9d214227b9688eb11dba3f44f75012ed552 --- src/prerna/web/conf/CACFilter.java | 69 +++++++++++++++++++----------- 1 file changed, 45 insertions(+), 24 deletions(-) diff --git a/src/prerna/web/conf/CACFilter.java b/src/prerna/web/conf/CACFilter.java index a83e321bd..be5d15a57 100644 --- a/src/prerna/web/conf/CACFilter.java +++ b/src/prerna/web/conf/CACFilter.java @@ -13,6 +13,7 @@ import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import prerna.auth.AccessToken; @@ -24,40 +25,60 @@ public class CACFilter implements Filter { @Override public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { X509Certificate[] certs = (X509Certificate[]) arg0.getAttribute("javax.servlet.request.X509Certificate"); - HttpSession session = ((HttpServletRequest)arg0).getSession(false); + HttpSession session = ((HttpServletRequest)arg0).getSession(true); - if(session != null && certs != null) { + if(certs != null) { User2 user = (User2) session.getAttribute("semoss_user"); if(user == null) { user = new User2(); - } - - AccessToken token = new AccessToken(); - for(int i = 0; i < certs.length; i++) { - X509Certificate cert = certs[i]; + AccessToken token = new AccessToken(); + token.setProvider(AuthProvider.CAC.toString()); + for(int i = 0; i < certs.length; i++) { + X509Certificate cert = certs[i]; - token.setToken_type(AuthProvider.CAC.toString()); - token.setProvider(cert.getIssuerDN().getName()); - token.setExpires_in((int) cert.getNotAfter().getTime()); - - String fullName = cert.getSubjectX500Principal().getName(); - LdapName ldapDN; - try { - ldapDN = new LdapName(fullName); - for(Rdn rdn: ldapDN.getRdns()) { - if(rdn.getType().equals("CN")) { - token.setName(rdn.getValue().toString()); + String fullName = cert.getSubjectX500Principal().getName(); + LdapName ldapDN; + try { + ldapDN = new LdapName(fullName); + for(Rdn rdn: ldapDN.getRdns()) { + if(rdn.getType().equals("CN")) { + String value = rdn.getValue().toString(); + String[] split = value.split("\\."); + if(split.length == 3 || split.length == 4) { + // no idea if middle name is always there or not + // just gonna validate the cac has length 10 + String cacId = split[split.length-1]; + if(cacId.length() >= 10) { + // valid CAC!!! + token.setName(value); + // now set the other properties + token.setToken_type(cert.getIssuerDN().getName()); + token.setExpires_in((int) cert.getNotAfter().getTime()); + } else { + continue; + } + } else { + continue; + } + } } + } catch (InvalidNameException e) { + token.setName(fullName); + e.printStackTrace(); } - } catch (InvalidNameException e) { - token.setName(fullName); - e.printStackTrace(); + } + + if(token.getName() != null) { + user.setAccessToken(token); + session.setAttribute("semoss_user", user); } } - - user.setAccessToken(token); - session.setAttribute("semoss-user", user); + } else { + //TOOD: figure out redirect +// HttpServletResponse httpResponse = (HttpServletResponse) arg1; +// httpResponse.sendRedirect( ((HttpServletRequest)arg0).getHeader("Referer") + "TestRedirect/test.html"); +// return; } arg2.doFilter(arg0, arg1); From ad9b122c8ac9e8944e6bb473da19d7a2fbd7011e Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 31 May 2018 12:39:30 +0000 Subject: [PATCH 0059/1906] UPDATE ::: Fixing location of check for valid CAC git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28327 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 8c0c048d81f0454a8c6f1caba2cbd39b31d3909b --- src/prerna/web/conf/CACFilter.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/prerna/web/conf/CACFilter.java b/src/prerna/web/conf/CACFilter.java index be5d15a57..178edfc28 100644 --- a/src/prerna/web/conf/CACFilter.java +++ b/src/prerna/web/conf/CACFilter.java @@ -74,11 +74,13 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 session.setAttribute("semoss_user", user); } } - } else { + } + + if(session.getAttribute("semoss_user") == null) { //TOOD: figure out redirect -// HttpServletResponse httpResponse = (HttpServletResponse) arg1; -// httpResponse.sendRedirect( ((HttpServletRequest)arg0).getHeader("Referer") + "TestRedirect/test.html"); -// return; + HttpServletResponse httpResponse = (HttpServletResponse) arg1; + httpResponse.sendRedirect( ((HttpServletRequest)arg0).getHeader("Referer") + "TestRedirect/test.html"); + return; } arg2.doFilter(arg0, arg1); From 63d18c8906e44e75a108e78e405636a4be01027d Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 31 May 2018 14:33:14 +0000 Subject: [PATCH 0060/1906] BUGFIX ::: Fixing playsheets to work again git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28333 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 32d5f1f2962f00cdc76c3e998284e0486350302e --- .../semoss/web/services/NameServer.java | 33 +++++++++++-------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/src/prerna/semoss/web/services/NameServer.java b/src/prerna/semoss/web/services/NameServer.java index b89242cd9..9aca1cc61 100644 --- a/src/prerna/semoss/web/services/NameServer.java +++ b/src/prerna/semoss/web/services/NameServer.java @@ -126,8 +126,7 @@ public class NameServer { // gets the engine resource necessary for all engine calls @Path("e-{engine}") - public Object getLocalDatabase(@PathParam("engine") String db, @QueryParam("api") String api, - @Context HttpServletRequest request) throws IOException { + public Object getLocalDatabase(@Context HttpServletRequest request, @PathParam("engine") String db, @QueryParam("api") String api) throws IOException { // check if api has been passed // if yes: // check if remote engine has already been started and stored in context @@ -139,14 +138,16 @@ public Object getLocalDatabase(@PathParam("engine") String db, @QueryParam("api" // otherwise grab local engine System.out.println(" Getting DB... " + db); HttpSession session = request.getSession(); - if(api != null && api.equalsIgnoreCase("undefined")) // why do we send this shit ? + if(api != null && api.equalsIgnoreCase("undefined")) { api = null; + } IEngine engine = null; - if (api != null) { + if(api != null) { String remoteEngineKey = api + ":" + db; engine = (IEngine) session.getAttribute(remoteEngineKey); - if (engine == null && session.getAttribute(db) instanceof IEngine) + if (engine == null && session.getAttribute(db) instanceof IEngine) { engine = (IEngine) session.getAttribute(db); + } if (engine == null && !api.equalsIgnoreCase("null")) { // this is a legit API addEngine(request, api, db); engine = (IEngine) session.getAttribute(remoteEngineKey); @@ -155,27 +156,31 @@ else if(engine == null){ // this is when the api is null.. need to understand ho engine = loadEngine(db); session.setAttribute(remoteEngineKey, engine); } - } - else - { + } else { String remoteEngineKey = db; - if(session.getAttribute(remoteEngineKey) instanceof IEngine) + if(session.getAttribute(remoteEngineKey) instanceof IEngine) { engine = (IEngine) session.getAttribute(remoteEngineKey); - else - { + } else { engine = loadEngine(db); session.setAttribute(remoteEngineKey, engine); } } - if (engine == null) + // error at the end + if(engine == null) { throw new IOException("The engine " + db + " at " + api + " cannot be found"); + } EngineResource res = new EngineResource(); res.setEngine(engine); return res; } - private IEngine loadEngine(String db){ - return Utility.getEngine(db); + private IEngine loadEngine(String engineId) { + try { + engineId = MasterDatabaseUtility.testEngineIdIfAlias(engineId); + } catch(Exception e) { + return null; + } + return Utility.getEngine(engineId); } @Path("s-{engine}") From 720576b5c26fad16f0b63f423851a90828a4a057 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 1 Jun 2018 14:30:01 +0000 Subject: [PATCH 0061/1906] BUGFIX ::: Removing ids improperly on database uplaoder git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28385 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 3f1dd11ef2efb2a03716b237c66fd49a5dbd2e17 --- src/prerna/upload/DatabaseUploader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prerna/upload/DatabaseUploader.java b/src/prerna/upload/DatabaseUploader.java index f301de707..349bdcc68 100644 --- a/src/prerna/upload/DatabaseUploader.java +++ b/src/prerna/upload/DatabaseUploader.java @@ -199,7 +199,7 @@ private void setDefaultOptions(ImportOptions options, MultivaluedMap Date: Fri, 1 Jun 2018 17:51:56 +0000 Subject: [PATCH 0062/1906] UPDATE ::: Linking Semoss and Monolith in pom.xml so that Monolith can be built using mvn clean install. Must run mvn clean install on Semoss before Monolith (will add Semoss into local .m2, which is referenced in Monolith's pom.xml). Can now use mvn dependency:analyze to see unused jars. git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28401 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: d3bb81df360bc6ebacaa69ad48335d1c228e6750 --- pom.xml | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 495f501bf..8ce53f7c5 100644 --- a/pom.xml +++ b/pom.xml @@ -1,8 +1,8 @@ 4.0.0 - com.semoss - Monolith + org.semoss + monolith 0.0.1-SNAPSHOT war Monolith @@ -27,6 +27,10 @@ true + + maven-dependency-plugin + 2.10 + @@ -93,6 +97,11 @@ + + org.semoss + semoss + 0.0.1-SNAPSHOT + jdk.tools jdk.tools From 44ed623a6b5117590cd653c29712a6b2c4fa7133 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 4 Jun 2018 14:14:48 +0000 Subject: [PATCH 0063/1906] UPDATE ::: Pushing update to metamodel creator to return format UPDATE ::: Pushing CACFilter to only store id git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28418 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: e1516543bd04fd8250e128e6cd653a52113a71cd --- src/prerna/upload/DatabaseUploader.java | 2 +- src/prerna/web/conf/CACFilter.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/prerna/upload/DatabaseUploader.java b/src/prerna/upload/DatabaseUploader.java index 349bdcc68..c4ff47db0 100644 --- a/src/prerna/upload/DatabaseUploader.java +++ b/src/prerna/upload/DatabaseUploader.java @@ -461,7 +461,6 @@ public Response uploadCsvFileAndPredictMetamodel(@Context HttpServletRequest req Map>> metaModel = predictor.getMetaModelData(); fileMetaModelData.putAll(metaModel); } - else { // user is creating their own predictor = new MetaModelCreator(helper, null); @@ -475,6 +474,7 @@ public Response uploadCsvFileAndPredictMetamodel(@Context HttpServletRequest req fileMetaModelData.put("startCount", start); fileMetaModelData.put("endCount", end); fileMetaModelData.put("dataTypes", predictor.getDataTypeMap()); + fileMetaModelData.put("additionalDataTypes", predictor.getAdditionalDataTypeMap()); fileMetaModelData.put("additionalInfo", additionalInfo); // store auto modified header names fileMetaModelData.put("headerModifications", helper.getChangedHeaders()); diff --git a/src/prerna/web/conf/CACFilter.java b/src/prerna/web/conf/CACFilter.java index 178edfc28..ecabd4825 100644 --- a/src/prerna/web/conf/CACFilter.java +++ b/src/prerna/web/conf/CACFilter.java @@ -51,7 +51,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 String cacId = split[split.length-1]; if(cacId.length() >= 10) { // valid CAC!!! - token.setName(value); + token.setName(cacId); // now set the other properties token.setToken_type(cert.getIssuerDN().getName()); token.setExpires_in((int) cert.getNotAfter().getTime()); From 6f5c21ccf6f9730bdcb172df6afa17f5e8aea138 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 4 Jun 2018 16:45:00 +0000 Subject: [PATCH 0064/1906] UPDATE ::: Removing annoying println git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28427 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: ffc5b805cb0966f2da3cd28404ebccc3c872f7bf --- src/prerna/web/services/util/PixelWebUtility.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prerna/web/services/util/PixelWebUtility.java b/src/prerna/web/services/util/PixelWebUtility.java index bd3facd65..b5bd6038a 100644 --- a/src/prerna/web/services/util/PixelWebUtility.java +++ b/src/prerna/web/services/util/PixelWebUtility.java @@ -74,7 +74,7 @@ private static void processPixelRunner(PrintStream ps, Gson gson, PixelRunner ru ps.flush(); // now flush array of pixel returns - ps.println("\"pixelReturn\":["); + ps.print("\"pixelReturn\":["); int size = pixelStrings.size(); // THIS IS BECAUSE WE APPEND THE JOB PIXEL From 9b4043f7c43d8ed6ed515124bf66f920451284dc Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 4 Jun 2018 17:06:50 +0000 Subject: [PATCH 0065/1906] UPDATE ::: Removing dead code that is no longer used git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28434 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 14802e9cf11c157e90695ef41b991afdca751b75 --- .../semoss/web/services/NameServer.java | 12 -- src/prerna/upload/FileUploader.java | 107 ---------------- src/prerna/upload/Uploader.java | 114 +----------------- 3 files changed, 1 insertion(+), 232 deletions(-) delete mode 100644 src/prerna/upload/FileUploader.java diff --git a/src/prerna/semoss/web/services/NameServer.java b/src/prerna/semoss/web/services/NameServer.java index 9aca1cc61..c20778368 100644 --- a/src/prerna/semoss/web/services/NameServer.java +++ b/src/prerna/semoss/web/services/NameServer.java @@ -100,7 +100,6 @@ import prerna.solr.SolrIndexEngine.SOLR_PATHS; import prerna.solr.SolrIndexEngineQueryBuilder; import prerna.upload.DatabaseUploader; -import prerna.upload.FileUploader; import prerna.upload.ImageUploader; import prerna.upload.Uploader; import prerna.util.Constants; @@ -343,17 +342,6 @@ public Uploader uploadDatabase(@Context HttpServletRequest request) { return upload; } - @Path("/uploadFile") - public Uploader uploadFile(@Context HttpServletRequest request) { - Uploader upload = new FileUploader(); - String filePath = DIHelper.getInstance().getProperty(Constants.INSIGHT_CACHE_DIR) + "\\" + DIHelper.getInstance().getProperty(Constants.CSV_INSIGHT_CACHE_FOLDER); - upload.setFilePath(filePath); - String tempFilePath = context.getInitParameter("temp-file-upload"); - upload.setTempFilePath(tempFilePath); - upload.setSecurityEnabled(Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED))); - return upload; - } - @Path("/uploadImage") public Uploader uploadImage(@Context HttpServletRequest request) { Uploader upload = new ImageUploader(); diff --git a/src/prerna/upload/FileUploader.java b/src/prerna/upload/FileUploader.java deleted file mode 100644 index 84b27fca1..000000000 --- a/src/prerna/upload/FileUploader.java +++ /dev/null @@ -1,107 +0,0 @@ -package prerna.upload; - -import java.io.File; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.HashMap; -import java.util.Hashtable; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.Response; - -import org.apache.commons.fileupload.FileItem; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; - -import prerna.web.services.util.WebUtility; - -public class FileUploader extends Uploader { - - private static final Logger LOGGER = LogManager.getLogger(FileUploader.class); - /* - * Moving a file onto the BE cannot be performed through PKQL - * Thus, we still expose "drag and drop" of a file through a rest call - * However, this is only used to push the file to the BE server, the actual - * processing of the file to create/add to a data frame occurs through PKQL - */ - - @POST - @Path("determineDataTypesForFile") - public Response determineDataTypesForFile(@Context HttpServletRequest request) { - try { - List fileItems = processRequest(request); - // collect all of the data input on the form - Hashtable inputData = getInputData(fileItems); - Map retObj = generateDataTypes(inputData); - return WebUtility.getResponse(retObj, 200); - } catch(Exception e) { - e.printStackTrace(); - HashMap errorMap = new HashMap(); - errorMap.put("errorMessage", "Error processing new data"); - return WebUtility.getResponse(errorMap, 400); - } - } - - @Override - /** - * Extract the data to generate the file being passed from the user to the BE server - */ - protected Hashtable getInputData(List fileItems) - { - // Process the uploaded file items - Iterator iteratorFileItems = fileItems.iterator(); - - // collect all of the data input on the form - Hashtable inputData = new Hashtable(); - File file; - - while(iteratorFileItems.hasNext()) - { - FileItem fi = (FileItem) iteratorFileItems.next(); - // Get the uploaded file parameters - String fieldName = fi.getFieldName(); - String fileName = fi.getName(); - String value = fi.getString(); - if (!fi.isFormField()) { - if(fileName.equals("")) { - continue; - } - else { - if(fieldName.equals("file")) { - // need to clean the fileName to not have ";" since we split on that in upload data - fileName = fileName.replace(";", ""); - Date date = new Date(); - String modifiedDate = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_SSSS").format(date); - value = filePath + "\\\\" + fileName.substring(fileName.lastIndexOf("\\") + 1, fileName.lastIndexOf(".")).replace(" ", "") + modifiedDate + fileName.substring(fileName.lastIndexOf(".")); - file = new File(value); - writeFile(fi, file); - LOGGER.info("Saved Filename: " + fileName + " to "+ file); - } - } - } else if(fieldName.equals("file")) { // its a file, but not in a form - System.err.println("Writing input string into file..."); - Date date = new Date(); - String modifiedDate = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_SSSS").format(date); - value = filePath + "\\\\FileString_" + modifiedDate; - file = new File(value); - writeFile(fi, file); - LOGGER.info( "Created new file..."); - } - //need to handle multiple files getting selected for upload - if(inputData.get(fieldName) != null) - { - value = inputData.get(fieldName) + ";" + value; - } - inputData.put(fieldName, value); - fi.delete(); - } - - return inputData; - } -} diff --git a/src/prerna/upload/Uploader.java b/src/prerna/upload/Uploader.java index ed276d34a..196cfafde 100644 --- a/src/prerna/upload/Uploader.java +++ b/src/prerna/upload/Uploader.java @@ -31,12 +31,9 @@ import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; -import java.util.HashMap; import java.util.Hashtable; import java.util.Iterator; -import java.util.LinkedHashMap; import java.util.List; -import java.util.Map; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; @@ -49,15 +46,9 @@ import org.apache.log4j.LogManager; import org.apache.log4j.Logger; -import prerna.cache.FileStore; import prerna.cache.ICache; import prerna.poi.main.HeadersException; -import prerna.poi.main.helper.AmazonApiHelper; import prerna.poi.main.helper.CSVFileHelper; -import prerna.poi.main.helper.ImportApiHelper; -import prerna.poi.main.helper.WebAPIHelper; -import prerna.poi.main.helper.XLFileHelper; -import prerna.util.Utility; /** * Servlet implementation class Uploader @@ -65,7 +56,7 @@ @SuppressWarnings("serial") public abstract class Uploader extends HttpServlet { - private static final Logger LOGGER = LogManager.getLogger(FileUploader.class); + private static final Logger LOGGER = LogManager.getLogger(Uploader.class); // get the directory separator protected static final String DIR_SEPARATOR = java.nio.file.FileSystems.getDefault().getSeparator(); @@ -205,107 +196,4 @@ public boolean checkHeaders(String[] files) throws IOException { return true; } - - /** - * - * @param inputData - * @return - * @throws IOException - */ - protected static Map generateDataTypes(Map inputData) throws IOException { - Map retObj = new HashMap(); - - Map> headerTypeMap = new Hashtable>(); - - boolean webExtract = (inputData.get("file") == null); - String keyvalue = ""; - - if(webExtract){//Provision for extracted data via import.io - WebAPIHelper helper = null; - if(inputData.get("api") != null){ - keyvalue = inputData.get("api"); - helper = new ImportApiHelper(); - }else if(inputData.get("itemSearch") != null){ - keyvalue = inputData.get("itemSearch"); - helper = new AmazonApiHelper(); - ((AmazonApiHelper) helper).setOperationType("ItemSearch"); - }else if(inputData.get("itemLookup") != null){ - keyvalue = inputData.get("itemLookup"); - helper = new AmazonApiHelper(); - ((AmazonApiHelper) helper).setOperationType("ItemLookup"); - } - - helper.setApiParam(keyvalue); - helper.parse(); - - - String [] headers = helper.getHeaders(); - String [] types = helper.predictTypes(); - - Map headerTypes = new LinkedHashMap(); - for(int j = 0; j < headers.length; j++) { - headerTypes.put(headers[j], Utility.getCleanDataType(types[j])); - } - headerTypeMap.put(CSV_FILE_KEY, headerTypes); - - } else { - - String fileLoc = inputData.get("file"); - String uniqueStorageId = FileStore.getInstance().put(fileLoc); - retObj.put("uniqueFileKey", uniqueStorageId); - if(fileLoc.endsWith(".xlsx") || fileLoc.endsWith(".xlsm")) { - XLFileHelper helper = new XLFileHelper(); - helper.parse(fileLoc); - - String[] sheets = helper.getTables(); - for(int i = 0; i < sheets.length; i++) - { - String sheetName = sheets[i]; - String[] types = helper.predictRowTypes(sheetName); - String[] headers = helper.getHeaders(sheetName); - - String [] cleanHeaders = new String[headers.length]; - for(int x = 0; x < headers.length; x++) { - cleanHeaders[i] = Utility.cleanVariableString(headers[i]); - } - - Map headerTypes = new LinkedHashMap(); - for(int j = 0; j < cleanHeaders.length; j++) { - headerTypes.put(cleanHeaders[j], Utility.getCleanDataType(types[j])); - } - headerTypeMap.put(sheetName, headerTypes); - } - } else { - String delimiter = inputData.get("delimiter"); - // generate tinker frame from - if(inputData.get("delimiter") == null || inputData.get("delimiter").isEmpty()) { - delimiter = "\t"; - } - - CSVFileHelper helper = new CSVFileHelper(); - helper.setDelimiter(delimiter.charAt(0)); - helper.parse(fileLoc); - - String [] headers = helper.getHeaders(); - String [] types = helper.predictTypes(); - - Map headerTypes = new LinkedHashMap(); - for(int j = 0; j < headers.length; j++) { - headerTypes.put(headers[j], Utility.getCleanDataType(types[j])); - } - headerTypeMap.put(CSV_FILE_KEY, headerTypes); - retObj.put("delimiter", delimiter); - -// String htmlMessage = helper.getHTMLBasedHeaderChanges(); -// if(htmlMessage != null) { -// retObj.put(CSV_HELPER_MESSAGE, htmlMessage); -// } - - helper.clear(); - } - } - - retObj.put("headerData", headerTypeMap); - return retObj; - } } From 9c946e5acb35fd383e148b271f90d698b43016d7 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 4 Jun 2018 20:36:42 +0000 Subject: [PATCH 0066/1906] BUGFIX ::: Fixing error with settings app image git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28458 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 03c4dbddf03f9be355daa3545d9b38b74fc8d3d3 --- src/prerna/upload/ImageUploader.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/prerna/upload/ImageUploader.java b/src/prerna/upload/ImageUploader.java index 5a2b05bfe..881d79f56 100644 --- a/src/prerna/upload/ImageUploader.java +++ b/src/prerna/upload/ImageUploader.java @@ -3,6 +3,7 @@ import java.io.File; import java.io.FileFilter; import java.util.List; +import java.util.Properties; import java.util.Vector; import javax.servlet.http.HttpServletRequest; @@ -16,6 +17,9 @@ import prerna.engine.impl.SmssUtilities; import prerna.nameserver.utility.MasterDatabaseUtility; +import prerna.util.Constants; +import prerna.util.DIHelper; +import prerna.util.Utility; public class ImageUploader extends Uploader { @@ -40,7 +44,10 @@ public void uploadAppImage(@Context HttpServletRequest request) { } //TODO: account for user here - String appId = MasterDatabaseUtility.getEngineIdsForAlias(appName).get(0); + String appId = MasterDatabaseUtility.testEngineIdIfAlias(appName); + String propFileLoc = DIHelper.getInstance().getProperty(appId + "_" + Constants.STORE); + Properties prop = Utility.loadProperties(propFileLoc); + appName = prop.getProperty(Constants.ENGINE_ALIAS); // now that we have the app name // and the image file From 332c554ecfc30ef8464daf00342a6432324f4aee Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 4 Jun 2018 22:37:09 +0000 Subject: [PATCH 0067/1906] UPDATE ::: Readding file upload till xray can be ported UPDATE ::: Shifting excel to predict types w/ date format git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28473 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 12ee716feb5ec96bb7dcd516bc596a39759e2c0c --- .../semoss/web/services/NameServer.java | 12 + src/prerna/upload/DatabaseUploader.java | 407 +++++++++--------- src/prerna/upload/FileUploader.java | 216 ++++++++++ 3 files changed, 425 insertions(+), 210 deletions(-) create mode 100644 src/prerna/upload/FileUploader.java diff --git a/src/prerna/semoss/web/services/NameServer.java b/src/prerna/semoss/web/services/NameServer.java index c20778368..9aca1cc61 100644 --- a/src/prerna/semoss/web/services/NameServer.java +++ b/src/prerna/semoss/web/services/NameServer.java @@ -100,6 +100,7 @@ import prerna.solr.SolrIndexEngine.SOLR_PATHS; import prerna.solr.SolrIndexEngineQueryBuilder; import prerna.upload.DatabaseUploader; +import prerna.upload.FileUploader; import prerna.upload.ImageUploader; import prerna.upload.Uploader; import prerna.util.Constants; @@ -342,6 +343,17 @@ public Uploader uploadDatabase(@Context HttpServletRequest request) { return upload; } + @Path("/uploadFile") + public Uploader uploadFile(@Context HttpServletRequest request) { + Uploader upload = new FileUploader(); + String filePath = DIHelper.getInstance().getProperty(Constants.INSIGHT_CACHE_DIR) + "\\" + DIHelper.getInstance().getProperty(Constants.CSV_INSIGHT_CACHE_FOLDER); + upload.setFilePath(filePath); + String tempFilePath = context.getInitParameter("temp-file-upload"); + upload.setTempFilePath(tempFilePath); + upload.setSecurityEnabled(Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED))); + return upload; + } + @Path("/uploadImage") public Uploader uploadImage(@Context HttpServletRequest request) { Uploader upload = new ImageUploader(); diff --git a/src/prerna/upload/DatabaseUploader.java b/src/prerna/upload/DatabaseUploader.java index c4ff47db0..9134b6dcb 100644 --- a/src/prerna/upload/DatabaseUploader.java +++ b/src/prerna/upload/DatabaseUploader.java @@ -12,7 +12,6 @@ import java.util.Date; import java.util.HashMap; import java.util.Hashtable; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.UUID; @@ -47,6 +46,7 @@ import prerna.poi.main.MetaModelCreator; import prerna.poi.main.SolrEngineConnector; import prerna.poi.main.helper.CSVFileHelper; +import prerna.poi.main.helper.FileHelperUtil; import prerna.poi.main.helper.ImportOptions; import prerna.poi.main.helper.XLFileHelper; import prerna.rdf.main.ImportRDBMSProcessor; @@ -54,7 +54,6 @@ import prerna.util.Constants; import prerna.util.DIHelper; import prerna.util.Utility; -import prerna.util.ga.GATracker; import prerna.util.sql.SQLQueryUtil; import prerna.web.services.util.WebUtility; @@ -498,11 +497,6 @@ public Response uploadCsvFileAndPredictMetamodel(@Context HttpServletRequest req // store the info returnObj.put("metaModelData", metaModelData); - // add question file location on server is present - if(inputData.containsKey("questionFile")){ - returnObj.put("questionFile", returnObj.get("questionFile")); - } - return Response.status(200).entity(gson.toJson(returnObj)).build(); } @@ -636,10 +630,6 @@ public Response uploadCSVFile(MultivaluedMap form, @Context Http if(files != null && !files.isEmpty()) { deleteFilesFromServer(files.split(";")); } - String questionFile = form.getFirst("questionFile"); - if(questionFile != null && !questionFile.isEmpty()) { - deleteFilesFromServer(new String[]{questionFile}); - } } try { @@ -670,101 +660,100 @@ public Response uploadCSVFile(MultivaluedMap form, @Context Http return Response.status(200).entity(gson.toJson(outputText)).build(); } - @POST - @Path("/csv/flat") - @Produces("application/json") - /** - * The process flow for loading a flat file based on drag/drop - * Since the user confirms what type of datatypes they want for each column - * The file has already been loaded onto the server - * @param form Form object containing all the information regarding the load - * @param request - * @return - */ - public Response uploadFlatCsvFile(MultivaluedMap form, @Context HttpServletRequest request) { - Gson gson = new Gson(); - System.out.println(form); - - ImportOptions options = null; - try { - options = new ImportOptions(); - setDefaultOptions(options, form); - // can only load flat files as RDBMS - options.setDbType(ImportOptions.DB_TYPE.RDBMS); - options.setRDBMSDriverType(SQLQueryUtil.DB_TYPE.H2_DB); - options.setImportType(ImportOptions.IMPORT_TYPE.CSV_FLAT_LOAD); - - // set the files - String files = form.getFirst("file"); - if(files == null || files.trim().isEmpty()) { - Map errorHash = new HashMap(); - errorHash.put("errorMessage", "No files have been identified to upload"); - return Response.status(400).entity(gson.toJson(errorHash)).build(); - } - options.setFileLocation(files); - - // see if user also manually changed some the headers - String newHeadersStr = form.getFirst("newHeaders"); - System.out.println("new headers is " + newHeadersStr); - if(newHeadersStr != null && newHeadersStr.equalsIgnoreCase("undefined")) - newHeadersStr = null; - if(newHeadersStr != null) { - Map> newHeaders = - gson.fromJson(newHeadersStr, new TypeToken>>() {}.getType()); - options.setCsvNewHeaders(newHeaders); - } - - // this should always be present now since we dont want to predict types twice on the BE - // get the data types and set them in the options - String headerDataTypesStr = form.getFirst("headerData"); - if(headerDataTypesStr != null) { - List> headerDataTypes = - gson.fromJson(headerDataTypesStr, new TypeToken>>() {}.getType()); - options.setCsvDataTypeMap(headerDataTypes); - - // track GA data - String tableName = form.getFirst("dbName"); - GATracker.getInstance().trackCsvUpload(files, tableName, headerDataTypes); - } - // add engine owner for permissions - if(this.securityEnabled) { - Object user = request.getSession().getAttribute(Constants.SESSION_USER); - if(user != null && !((User) user).getId().equals(Constants.ANONYMOUS_USER_ID)) { - addEngineOwner(options.getDbName(), ((User) user).getId()); - } else { - Map errorHash = new HashMap(); - errorHash.put("errorMessage", "Please log in to upload data."); - return Response.status(400).entity(gson.toJson(errorHash)).build(); - } - } - - ImportDataProcessor importer = new ImportDataProcessor(); - importer.runProcessor(options); - } catch (IOException e) { - e.printStackTrace(); - Map errorHash = new HashMap(); - errorHash.put("errorMessage", e.getMessage()); - return Response.status(400).entity(gson.toJson(errorHash)).build(); - } catch(Exception e) { - e.printStackTrace(); - Map errorHash = new HashMap(); - errorHash.put("errorMessage", e.getMessage()); - return Response.status(400).entity(gson.toJson(errorHash)).build(); - } finally { - // we can't really use the options object for this :/ - String files = form.getFirst("file"); - if(files != null && !files.isEmpty()) { - deleteFilesFromServer(files.split(";")); - } - String questionFile = form.getFirst("questionFile"); - if(questionFile != null && !questionFile.isEmpty()) { - deleteFilesFromServer(new String[]{questionFile}); - } - } - - String outputText = "Flat database loading was a success."; - return Response.status(200).entity(gson.toJson(outputText)).build(); - } +// @POST +// @Path("/csv/flat") +// @Produces("application/json") +// /** +// * The process flow for loading a flat file based on drag/drop +// * Since the user confirms what type of datatypes they want for each column +// * The file has already been loaded onto the server +// * @param form Form object containing all the information regarding the load +// * @param request +// * @return +// */ +// public Response uploadFlatCsvFile(MultivaluedMap form, @Context HttpServletRequest request) { +// Gson gson = new Gson(); +// System.out.println(form); +// +// ImportOptions options = null; +// try { +// options = new ImportOptions(); +// setDefaultOptions(options, form); +// // can only load flat files as RDBMS +// options.setDbType(ImportOptions.DB_TYPE.RDBMS); +// options.setRDBMSDriverType(SQLQueryUtil.DB_TYPE.H2_DB); +// options.setImportType(ImportOptions.IMPORT_TYPE.CSV_FLAT_LOAD); +// +// // set the files +// String files = form.getFirst("file"); +// if(files == null || files.trim().isEmpty()) { +// Map errorHash = new HashMap(); +// errorHash.put("errorMessage", "No files have been identified to upload"); +// return Response.status(400).entity(gson.toJson(errorHash)).build(); +// } +// options.setFileLocation(files); +// +// // see if user also manually changed some the headers +// String newHeadersStr = form.getFirst("newHeaders"); +// System.out.println("new headers is " + newHeadersStr); +// if(newHeadersStr != null && newHeadersStr.equalsIgnoreCase("undefined")) +// newHeadersStr = null; +// if(newHeadersStr != null) { +// Map> newHeaders = +// gson.fromJson(newHeadersStr, new TypeToken>>() {}.getType()); +// options.setCsvNewHeaders(newHeaders); +// } +// +// // this should always be present now since we dont want to predict types twice on the BE +// // get the data types and set them in the options +// String headerDataTypesStr = form.getFirst("headerData"); +// if(headerDataTypesStr != null) { +// List> headerDataTypes = gson.fromJson(headerDataTypesStr, new TypeToken>>() {}.getType()); +// options.setCsvDataTypeMap(headerDataTypes); +// +// // track GA data +// String tableName = form.getFirst("dbName"); +// GATracker.getInstance().trackCsvUpload(files, tableName, headerDataTypes); +// } +// // add engine owner for permissions +// if(this.securityEnabled) { +// Object user = request.getSession().getAttribute(Constants.SESSION_USER); +// if(user != null && !((User) user).getId().equals(Constants.ANONYMOUS_USER_ID)) { +// addEngineOwner(options.getDbName(), ((User) user).getId()); +// } else { +// Map errorHash = new HashMap(); +// errorHash.put("errorMessage", "Please log in to upload data."); +// return Response.status(400).entity(gson.toJson(errorHash)).build(); +// } +// } +// +// ImportDataProcessor importer = new ImportDataProcessor(); +// importer.runProcessor(options); +// } catch (IOException e) { +// e.printStackTrace(); +// Map errorHash = new HashMap(); +// errorHash.put("errorMessage", e.getMessage()); +// return Response.status(400).entity(gson.toJson(errorHash)).build(); +// } catch(Exception e) { +// e.printStackTrace(); +// Map errorHash = new HashMap(); +// errorHash.put("errorMessage", e.getMessage()); +// return Response.status(400).entity(gson.toJson(errorHash)).build(); +// } finally { +// // we can't really use the options object for this :/ +// String files = form.getFirst("file"); +// if(files != null && !files.isEmpty()) { +// deleteFilesFromServer(files.split(";")); +// } +// String questionFile = form.getFirst("questionFile"); +// if(questionFile != null && !questionFile.isEmpty()) { +// deleteFilesFromServer(new String[]{questionFile}); +// } +// } +// +// String outputText = "Flat database loading was a success."; +// return Response.status(200).entity(gson.toJson(outputText)).build(); +// } ////////////////////////////////////////////// END CSV UPLOADING ////////////////////////////////////////////////////////// @@ -809,20 +798,19 @@ public Response uploadExcelFile(@Context HttpServletRequest request) { // store the suggested data types String[] sheetNames = helper.getTables(); Map> dataTypes = new Hashtable>(); + Map> additionalDataTypes = new Hashtable>(); + for(String sheetName : sheetNames) { - Map sheetDataMap = new LinkedHashMap(); - String[] columnHeaders = helper.getHeaders(sheetName); - String[] predicatedDataTypes = helper.predictRowTypes(sheetName); - - int size = columnHeaders.length; - for(int colIdx = 0; colIdx < size; colIdx++) { - sheetDataMap.put(columnHeaders[colIdx], Utility.getCleanDataType(predicatedDataTypes[colIdx])); - } + Map[] predictionMaps = FileHelperUtil.generateDataTypeMapsFromPrediction(helper.getHeaders(sheetName), helper.predictTypes(sheetName)); + Map sheetDataMap = predictionMaps[0]; + Map additionalTypesMap = predictionMaps[1]; dataTypes.put(sheetName, sheetDataMap); + additionalDataTypes.put(sheetName, additionalTypesMap); } fileMetaModelData.put("dataTypes", dataTypes); - + fileMetaModelData.put("additionalDataTypes", additionalDataTypes); + // store auto modified header names Map> fileHeaderMods = helper.getChangedHeaders(); fileMetaModelData.put("headerModifications", fileHeaderMods); @@ -836,7 +824,6 @@ public Response uploadExcelFile(@Context HttpServletRequest request) { // grab the error thrown and send it to the FE HashMap errorMap = new HashMap(); errorMap.put("errorMessage", e.getMessage()); -// return Response.status(400).entity(WebUtility.getSO(errorMap)).build(); return WebUtility.getResponse(errorMap, 400); } @@ -1074,100 +1061,100 @@ public Response uploadExcelPOIFormat(@Context HttpServletRequest request) return Response.status(200).entity(gson.toJson(outputText)).build(); } - @POST - @Path("/excel/flat") - @Produces("application/json") - /** - * The process flow for loading a flat file based on drag/drop - * Since the user confirms what type of datatypes they want for each column - * The file has already been loaded onto the server - * @param form Form object containing all the information regarding the load - * @param request - * @return - */ - public Response uploadFlatExcelFile(MultivaluedMap form, @Context HttpServletRequest request) { - Gson gson = new Gson(); - System.out.println(form); - - ImportOptions options = null; - try { - options = new ImportOptions(); - setDefaultOptions(options, form); - // can only load flat files as RDBMS - options.setDbType(ImportOptions.DB_TYPE.RDBMS); - options.setRDBMSDriverType(SQLQueryUtil.DB_TYPE.H2_DB); - options.setImportType(ImportOptions.IMPORT_TYPE.EXCEL_FLAT_UPLOAD); - - // set the files - String files = form.getFirst("file"); - if(files == null || files.trim().isEmpty()) { - Map errorHash = new HashMap(); - errorHash.put("errorMessage", "No files have been identified to upload"); - return Response.status(400).entity(gson.toJson(errorHash)).build(); - } - options.setFileLocation(files); - - // see if user also manually changed some the headers - String newHeadersStr = form.getFirst("newHeaders"); - if(newHeadersStr != null) { - List>> newHeaders = - gson.fromJson(newHeadersStr, new TypeToken>>>() {}.getType()); - options.setExcelNewHeaders(newHeaders); - } - - // this should always be present now since we dont want to predict types twice on the BE - // get the data types and set them in the options - String headerDataTypesStr = form.getFirst("headerData"); - if(headerDataTypesStr != null) { - List>> headerDataTypes = - gson.fromJson(headerDataTypesStr, new TypeToken>>>() {}.getType()); - options.setExcelDataTypeMap(headerDataTypes); - - // track GA data - String dbName = form.getFirst("dbName"); - String fileName = files.substring(files.lastIndexOf("\\") + 1, files.lastIndexOf(".")); - GATracker.getInstance().trackExcelUpload(dbName, fileName, headerDataTypes); - } - - // add engine owner for permissions - if(this.securityEnabled) { - Object user = request.getSession().getAttribute(Constants.SESSION_USER); - if(user != null && !((User) user).getId().equals(Constants.ANONYMOUS_USER_ID)) { - addEngineOwner(options.getDbName(), ((User) user).getId()); - } else { - Map errorHash = new HashMap(); - errorHash.put("errorMessage", "Please log in to upload data."); - return Response.status(400).entity(gson.toJson(errorHash)).build(); - } - } - - ImportDataProcessor importer = new ImportDataProcessor(); - importer.runProcessor(options); - } catch (IOException e) { - e.printStackTrace(); - Map errorHash = new HashMap(); - errorHash.put("errorMessage", e.getMessage()); - return Response.status(400).entity(gson.toJson(errorHash)).build(); - } catch(Exception e) { - e.printStackTrace(); - Map errorHash = new HashMap(); - errorHash.put("errorMessage", e.getMessage()); - return Response.status(400).entity(gson.toJson(errorHash)).build(); - } finally { - // we can't really use the options object for this :/ - String files = form.getFirst("file"); - if(files != null && !files.isEmpty()) { - deleteFilesFromServer(files.split(";")); - } - String questionFile = form.getFirst("questionFile"); - if(questionFile != null && !questionFile.isEmpty()) { - deleteFilesFromServer(new String[]{questionFile}); - } - } - - String outputText = "Flat database loading was a success."; - return Response.status(200).entity(gson.toJson(outputText)).build(); - } +// @POST +// @Path("/excel/flat") +// @Produces("application/json") +// /** +// * The process flow for loading a flat file based on drag/drop +// * Since the user confirms what type of datatypes they want for each column +// * The file has already been loaded onto the server +// * @param form Form object containing all the information regarding the load +// * @param request +// * @return +// */ +// public Response uploadFlatExcelFile(MultivaluedMap form, @Context HttpServletRequest request) { +// Gson gson = new Gson(); +// System.out.println(form); +// +// ImportOptions options = null; +// try { +// options = new ImportOptions(); +// setDefaultOptions(options, form); +// // can only load flat files as RDBMS +// options.setDbType(ImportOptions.DB_TYPE.RDBMS); +// options.setRDBMSDriverType(SQLQueryUtil.DB_TYPE.H2_DB); +// options.setImportType(ImportOptions.IMPORT_TYPE.EXCEL_FLAT_UPLOAD); +// +// // set the files +// String files = form.getFirst("file"); +// if(files == null || files.trim().isEmpty()) { +// Map errorHash = new HashMap(); +// errorHash.put("errorMessage", "No files have been identified to upload"); +// return Response.status(400).entity(gson.toJson(errorHash)).build(); +// } +// options.setFileLocation(files); +// +// // see if user also manually changed some the headers +// String newHeadersStr = form.getFirst("newHeaders"); +// if(newHeadersStr != null) { +// List>> newHeaders = +// gson.fromJson(newHeadersStr, new TypeToken>>>() {}.getType()); +// options.setExcelNewHeaders(newHeaders); +// } +// +// // this should always be present now since we dont want to predict types twice on the BE +// // get the data types and set them in the options +// String headerDataTypesStr = form.getFirst("headerData"); +// if(headerDataTypesStr != null) { +// List>> headerDataTypes = +// gson.fromJson(headerDataTypesStr, new TypeToken>>>() {}.getType()); +// options.setExcelDataTypeMap(headerDataTypes); +// +// // track GA data +// String dbName = form.getFirst("dbName"); +// String fileName = files.substring(files.lastIndexOf("\\") + 1, files.lastIndexOf(".")); +// GATracker.getInstance().trackExcelUpload(dbName, fileName, headerDataTypes); +// } +// +// // add engine owner for permissions +// if(this.securityEnabled) { +// Object user = request.getSession().getAttribute(Constants.SESSION_USER); +// if(user != null && !((User) user).getId().equals(Constants.ANONYMOUS_USER_ID)) { +// addEngineOwner(options.getDbName(), ((User) user).getId()); +// } else { +// Map errorHash = new HashMap(); +// errorHash.put("errorMessage", "Please log in to upload data."); +// return Response.status(400).entity(gson.toJson(errorHash)).build(); +// } +// } +// +// ImportDataProcessor importer = new ImportDataProcessor(); +// importer.runProcessor(options); +// } catch (IOException e) { +// e.printStackTrace(); +// Map errorHash = new HashMap(); +// errorHash.put("errorMessage", e.getMessage()); +// return Response.status(400).entity(gson.toJson(errorHash)).build(); +// } catch(Exception e) { +// e.printStackTrace(); +// Map errorHash = new HashMap(); +// errorHash.put("errorMessage", e.getMessage()); +// return Response.status(400).entity(gson.toJson(errorHash)).build(); +// } finally { +// // we can't really use the options object for this :/ +// String files = form.getFirst("file"); +// if(files != null && !files.isEmpty()) { +// deleteFilesFromServer(files.split(";")); +// } +// String questionFile = form.getFirst("questionFile"); +// if(questionFile != null && !questionFile.isEmpty()) { +// deleteFilesFromServer(new String[]{questionFile}); +// } +// } +// +// String outputText = "Flat database loading was a success."; +// return Response.status(200).entity(gson.toJson(outputText)).build(); +// } ////////////////////////////////////////////// END EXCEL UPLOADING ////////////////////////////////////////////////////////// diff --git a/src/prerna/upload/FileUploader.java b/src/prerna/upload/FileUploader.java new file mode 100644 index 000000000..c7d5012d8 --- /dev/null +++ b/src/prerna/upload/FileUploader.java @@ -0,0 +1,216 @@ +package prerna.upload; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.Response; + +import org.apache.commons.fileupload.FileItem; +import org.apache.log4j.LogManager; +import org.apache.log4j.Logger; + +import prerna.cache.FileStore; +import prerna.poi.main.helper.AmazonApiHelper; +import prerna.poi.main.helper.CSVFileHelper; +import prerna.poi.main.helper.FileHelperUtil; +import prerna.poi.main.helper.ImportApiHelper; +import prerna.poi.main.helper.WebAPIHelper; +import prerna.poi.main.helper.XLFileHelper; +import prerna.util.Utility; +import prerna.web.services.util.WebUtility; + +public class FileUploader extends Uploader { + + private static final Logger LOGGER = LogManager.getLogger(FileUploader.class); + /* + * Moving a file onto the BE cannot be performed through PKQL + * Thus, we still expose "drag and drop" of a file through a rest call + * However, this is only used to push the file to the BE server, the actual + * processing of the file to create/add to a data frame occurs through PKQL + */ + + @POST + @Path("determineDataTypesForFile") + public Response determineDataTypesForFile(@Context HttpServletRequest request) { + try { + List fileItems = processRequest(request); + // collect all of the data input on the form + Hashtable inputData = getInputData(fileItems); + Map retObj = generateDataTypes(inputData); + return WebUtility.getResponse(retObj, 200); + } catch(Exception e) { + e.printStackTrace(); + HashMap errorMap = new HashMap(); + errorMap.put("errorMessage", "Error processing new data"); + return WebUtility.getResponse(errorMap, 400); + } + } + + + /** + * + * @param inputData + * @return + * @throws IOException + */ + protected static Map generateDataTypes(Map inputData) throws IOException { + Map retObj = new HashMap(); + + Map> headerTypeMap = new Hashtable>(); + + boolean webExtract = (inputData.get("file") == null); + String keyvalue = ""; + + if(webExtract){//Provision for extracted data via import.io + WebAPIHelper helper = null; + if(inputData.get("api") != null){ + keyvalue = inputData.get("api"); + helper = new ImportApiHelper(); + }else if(inputData.get("itemSearch") != null){ + keyvalue = inputData.get("itemSearch"); + helper = new AmazonApiHelper(); + ((AmazonApiHelper) helper).setOperationType("ItemSearch"); + }else if(inputData.get("itemLookup") != null){ + keyvalue = inputData.get("itemLookup"); + helper = new AmazonApiHelper(); + ((AmazonApiHelper) helper).setOperationType("ItemLookup"); + } + + helper.setApiParam(keyvalue); + helper.parse(); + + + String [] headers = helper.getHeaders(); + String [] types = helper.predictTypes(); + + Map headerTypes = new LinkedHashMap(); + for(int j = 0; j < headers.length; j++) { + headerTypes.put(headers[j], Utility.getCleanDataType(types[j])); + } + headerTypeMap.put(CSV_FILE_KEY, headerTypes); + + } else { + + String fileLoc = inputData.get("file"); + String uniqueStorageId = FileStore.getInstance().put(fileLoc); + retObj.put("uniqueFileKey", uniqueStorageId); + if(fileLoc.endsWith(".xlsx") || fileLoc.endsWith(".xlsm")) { + XLFileHelper helper = new XLFileHelper(); + helper.parse(fileLoc); + + String[] sheets = helper.getTables(); + for(int i = 0; i < sheets.length; i++) { + String sheetName = sheets[i]; + String[] headers = helper.getHeaders(sheetName); + String[] types = FileHelperUtil.generateDataTypeArrayFromPrediction(helper.predictTypes(sheetName)); + + String [] cleanHeaders = new String[headers.length]; + for(int x = 0; x < headers.length; x++) { + cleanHeaders[i] = Utility.cleanVariableString(headers[i]); + } + + Map headerTypes = new LinkedHashMap(); + for(int j = 0; j < cleanHeaders.length; j++) { + headerTypes.put(cleanHeaders[j], Utility.getCleanDataType(types[j])); + } + headerTypeMap.put(sheetName, headerTypes); + } + } else { + String delimiter = inputData.get("delimiter"); + // generate tinker frame from + if(inputData.get("delimiter") == null || inputData.get("delimiter").isEmpty()) { + delimiter = "\t"; + } + + CSVFileHelper helper = new CSVFileHelper(); + helper.setDelimiter(delimiter.charAt(0)); + helper.parse(fileLoc); + + String[] headers = helper.getHeaders(); + String[] types = FileHelperUtil.generateDataTypeArrayFromPrediction(helper.predictTypes()); + + Map headerTypes = new LinkedHashMap(); + for(int j = 0; j < headers.length; j++) { + headerTypes.put(headers[j], Utility.getCleanDataType(types[j])); + } + headerTypeMap.put(CSV_FILE_KEY, headerTypes); + retObj.put("delimiter", delimiter); + + helper.clear(); + } + } + + retObj.put("headerData", headerTypeMap); + return retObj; + } + + + /** + * Extract the data to generate the file being passed from the user to the BE server + */ + @Override + protected Hashtable getInputData(List fileItems) + { + // Process the uploaded file items + Iterator iteratorFileItems = fileItems.iterator(); + + // collect all of the data input on the form + Hashtable inputData = new Hashtable(); + File file; + + while(iteratorFileItems.hasNext()) + { + FileItem fi = (FileItem) iteratorFileItems.next(); + // Get the uploaded file parameters + String fieldName = fi.getFieldName(); + String fileName = fi.getName(); + String value = fi.getString(); + if (!fi.isFormField()) { + if(fileName.equals("")) { + continue; + } + else { + if(fieldName.equals("file")) { + // need to clean the fileName to not have ";" since we split on that in upload data + fileName = fileName.replace(";", ""); + Date date = new Date(); + String modifiedDate = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_SSSS").format(date); + value = filePath + "\\\\" + fileName.substring(fileName.lastIndexOf("\\") + 1, fileName.lastIndexOf(".")).replace(" ", "") + modifiedDate + fileName.substring(fileName.lastIndexOf(".")); + file = new File(value); + writeFile(fi, file); + LOGGER.info("Saved Filename: " + fileName + " to "+ file); + } + } + } else if(fieldName.equals("file")) { // its a file, but not in a form + System.err.println("Writing input string into file..."); + Date date = new Date(); + String modifiedDate = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_SSSS").format(date); + value = filePath + "\\\\FileString_" + modifiedDate; + file = new File(value); + writeFile(fi, file); + LOGGER.info( "Created new file..."); + } + //need to handle multiple files getting selected for upload + if(inputData.get(fieldName) != null) + { + value = inputData.get(fieldName) + ";" + value; + } + inputData.put(fieldName, value); + fi.delete(); + } + + return inputData; + } +} From acbb239399f83dc6de596c393347bd34f8760a49 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 5 Jun 2018 16:51:58 +0000 Subject: [PATCH 0068/1906] UPDATE ::: Pushing in standard key to substring file names when we append date for uniqueness UPDATE ::: Adding check to not create random folders for app ids that don't actually exist git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28506 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 5295203d62f39fc63219b8e0ce5a1d92188f8fd6 --- src/prerna/semoss/web/services/AppResource.java | 11 +++++++---- src/prerna/upload/Uploader.java | 2 +- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/prerna/semoss/web/services/AppResource.java b/src/prerna/semoss/web/services/AppResource.java index 1d46b1c3b..9461ef3ed 100644 --- a/src/prerna/semoss/web/services/AppResource.java +++ b/src/prerna/semoss/web/services/AppResource.java @@ -44,13 +44,13 @@ public class AppResource { @Produces(MediaType.APPLICATION_OCTET_STREAM) public Response downloadAppImage(@Context HttpServletRequest request, @PathParam("appName") String app) { File exportFile = getAppImageFile(app); - if(exportFile.exists()) { + if(exportFile != null && exportFile.exists()) { String exportName = app + "_Image." + FilenameUtils.getExtension(exportFile.getAbsolutePath()); return Response.status(200).entity(exportFile).header("Content-Disposition", "attachment; filename=" + exportName).build(); } else { Map errorMap = new HashMap(); errorMap.put("errorMessage", "error sending image file"); - return Response.status(400).entity(errorMap).build(); + return WebUtility.getResponse(errorMap, 400); } } @@ -62,6 +62,9 @@ public Response downloadAppImage(@Context HttpServletRequest request, @PathParam private File getAppImageFile(String app) { String appId = MasterDatabaseUtility.testEngineIdIfAlias(app); String propFileLoc = DIHelper.getInstance().getProperty(appId + "_" + Constants.STORE); + if(propFileLoc == null && !app.equals("NEWSEMOSSAPP")) { + return null; + } Properties prop = Utility.loadProperties(propFileLoc); app = prop.getProperty(Constants.ENGINE_ALIAS); @@ -90,13 +93,13 @@ private File getAppImageFile(String app) { @Produces(MediaType.APPLICATION_OCTET_STREAM) public Response downloadInsightImage(@Context HttpServletRequest request, @PathParam("appName") String app, @QueryParam("rdbmsId") String id, @QueryParam("params") String params) { File exportFile = getInsightImageFile(app, id, request.getHeader("Referer"), params); - if(exportFile.exists()) { + if(exportFile != null && exportFile.exists()) { String exportName = app + "_Image." + FilenameUtils.getExtension(exportFile.getAbsolutePath()); return Response.status(200).entity(exportFile).header("Content-Disposition", "attachment; filename=" + exportName).build(); } else { Map errorMap = new HashMap(); errorMap.put("errorMessage", "error sending image file"); - return Response.status(400).entity(errorMap).build(); + return WebUtility.getResponse(errorMap, 400); } } diff --git a/src/prerna/upload/Uploader.java b/src/prerna/upload/Uploader.java index 196cfafde..dcef6d18c 100644 --- a/src/prerna/upload/Uploader.java +++ b/src/prerna/upload/Uploader.java @@ -155,7 +155,7 @@ protected Hashtable getInputData(List fileItems) fileName = fileName.replace(";", ""); Date date = new Date(); String modifiedDate = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_SSSS").format(date); - value = this.filePath + fileName.substring(fileName.lastIndexOf(DIR_SEPARATOR) + 1, fileName.lastIndexOf(".")).trim().replace(" ", "_") + modifiedDate + fileName.substring(fileName.lastIndexOf(".")); + value = this.filePath + fileName.substring(fileName.lastIndexOf(DIR_SEPARATOR) + 1, fileName.lastIndexOf(".")).trim().replace(" ", "_") + "_____UNIQUE" + modifiedDate + fileName.substring(fileName.lastIndexOf(".")); file = new File(value); writeFile(fi, file); LOGGER.info("File item is the actual data. Saved Filename: " + fileName + " to "+ file); From b53242198a6039e6c3e59fc798a9d8881a618180 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 5 Jun 2018 19:52:56 +0000 Subject: [PATCH 0069/1906] UPDATE ::: Modifying payload for pasted data so it returns additional types git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28532 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 74108874c404ab20f4c68f02dd6efcc972777b04 --- src/prerna/upload/FileUploader.java | 128 +++++++++------------------- 1 file changed, 40 insertions(+), 88 deletions(-) diff --git a/src/prerna/upload/FileUploader.java b/src/prerna/upload/FileUploader.java index c7d5012d8..529308cb5 100644 --- a/src/prerna/upload/FileUploader.java +++ b/src/prerna/upload/FileUploader.java @@ -7,7 +7,6 @@ import java.util.HashMap; import java.util.Hashtable; import java.util.Iterator; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -22,13 +21,9 @@ import org.apache.log4j.Logger; import prerna.cache.FileStore; -import prerna.poi.main.helper.AmazonApiHelper; import prerna.poi.main.helper.CSVFileHelper; import prerna.poi.main.helper.FileHelperUtil; -import prerna.poi.main.helper.ImportApiHelper; -import prerna.poi.main.helper.WebAPIHelper; import prerna.poi.main.helper.XLFileHelper; -import prerna.util.Utility; import prerna.web.services.util.WebUtility; public class FileUploader extends Uploader { @@ -40,7 +35,7 @@ public class FileUploader extends Uploader { * However, this is only used to push the file to the BE server, the actual * processing of the file to create/add to a data frame occurs through PKQL */ - + @POST @Path("determineDataTypesForFile") public Response determineDataTypesForFile(@Context HttpServletRequest request) { @@ -57,7 +52,7 @@ public Response determineDataTypesForFile(@Context HttpServletRequest request) { return WebUtility.getResponse(errorMap, 400); } } - + /** * @@ -68,95 +63,52 @@ public Response determineDataTypesForFile(@Context HttpServletRequest request) { protected static Map generateDataTypes(Map inputData) throws IOException { Map retObj = new HashMap(); - Map> headerTypeMap = new Hashtable>(); - - boolean webExtract = (inputData.get("file") == null); - String keyvalue = ""; - - if(webExtract){//Provision for extracted data via import.io - WebAPIHelper helper = null; - if(inputData.get("api") != null){ - keyvalue = inputData.get("api"); - helper = new ImportApiHelper(); - }else if(inputData.get("itemSearch") != null){ - keyvalue = inputData.get("itemSearch"); - helper = new AmazonApiHelper(); - ((AmazonApiHelper) helper).setOperationType("ItemSearch"); - }else if(inputData.get("itemLookup") != null){ - keyvalue = inputData.get("itemLookup"); - helper = new AmazonApiHelper(); - ((AmazonApiHelper) helper).setOperationType("ItemLookup"); - } - - helper.setApiParam(keyvalue); - helper.parse(); - - - String [] headers = helper.getHeaders(); - String [] types = helper.predictTypes(); - - Map headerTypes = new LinkedHashMap(); - for(int j = 0; j < headers.length; j++) { - headerTypes.put(headers[j], Utility.getCleanDataType(types[j])); + String fileLoc = inputData.get("file"); + String uniqueStorageId = FileStore.getInstance().put(fileLoc); + retObj.put("uniqueFileKey", uniqueStorageId); + if(fileLoc.endsWith(".xlsx") || fileLoc.endsWith(".xlsm")) { + XLFileHelper helper = new XLFileHelper(); + helper.parse(fileLoc); + + String[] sheets = helper.getTables(); + for(int i = 0; i < sheets.length; i++) { + String sheetName = sheets[i]; + String[] headers = helper.getHeaders(sheetName); + Map[] retMaps = FileHelperUtil.generateDataTypeMapsFromPrediction(headers, helper.predictTypes(sheetName)); + + Map innerObj = new HashMap(); + innerObj.put("dataTypes", retMaps[0]); + innerObj.put("additionalDataTypes", retMaps[1]); + retObj.put(sheetName, innerObj); } - headerTypeMap.put(CSV_FILE_KEY, headerTypes); - + + helper.clear(); } else { + String delimiter = inputData.get("delimiter"); + // generate tinker frame from + if(inputData.get("delimiter") == null || inputData.get("delimiter").isEmpty()) { + delimiter = "\t"; + } - String fileLoc = inputData.get("file"); - String uniqueStorageId = FileStore.getInstance().put(fileLoc); - retObj.put("uniqueFileKey", uniqueStorageId); - if(fileLoc.endsWith(".xlsx") || fileLoc.endsWith(".xlsm")) { - XLFileHelper helper = new XLFileHelper(); - helper.parse(fileLoc); - - String[] sheets = helper.getTables(); - for(int i = 0; i < sheets.length; i++) { - String sheetName = sheets[i]; - String[] headers = helper.getHeaders(sheetName); - String[] types = FileHelperUtil.generateDataTypeArrayFromPrediction(helper.predictTypes(sheetName)); - - String [] cleanHeaders = new String[headers.length]; - for(int x = 0; x < headers.length; x++) { - cleanHeaders[i] = Utility.cleanVariableString(headers[i]); - } - - Map headerTypes = new LinkedHashMap(); - for(int j = 0; j < cleanHeaders.length; j++) { - headerTypes.put(cleanHeaders[j], Utility.getCleanDataType(types[j])); - } - headerTypeMap.put(sheetName, headerTypes); - } - } else { - String delimiter = inputData.get("delimiter"); - // generate tinker frame from - if(inputData.get("delimiter") == null || inputData.get("delimiter").isEmpty()) { - delimiter = "\t"; - } - - CSVFileHelper helper = new CSVFileHelper(); - helper.setDelimiter(delimiter.charAt(0)); - helper.parse(fileLoc); + CSVFileHelper helper = new CSVFileHelper(); + helper.setDelimiter(delimiter.charAt(0)); + helper.parse(fileLoc); - String[] headers = helper.getHeaders(); - String[] types = FileHelperUtil.generateDataTypeArrayFromPrediction(helper.predictTypes()); + String[] headers = helper.getHeaders(); + Map[] retMaps = FileHelperUtil.generateDataTypeMapsFromPrediction(headers, helper.predictTypes()); - Map headerTypes = new LinkedHashMap(); - for(int j = 0; j < headers.length; j++) { - headerTypes.put(headers[j], Utility.getCleanDataType(types[j])); - } - headerTypeMap.put(CSV_FILE_KEY, headerTypes); - retObj.put("delimiter", delimiter); - - helper.clear(); - } + Map innerObj = new HashMap(); + innerObj.put("dataTypes", retMaps[0]); + innerObj.put("additionalDataTypes", retMaps[1]); + retObj.put(CSV_FILE_KEY, innerObj); + retObj.put("delimiter", delimiter); + helper.clear(); } - retObj.put("headerData", headerTypeMap); return retObj; } - - + + /** * Extract the data to generate the file being passed from the user to the BE server */ @@ -187,7 +139,7 @@ protected Hashtable getInputData(List fileItems) fileName = fileName.replace(";", ""); Date date = new Date(); String modifiedDate = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_SSSS").format(date); - value = filePath + "\\\\" + fileName.substring(fileName.lastIndexOf("\\") + 1, fileName.lastIndexOf(".")).replace(" ", "") + modifiedDate + fileName.substring(fileName.lastIndexOf(".")); + value = filePath + "\\\\" + fileName.substring(fileName.lastIndexOf("\\") + 1, fileName.lastIndexOf(".")).replace(" ", "") + "_____UNIQUE" + modifiedDate + fileName.substring(fileName.lastIndexOf(".")); file = new File(value); writeFile(fi, file); LOGGER.info("Saved Filename: " + fileName + " to "+ file); From e0e414d8cb42be3a6211b86daf48b0380f93b311 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 5 Jun 2018 20:09:53 +0000 Subject: [PATCH 0070/1906] UPDATE ::: Cleaning file name by removing from _____UNQIUE git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28534 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 0c6e3fd8a49e6e9fd260d8a1156a8f8ea8815165 --- src/prerna/upload/DatabaseUploader.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/prerna/upload/DatabaseUploader.java b/src/prerna/upload/DatabaseUploader.java index 9134b6dcb..2d4f75351 100644 --- a/src/prerna/upload/DatabaseUploader.java +++ b/src/prerna/upload/DatabaseUploader.java @@ -427,7 +427,7 @@ public Response uploadCsvFileAndPredictMetamodel(@Context HttpServletRequest req char delimiter = delimiters[i].charAt(0); String file = filePath.substring(filePath.lastIndexOf(DIR_SEPARATOR) + DIR_SEPARATOR.length(), filePath.lastIndexOf(".")); try { - file = file.substring(0, file.length() - 24); //taking out the date added onto the original file name + file = file.substring(0, file.indexOf("_____UNIQUE")); //taking out the date added onto the original file name } catch(Exception e) { //just in case that fails, this shouldnt because if its a filename it should have a "." file = filePath.substring(filePath.lastIndexOf(DIR_SEPARATOR) + DIR_SEPARATOR.length(), filePath.lastIndexOf(".")); @@ -786,7 +786,7 @@ public Response uploadExcelFile(@Context HttpServletRequest request) { fileMetaModelData.put("fileLocation", files[i]); String file = files[i].substring(files[i].lastIndexOf("\\") + 1, files[i].lastIndexOf(".")); try { - file = file.substring(0, file.length() - 24); //taking out the date added onto the original file name + file = file.substring(0, file.indexOf("_____UNIQUE")); //taking out the date added onto the original file name } catch(Exception e) { file = files[i].substring(files[i].lastIndexOf("\\") + 1, files[i].lastIndexOf(".")); //just in case that fails, this shouldnt because if its a filename it should have a "." } From 5764c7a08e3d12fa1122a6e49d669aac5a084589 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 6 Jun 2018 20:39:25 +0000 Subject: [PATCH 0071/1906] UPDATE ::: Requiring CAC information to be set for forms to get the user git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28577 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 19f94fbd427398d90eb27d0feaa01083af75435b --- .../semoss/web/services/EngineResource.java | 25 ++++++++++++++++--- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/prerna/semoss/web/services/EngineResource.java b/src/prerna/semoss/web/services/EngineResource.java index 8e3957b09..753766150 100644 --- a/src/prerna/semoss/web/services/EngineResource.java +++ b/src/prerna/semoss/web/services/EngineResource.java @@ -28,6 +28,7 @@ package prerna.semoss.web.services; import java.io.File; +import java.util.HashMap; import java.util.Hashtable; import java.util.List; import java.util.Map; @@ -50,7 +51,9 @@ import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; +import prerna.auth.AuthProvider; import prerna.auth.User; +import prerna.auth.User2; import prerna.engine.api.IEngine; import prerna.engine.api.IEngine.ENGINE_TYPE; import prerna.engine.api.IRawSelectWrapper; @@ -221,14 +224,28 @@ public Response createOutput(MultivaluedMap form, @Context HttpS NounMetadata retNoun = playsheetRunReactor.execute(); return WebUtility.getResponse(retNoun.getValue(), 200); - } @POST @Path("/commitFormData") @Produces("application/json") - public Response commitFormData(MultivaluedMap form, @Context HttpServletRequest request) + public Response commitFormData(@Context HttpServletRequest request, MultivaluedMap form) { + String userId = null; + try { + HttpSession session = ((HttpServletRequest)request).getSession(false); + User2 user = (User2) session.getAttribute("semoss_user"); + userId = user.getAccessToken(AuthProvider.CAC.toString()).getName(); + } catch(Exception e) { + Map err = new HashMap(); + err.put("errorMessage", "Could not identify user"); + return WebUtility.getResponse(err, 400); + } + if(userId == null) { + Map err = new HashMap(); + err.put("errorMessage", "Could not identify user"); + return WebUtility.getResponse(err, 400); + } Gson gson = new Gson(); try { String formData = form.getFirst("formData"); @@ -237,11 +254,11 @@ public Response commitFormData(MultivaluedMap form, @Context Htt AbstractFormBuilder formbuilder = FormFactory.getFormBuilder(this.coreEngine); if(formbuilder != null) { //TODO: need to build this out for RDBMS engines!!! - formbuilder.commitFormData(engineHash); + formbuilder.commitFormData(engineHash, userId); } else { // old way is super messy since it has both implementations of inserting // into both rdbms and rdf.. super annoying to go through - FormBuilder.commitFormData(this.coreEngine, engineHash); + FormBuilder.commitFormData(this.coreEngine, engineHash, userId); } } catch(Exception e) { e.printStackTrace(); From ca83f223efbfc0a102413c5e45784df25fa1504d Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 7 Jun 2018 15:34:40 +0000 Subject: [PATCH 0072/1906] BUGFIX ::: Fixing error with session id for playsheets git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28583 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: bec12059459d123cabf278177b4b5736c9ada552 --- src/prerna/semoss/web/services/EngineResource.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/prerna/semoss/web/services/EngineResource.java b/src/prerna/semoss/web/services/EngineResource.java index 753766150..d6f3651a2 100644 --- a/src/prerna/semoss/web/services/EngineResource.java +++ b/src/prerna/semoss/web/services/EngineResource.java @@ -62,11 +62,14 @@ import prerna.forms.FormFactory; import prerna.insights.admin.DBAdminResource; import prerna.om.Insight; +import prerna.om.InsightStore; import prerna.rdf.engine.wrappers.WrapperManager; import prerna.sablecc2.om.GenRowStruct; import prerna.sablecc2.om.PixelDataType; import prerna.sablecc2.om.ReactorKeysEnum; import prerna.sablecc2.om.nounmeta.NounMetadata; +import prerna.sablecc2.reactor.PixelPlanner; +import prerna.sablecc2.reactor.job.JobReactor; import prerna.sablecc2.reactor.legacy.playsheets.GetPlaysheetParamsReactor; import prerna.sablecc2.reactor.legacy.playsheets.RunPlaysheetReactor; import prerna.util.Constants; @@ -208,8 +211,14 @@ public Response createOutput(MultivaluedMap form, @Context HttpS // make an insight to set // so we can pass the user Insight dummyIn = new Insight(); + InsightStore.getInstance().put(dummyIn); + InsightStore.getInstance().addToSessionHash(session.getId(), dummyIn.getInsightId()); + dummyIn.getVarStore().put(JobReactor.SESSION_KEY, new NounMetadata(session.getId(), PixelDataType.CONST_STRING)); dummyIn.setUser(user); playsheetRunReactor.setInsight(dummyIn); + PixelPlanner planner = new PixelPlanner(); + planner.setVarStore(dummyIn.getVarStore()); + playsheetRunReactor.setPixelPlanner(planner); GenRowStruct grs1 = new GenRowStruct(); grs1.add(new NounMetadata(coreEngine.getEngineId(), PixelDataType.CONST_STRING)); playsheetRunReactor.getNounStore().addNoun(ReactorKeysEnum.APP.getKey(), grs1); From 5f693ec44af1f5730b7a1f8e4dd5f07e6b273193 Mon Sep 17 00:00:00 2001 From: tbanach Date: Thu, 7 Jun 2018 16:34:48 +0000 Subject: [PATCH 0073/1906] REQUIREMENT ::: Right click Semoss and Monolith and Maven update. UPDATE ::: Commenting out unused libraries in pom.xml. git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28591 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 97db67e62888242f31f762ed426cd63604342a2c --- pom.xml | 609 +++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 378 insertions(+), 231 deletions(-) diff --git a/pom.xml b/pom.xml index 8ce53f7c5..fdd6cd7b6 100644 --- a/pom.xml +++ b/pom.xml @@ -120,7 +120,8 @@ - + + com.blazegraph bigdata @@ -142,7 +143,8 @@ - + + org.apache.commons commons-collections4 @@ -208,6 +210,16 @@ + + commons-collections + commons-collections + 3.2.1 + + + commons-beanutils + commons-beanutils + 1.9.2 + org.apache.commons commons-dbcp2 @@ -318,7 +330,8 @@ - + + + + + + + + com.google.apis google-api-services-oauth2 @@ -384,7 +400,8 @@ - + + + + com.google.oauth-client google-oauth-client @@ -417,7 +435,8 @@ - + + + + + + + + + + + + + + org.apache.tinkerpop tinkergraph-gremlin @@ -560,7 +585,8 @@ - + + org.codehaus.groovy groovy-jsr223 @@ -583,7 +609,8 @@ - + + com.google.code.gson gson @@ -633,7 +660,8 @@ - + + + + org.apache.httpcomponents httpclient @@ -666,7 +695,8 @@ - + + + + org.apache.httpcomponents httpcore @@ -699,7 +730,8 @@ - + + com.ibm.icu icu4j @@ -721,7 +753,8 @@ - + + com.itextpdf itextpdf @@ -743,7 +776,8 @@ - + + + + + + org.javatuples javatuples @@ -798,7 +834,8 @@ - + + + + + + redis.clients jedis @@ -864,7 +903,8 @@ - + + org.apache.jena jena-larq @@ -886,7 +926,8 @@ - + + + + org.python @@ -931,7 +973,8 @@ - + + org.jgrapht jgrapht-core @@ -975,7 +1018,8 @@ - + + + + + + + + org.jsoup jsoup @@ -1041,7 +1088,8 @@ - + + net.sf.jung jung-algorithms @@ -1096,7 +1144,8 @@ - + + log4j log4j @@ -1129,7 +1178,8 @@ - + + org.apache.lucene lucene-core @@ -1184,7 +1234,8 @@ - + + mysql mysql-connector-java @@ -1206,7 +1257,8 @@ - + + + + + + + + com.oracle ojdbc6 @@ -1283,7 +1338,8 @@ - + + + + org.jboss.resteasy resteasy-jaxrs @@ -1349,7 +1406,8 @@ - + + + + + + + + + + + + + + + + + + org.apache.solr solr-core 4.7.0 - + - + + + + + + + + + + + + org.apache.solr solr-solrj 4.7.0 - + - + + + + + + edu.stanford.nlp stanford-corenlp @@ -1592,7 +1667,8 @@ - + + net.sf.supercsv super-csv @@ -1636,7 +1712,8 @@ - + + com.github.dblock.waffle waffle-jna @@ -1685,7 +1762,8 @@ - + + + + + + + + + + + it.unimi.dsi + dsiutils + 2.4.2 + + + aurelionribon.ui css-engine-swing-api @@ -1762,7 +1850,8 @@ - + + + + + + + + + + com.teamdev.jxbrowser jxbrowser @@ -1828,7 +1921,8 @@ - + + + + + + + + + + org.rednoise rita @@ -1894,7 +1992,8 @@ - + + com.microsoft sqlserver @@ -1916,7 +2015,8 @@ - + + edu.cmu ws4j @@ -1985,23 +2085,26 @@ 1.4.0 - + + - + + - + + org.scala-lang @@ -2009,11 +2112,12 @@ 2.11.7 - + + org.apache.hadoop @@ -2021,11 +2125,12 @@ 2.6.0 - + + org.javassist @@ -2063,33 +2168,37 @@ extjwnl 1.9.2 - + + + + - + + org.apache.storm storm-core 1.0.2 - + + org.quartz-scheduler quartz @@ -2126,16 +2235,18 @@ postgresql 42.1.1 - + + + + org.apache.tinkerpop @@ -2154,35 +2265,39 @@ commons-validator 1.4.0 - + + + - + org.eclipse.jgit org.eclipse.jgit 4.8.0.201706111038-r + - + - + + org.kohsuke @@ -2195,7 +2310,8 @@ 2.1.5 - + + + + com.cloudera impala4 @@ -2228,7 +2345,8 @@ - + + + + + + + + - + + + + + + org.json + json + 20160810 com.fasterxml.jackson.core @@ -2287,7 +2420,7 @@ com.fasterxml.jackson.core jackson-annotations 2.9.0 - + com.amazon.redshift redshift-jdbc41 @@ -2299,12 +2432,13 @@ j2v8_win32_x86_64 4.4.0 + - + com.corundumstudio.socketio @@ -2312,16 +2446,18 @@ 1.7.12 - + + + + black.ninia jep @@ -2338,16 +2474,21 @@ json-flattener 0.4.1 - - org.xerial - sqlite-jdbc - 3.14.2 - + + org.xerial + sqlite-jdbc + 3.14.2 + com.jayway.jsonpath json-path 2.3.0 + + net.minidev + json-smart + 1.0.9 + io.burt jmespath-jackson @@ -2359,11 +2500,12 @@ google-api-services-sheets v4-rev506-1.23.0 - + + com.google.apis google-api-services-drive @@ -2390,6 +2532,11 @@ jsoup 1.11.3 - + + + au.com.bytecode + opencsv + 2.4 + \ No newline at end of file From a29727e7ef0ab5be7c8ded36ccce1bea1abae74b Mon Sep 17 00:00:00 2001 From: tbanach Date: Thu, 7 Jun 2018 18:40:36 +0000 Subject: [PATCH 0074/1906] REQUIREMENT ::: Maven update Semoss and Monolith. UPDATE ::: Removing Spark altogether (commenting out in code and in pom.xml). git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28595 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 5708fd325a5cff866fea7bf16a9502b241adcdc3 --- pom.xml | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index fdd6cd7b6..945f47fa1 100644 --- a/pom.xml +++ b/pom.xml @@ -2072,18 +2072,20 @@ + - + + - + + + org.jodd + jodd-core + 3.6.2 + \ No newline at end of file From 36368ce31acee94019dfb007f186d9389f121990 Mon Sep 17 00:00:00 2001 From: tbanach Date: Thu, 7 Jun 2018 19:09:23 +0000 Subject: [PATCH 0075/1906] REQUIREMENT ::: Maven update Semoss and Monolith. UPDATE ::: Removing Kafka and Storm dependencies. Had to add a Guava jar that was a transient dependency of Storm. git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28597 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: ad0387c5df5bd28912fed7190296719a55943073 --- pom.xml | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 945f47fa1..82e2e0415 100644 --- a/pom.xml +++ b/pom.xml @@ -644,6 +644,12 @@ + + + com.google.guava + guava-collections + r03 + com.github.spullara.mustache.java compiler @@ -2190,11 +2196,12 @@ 3.8.1 test - + + + org.mariadb.jdbc From b2934ec50987348cfe38a74e9c12adb1c6dc87f7 Mon Sep 17 00:00:00 2001 From: tbanach Date: Thu, 7 Jun 2018 21:05:44 +0000 Subject: [PATCH 0076/1906] REQUIREMENT ::: Maven update Semoss and Monolith BUGFIX ::: Re-added RDF runtime dependency & restored logging using Storm (will need to find a lighter library for this) git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28604 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 2b8a3080fb8c6c2da498acd4d60a2320fcbb0c9a --- pom.xml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 82e2e0415..5567f05b0 100644 --- a/pom.xml +++ b/pom.xml @@ -2196,12 +2196,11 @@ 3.8.1 test - - + + + org.cliffc.high_scale_lib.wso2 + high-scale-lib + 1.1.2.wso2v1 + \ No newline at end of file From 46eb82e7256eccc1870593cb20191187487f9760 Mon Sep 17 00:00:00 2001 From: tbanach Date: Thu, 7 Jun 2018 21:22:46 +0000 Subject: [PATCH 0077/1906] REQUIREMENT ::: Maven update BUGFIX ::: Added repository URL for RDF runtime dependency git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28605 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 95a63885a82a78d3f1fab0b9c6badbbe04783048 --- pom.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pom.xml b/pom.xml index 5567f05b0..8cc865784 100644 --- a/pom.xml +++ b/pom.xml @@ -95,6 +95,10 @@ redshift http://redshift-maven-repository.s3-website-us-east-1.amazonaws.com/release + + high-scale-lib + http://dist.wso2.org/maven2/ + From d2c7560acc773e3a4badf34d2094a53e237db8fd Mon Sep 17 00:00:00 2001 From: tbanach Date: Fri, 8 Jun 2018 14:08:51 +0000 Subject: [PATCH 0078/1906] REQUIREMENT ::: Maven update BUGFIX ::: Reverting pom changes until I can test out the runtime deps more fully (RDF dbs were having some problems). git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28610 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 4c9388822365d65cb6ca1c969afa0896f3617278 --- pom.xml | 646 +++++++++++++++++++++----------------------------------- 1 file changed, 237 insertions(+), 409 deletions(-) diff --git a/pom.xml b/pom.xml index 8cc865784..8ce53f7c5 100644 --- a/pom.xml +++ b/pom.xml @@ -95,10 +95,6 @@ redshift http://redshift-maven-repository.s3-website-us-east-1.amazonaws.com/release - - high-scale-lib - http://dist.wso2.org/maven2/ - @@ -124,8 +120,7 @@ - - + com.blazegraph bigdata @@ -147,8 +142,7 @@ - - + org.apache.commons commons-collections4 @@ -214,16 +208,6 @@ - - commons-collections - commons-collections - 3.2.1 - - - commons-beanutils - commons-beanutils - 1.9.2 - org.apache.commons commons-dbcp2 @@ -334,8 +318,7 @@ - - - - - - - - + com.google.apis google-api-services-oauth2 @@ -404,8 +384,7 @@ - - - - + com.google.oauth-client google-oauth-client @@ -439,8 +417,7 @@ - - - - - - - - - - - - - - + org.apache.tinkerpop tinkergraph-gremlin @@ -589,8 +560,7 @@ - - + org.codehaus.groovy groovy-jsr223 @@ -613,8 +583,7 @@ - - + com.google.code.gson gson @@ -648,12 +617,6 @@ - - - com.google.guava - guava-collections - r03 - com.github.spullara.mustache.java compiler @@ -670,8 +633,7 @@ - - - - + org.apache.httpcomponents httpclient @@ -705,8 +666,7 @@ - - - - + org.apache.httpcomponents httpcore @@ -740,8 +699,7 @@ - - + com.ibm.icu icu4j @@ -763,8 +721,7 @@ - - + com.itextpdf itextpdf @@ -786,8 +743,7 @@ - - - - - - + org.javatuples javatuples @@ -844,8 +798,7 @@ - - - - - - + redis.clients jedis @@ -913,8 +864,7 @@ - - + org.apache.jena jena-larq @@ -936,8 +886,7 @@ - - - - + org.python @@ -983,8 +931,7 @@ - - + org.jgrapht jgrapht-core @@ -1028,8 +975,7 @@ - - - - - - - - + org.jsoup jsoup @@ -1098,8 +1041,7 @@ - - + net.sf.jung jung-algorithms @@ -1154,8 +1096,7 @@ - - + log4j log4j @@ -1188,8 +1129,7 @@ - - + org.apache.lucene lucene-core @@ -1244,8 +1184,7 @@ - - + mysql mysql-connector-java @@ -1267,8 +1206,7 @@ - - - - - - - - + com.oracle ojdbc6 @@ -1348,8 +1283,7 @@ - - - - + org.jboss.resteasy resteasy-jaxrs @@ -1416,8 +1349,7 @@ - - - - - - - - - - - - - - - - - - + org.apache.solr solr-core 4.7.0 - + - - - - - - - - - - - - + org.apache.solr solr-solrj 4.7.0 - + - - - - - - + edu.stanford.nlp stanford-corenlp @@ -1677,8 +1592,7 @@ - - + net.sf.supercsv super-csv @@ -1722,8 +1636,7 @@ - - + com.github.dblock.waffle waffle-jna @@ -1772,8 +1685,7 @@ - - - - - - - - - - - - it.unimi.dsi - dsiutils - 2.4.2 - - + aurelionribon.ui css-engine-swing-api @@ -1860,8 +1762,7 @@ - - - - - - - - - - + com.teamdev.jxbrowser jxbrowser @@ -1931,8 +1828,7 @@ - - - - - - - - - - + org.rednoise rita @@ -2002,8 +1894,7 @@ - - + com.microsoft sqlserver @@ -2025,8 +1916,7 @@ - - + edu.cmu ws4j @@ -2082,41 +1972,36 @@ - - - + - + - - + - - + - - + org.scala-lang @@ -2124,12 +2009,11 @@ 2.11.7 - - + org.apache.hadoop @@ -2137,12 +2021,11 @@ 2.6.0 - - + org.javassist @@ -2180,37 +2063,33 @@ extjwnl 1.9.2 - - - - + - - + org.apache.storm storm-core 1.0.2 - - + org.quartz-scheduler quartz @@ -2226,12 +2105,11 @@ mail 1.4 - - + org.mariadb.jdbc @@ -2248,18 +2126,16 @@ postgresql 42.1.1 - - - - + org.apache.tinkerpop @@ -2278,39 +2154,35 @@ commons-validator 1.4.0 - - - + - + org.eclipse.jgit org.eclipse.jgit 4.8.0.201706111038-r - - + - - + org.kohsuke @@ -2323,8 +2195,7 @@ 2.1.5 - - - - + com.cloudera impala4 @@ -2358,8 +2228,7 @@ - - - - - - - - + - - - - - - org.json - json - 20160810 com.fasterxml.jackson.core @@ -2433,7 +2287,7 @@ com.fasterxml.jackson.core jackson-annotations 2.9.0 - + com.amazon.redshift redshift-jdbc41 @@ -2445,13 +2299,12 @@ j2v8_win32_x86_64 4.4.0 - - + com.corundumstudio.socketio @@ -2459,18 +2312,16 @@ 1.7.12 - - - - + black.ninia jep @@ -2487,21 +2338,16 @@ json-flattener 0.4.1 - - org.xerial - sqlite-jdbc - 3.14.2 - + + org.xerial + sqlite-jdbc + 3.14.2 + com.jayway.jsonpath json-path 2.3.0 - - net.minidev - json-smart - 1.0.9 - io.burt jmespath-jackson @@ -2513,12 +2359,11 @@ google-api-services-sheets v4-rev506-1.23.0 - - + com.google.apis google-api-services-drive @@ -2545,23 +2390,6 @@ jsoup 1.11.3 - - - au.com.bytecode - opencsv - 2.4 - - - - org.jodd - jodd-core - 3.6.2 - - - - org.cliffc.high_scale_lib.wso2 - high-scale-lib - 1.1.2.wso2v1 - + \ No newline at end of file From 31cb0399743021c91193939832658c032ac00ef2 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 12 Jun 2018 11:16:20 +0000 Subject: [PATCH 0079/1906] UPDATE ::: Removing unused social properties. Relocated to semoss git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28640 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 3fd3ec2322c29485a16a5eb65b1b5f887751b51a --- social - Copy.properties | 49 ---------------------------------------- 1 file changed, 49 deletions(-) delete mode 100644 social - Copy.properties diff --git a/social - Copy.properties b/social - Copy.properties deleted file mode 100644 index ce8a3d151..000000000 --- a/social - Copy.properties +++ /dev/null @@ -1,49 +0,0 @@ -ms_authority https://login.microsoftonline.com/ -ms_tenant umweltoutlook.onmicrosoft.com -ms_client_id 88dd3ada-bde3-40f4-bdfd-ffafee14eb2d -ms_secret_key tnowmSRJG3995+[rpAAU1)} -ms_redirect_uri https://localhost:8443/Monolith/api/auth/login/ms -ms_scope User.Read.All People.Read.All Notes.ReadWrite.All Files.ReadWrite.All Mail.ReadWrite - - -git_client_id fa7d7e87dadda8f81010 -git_secret_key f643133c41bd828135b8783a5349f1a11e58ccca -git_redirect_uri https://localhost:8443/Monolith/api/auth/login/git -git_scope public_repo - -sf_client_id 3MVG9VmVOCGHKYBTBlNb_0gK2dzXQyp8BCpaRlwliCFRAOAyShcFh24TGLeVpJbw9cwshq378TZsXwCz9tjxZ -sf_secret_key 8073418897645717308 -sf_redirect_uri https://localhost:8443/Monolith/api/auth/login/sf - -dropbox_client_id nfqtet2kz9joqaa -dropbox_secret_key n6113ralaix4n4r -dropbox_role personal -dropbox_redirect_uri https://localhost:8443/Monolith/api/auth/login/dropbox - - -google_client_id 240368406693-g7985bej47c10fikkgr6ous6hpm95cbb.apps.googleusercontent.com -google_secret_key kEOyUUeWrOhvfmJ2PrsPB6SS -google_redirect_uri https://localhost:8443/Monolith/api/auth/login/google2 -google_scope https://www.googleapis.com/auth/forms https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/drive.metadata https://www.googleapis.com/auth/cloud-language -google_access_type online -google_maps_api ***REMOVED*** - -twitter_client_id ***REMOVED*** -twitter_secret_key ***REMOVED*** -twitter_redirect_uri https://localhost:8443/Monolith/api/auth/login/twitter - -in_client_id 77tg7s1lxx8mbh -in_secret_key eLCa8WsXquU8sPbl -in_redirect_uri https://localhost:8443/Monolith/api/auth/login/linkedin -in_scope r_network - - -producthunt_client_id 4d28e19836d50033c9329c55f30886f3f6e992e69732a2e48d80ad0d86466449 -producthunt_secret_key 88e5626b525eed525dc85b69c2c28f2a3476b54785c1f1106ef960f90617690a -producthunt_redirect_uri https://localhost:8443/Monolith/api/auth/login/producthunt -producthunt_scope public - -census_client_id d26315559398d855100a32a0ab1bfde2962d0cce - - - From e394bbcb5661d326d98cc06bd5247ed59eecee0e Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 12 Jun 2018 16:35:50 +0000 Subject: [PATCH 0080/1906] UPDATE ::: Deleting user object and replacing with just user2 git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28647 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: a9643a573ccdd4e5eb7bbd8789deac67748adea1 --- .../insights/admin/DBAdminResource.java | 377 ---- src/prerna/insights/admin/QuestionAdmin.java | 354 ---- .../web/services/AuthorizationResource.java | 428 ++-- .../semoss/web/services/EngineResource.java | 72 +- .../semoss/web/services/NameServer.java | 167 +- .../semoss/web/services/UserResource.java | 1731 ++++++----------- src/prerna/upload/DatabaseUploader.java | 46 +- src/prerna/web/conf/CACFilter.java | 2 +- src/prerna/web/conf/UserDBFilter.java | 22 +- src/prerna/web/conf/UserDBInsightFilter.java | 55 +- src/prerna/web/conf/UserSessionLoader.java | 34 +- 11 files changed, 902 insertions(+), 2386 deletions(-) delete mode 100644 src/prerna/insights/admin/QuestionAdmin.java diff --git a/src/prerna/insights/admin/DBAdminResource.java b/src/prerna/insights/admin/DBAdminResource.java index f7af4d4ca..85215ff02 100644 --- a/src/prerna/insights/admin/DBAdminResource.java +++ b/src/prerna/insights/admin/DBAdminResource.java @@ -28,52 +28,22 @@ package prerna.insights.admin; import java.io.File; -import java.io.FileInputStream; import java.io.FileWriter; import java.io.IOException; -import java.security.KeyManagementException; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; import java.util.ArrayList; -import java.util.HashMap; -import java.util.Hashtable; import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.Vector; import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; import javax.ws.rs.POST; import javax.ws.rs.Path; -import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.Context; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; -import javax.ws.rs.core.StreamingOutput; import org.apache.log4j.Logger; -import org.apache.solr.client.solrj.SolrServerException; -import org.apache.solr.common.SolrDocumentList; -import com.google.gson.Gson; -import com.google.gson.reflect.TypeToken; - -import prerna.auth.User; -import prerna.auth.UserPermissionsMasterDB; -import prerna.cache.CacheFactory; -import prerna.engine.api.IEngine; -import prerna.engine.impl.AbstractEngine; -import prerna.engine.impl.InsightAdministrator; -import prerna.nameserver.DeleteFromMasterDB; -import prerna.om.Insight; import prerna.rpa.RPAProps; -import prerna.solr.SolrDocumentExportWriter; -import prerna.solr.SolrIndexEngine; -import prerna.util.Constants; -import prerna.util.DIHelper; -import prerna.util.Utility; import prerna.web.services.util.WebUtility; public class DBAdminResource { @@ -154,351 +124,4 @@ public Response listJobs(MultivaluedMap form, @Context HttpServl } return WebUtility.getResponse(jobNames, 200); } - - // TODO delete - /* - @POST - @Path("/quartz") - @Produces("application/json") - public void scheduleJob(MultivaluedMap form, @Context HttpServletRequest request) { - String json = form.getFirst("json"); - final String baseFolder = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER); - Date date = new Date(); - String stringDate = date.toString(); - stringDate = stringDate.replaceAll("\\s+", "_").replaceAll(":", "_"); - try (FileWriter file = new FileWriter(baseFolder + "\\quartz\\job_" + stringDate + ".json")) { - file.write(json); - System.out.println("Successfully Copied JSON Object to File..."); - System.out.println("JSON Object: " + json); - } catch (IOException e) { - e.printStackTrace(); - } - } - */ - - @POST - @Path("/delete") - @Produces("application/json") - public Object delete(MultivaluedMap form, @Context HttpServletRequest request) { - Gson gson = new Gson(); - - String enginesString = form.getFirst("engines"); -// String perspectivesString = form.getFirst("perspectives"); - String questionsString = form.getFirst("insightIds"); - - List questionIds = null; - if (questionsString != null) { - questionIds = gson.fromJson(questionsString, List.class); - AbstractEngine engine = getEngine(enginesString, request); - InsightAdministrator admin = new InsightAdministrator(engine.getInsightDatabase()); - try { - admin.dropInsight(questionIds.toArray(new String[questionIds.size()])); - questionIds = SolrIndexEngine.getSolrIdFromInsightEngineId(engine.getEngineId(), questionIds); - } catch (RuntimeException e) { - // reload question xml from file if it errored - // otherwise xml gets corrupted - System.out.println("caught exception while deleting questions................."); - e.printStackTrace(); -// return Response.status(500).entity(WebUtility.getSO(e.toString().substring(0, -// (e.toString().length() < MAX_CHAR) ? e.toString().length() : MAX_CHAR))).build(); - return WebUtility.getResponse(e.toString().substring(0, - (e.toString().length() < MAX_CHAR) ? e.toString().length() : MAX_CHAR), 500); - } -// } else if (perspectivesString != null) { -// AbstractEngine engine = getEngine(enginesString, request); -// QuestionAdministrator questionAdmin = new QuestionAdministrator(engine); -// try { -// Vector perspectives = gson.fromJson(perspectivesString, Vector.class); -// questionIds = questionAdmin.removePerspective(perspectives.toArray(new String[perspectives.size()])); -// questionIds = SolrIndexEngine.getSolrIdFromInsightEngineId(engine.getEngineName(), questionIds); -// -// } catch (RuntimeException e) { -// // reload question xml from file if it errored -// // otherwise xml gets corrupted -// System.out.println("caught exception while deleting perspectives................."); -// e.printStackTrace(); -//// return Response.status(500).entity(WebUtility.getSO(e.toString().substring(0, -//// (e.toString().length() < MAX_CHAR) ? e.toString().length() : MAX_CHAR))).build(); -// -// return WebUtility.getResponse(e.toString().substring(0, -// (e.toString().length() < MAX_CHAR) ? e.toString().length() : MAX_CHAR), 500); -// } - - } else if (enginesString != null) { - Vector engines = gson.fromJson(enginesString, Vector.class); - UserPermissionsMasterDB permissions = new UserPermissionsMasterDB(); - ArrayList ownedEngines = permissions - .getUserOwnedEngines(((User) request.getSession().getAttribute(Constants.SESSION_USER)).getId()); - for (String engineString : engines) { - IEngine engine = getEngine(engineString, request); - if (this.securityEnabled) { - if (ownedEngines.contains(engineString)) { - deleteEngine(engine, request); - permissions.deleteEngine( - ((User) request.getSession().getAttribute(Constants.SESSION_USER)).getId(), - engineString); - } else { -// return Response.status(400).entity("You do not have access to delete this database.").build(); - return WebUtility.getResponse("You do not have access to delete this database.", 400); - } - } else { - deleteEngine(engine, request); - } - } - } - - if (questionIds != null) { - SolrIndexEngine solrE; - try { - solrE = SolrIndexEngine.getInstance(); - if (solrE.serverActive()) { - solrE.removeInsight(questionIds); - } - } catch (SolrServerException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } catch (KeyManagementException e) { - e.printStackTrace(); - } catch (NoSuchAlgorithmException e) { - e.printStackTrace(); - } catch (KeyStoreException e) { - e.printStackTrace(); - } - } -// return Response.status(200).entity(WebUtility.getSO("success")).build(); - return WebUtility.getResponse("success", 200); - } - -// @POST -// @Path("reorderPerspective") -// @Produces("application/json") -// public Response reorderPerspective(MultivaluedMap form, @Context HttpServletRequest request) { -// Gson gson = new Gson(); -// String perspective = form.getFirst("perspective"); -// String enginesString = form.getFirst("engine"); -// String insightsString = form.getFirst("insights"); -// List questionIds = gson.fromJson(insightsString, List.class); -// -// AbstractEngine engine = getEngine(enginesString, request); -// QuestionAdministrator questionAdmin = new QuestionAdministrator(engine); -// try { -// questionAdmin.reorderPerspective(perspective, questionIds); -// } catch (RuntimeException e) { -// -// System.out.println("caught exception while reordering................."); -// e.printStackTrace(); -// -// String errorMessage = e.toString().substring(0, (e.toString().length() < MAX_CHAR) ? e.toString().length() : MAX_CHAR); -//// return Response.status(500).entity(WebUtility.getSO( -//// e.toString().substring(0, (e.toString().length() < MAX_CHAR) ? e.toString().length() : MAX_CHAR))) -//// .build(); -// -// return WebUtility.getResponse(errorMessage, 500); -// } -// -//// return Response.status(200).entity(WebUtility.getSO("Success")).build(); -// return WebUtility.getResponse("success", 200); -// } - - @Path("insight-{engine}") - public Object insight(@PathParam("engine") String engineString, @Context HttpServletRequest request) { - AbstractEngine engine = getEngine(engineString, request); - QuestionAdmin admin = new QuestionAdmin(engine); - return admin; - } - - private boolean deleteEngine(IEngine coreEngine, HttpServletRequest request) { - String engineName = coreEngine.getEngineId(); - coreEngine.deleteDB(); - // remove from session - HttpSession session = request.getSession(); - ArrayList> engines = (ArrayList>) session - .getAttribute(Constants.ENGINES); - for (Hashtable engine : engines) { - String engName = engine.get("name"); - if (engName.equals(engineName)) { - engines.remove(engine); - System.out.println("Removed from engines"); - session.setAttribute(Constants.ENGINES, engines); - break;// - } - } - session.removeAttribute(engineName); - - // remove from dihelper... this is absurd - String engineNames = (String) DIHelper.getInstance().getLocalProp(Constants.ENGINES); - engineNames = engineNames.replace(";" + engineName, ""); - DIHelper.getInstance().setLocalProperty(Constants.ENGINES, engineNames); - - DeleteFromMasterDB remover = new DeleteFromMasterDB(); - remover.deleteEngineRDBMS(engineName); - - SolrIndexEngine solrE; - try { - solrE = SolrIndexEngine.getInstance(); - if (solrE.serverActive()) { - solrE.deleteEngine(engineName); - } - } catch (KeyManagementException e) { - e.printStackTrace(); - } catch (NoSuchAlgorithmException e) { - e.printStackTrace(); - } catch (KeyStoreException e) { - e.printStackTrace(); - } - - return true; - } - - private AbstractEngine getEngine(String engineName, HttpServletRequest request) { - HttpSession session = request.getSession(); - AbstractEngine engine = null; - if (session.getAttribute(engineName) instanceof IEngine) - engine = (AbstractEngine) session.getAttribute(engineName); - else - engine = (AbstractEngine) Utility.getEngine(engineName); - return engine; - } - - @POST - @Path("/deleteCache") - @Produces("application/json") - public Response deleteDbCache(MultivaluedMap form, @Context HttpServletRequest request) { - String dbName = form.getFirst("engine"); - String insightID = form.getFirst("insightID"); - String questionName = form.getFirst("questionName"); - Insight in = new Insight(getEngine(dbName, request).getEngineId(), insightID); - in.setInsightName(questionName); - - CacheFactory.getInsightCache(CacheFactory.CACHE_TYPE.DB_INSIGHT_CACHE).deleteInsightCache(in); -// return Response.status(200).entity(WebUtility.getSO("Success")).build(); - return WebUtility.getResponse("success", 200); - } - - //////////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////////// - /////////////////////////////////// START SOLR - //////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////////// - - /** - * Modify the insight tags - * - * @return - */ - @POST - @Path("modifyInsightTags") - @Produces("application/json") - public StreamingOutput modifyInsightTags(MultivaluedMap form, @Context HttpServletRequest request) { - String solrId = form.getFirst("id"); - String tagsStr = form.getFirst("tags"); - - Gson gson = new Gson(); - List tags = gson.fromJson(tagsStr, new TypeToken>() { - }.getType()); - - Map fieldsToModify = new HashMap(); - fieldsToModify.put(SolrIndexEngine.TAGS, tags); - fieldsToModify.put(SolrIndexEngine.INDEXED_TAGS, tags); - - return WebUtility.getSO(modifyInsight(solrId, fieldsToModify)); - - } - - private String modifyInsight(String solrId, Map fieldsToModify) { - String returnMessage = null; - try { - SolrIndexEngine.getInstance().modifyInsight(solrId, fieldsToModify); - returnMessage = "success"; - } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException | SolrServerException - | IOException e) { - e.printStackTrace(); - returnMessage = e.getMessage(); - if (returnMessage == null || returnMessage.isEmpty()) { - returnMessage = "Unknown error with modifying tags"; - } - } - return returnMessage; - } - - @POST - @Path("exportDbSolrText") - @Produces("application/json") - public StreamingOutput exportDbSolrInfo(MultivaluedMap form, @Context HttpServletRequest request) { - String engineName = form.getFirst("engineName"); - LOGGER.info("Starting to export solr documents for engine : " + engineName); - // grab the smss file to determine where we should export this file - String smssFile = (String)DIHelper.getInstance().getCoreProp().getProperty(engineName + "_" + Constants.STORE); - // create this text file in the same location as the insight_database - // actual process to load - FileInputStream fis = null; - String message = "success"; - try { - Properties daProp = new Properties(); - fis = new FileInputStream(smssFile); - daProp.load(fis); - - // if there is already a text file that we need to update - // get the existing file from the smss - String solrTextFile = null; - String smssUpdateValue = null; - boolean overrideExistingSolrFile = false; - if(daProp.containsKey(Constants.SOLR_EXPORT)) { - overrideExistingSolrFile = true; - solrTextFile = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER) - + "/" + daProp.getProperty(Constants.SOLR_EXPORT); - } else { - // get the location of the insight rdbms and modify it for a new file - smssUpdateValue = daProp.getProperty(Constants.RDBMS_INSIGHTS); - // get ride of the file name to get the extension - smssUpdateValue = smssUpdateValue.substring(0, smssUpdateValue.lastIndexOf("/")+1); - // add a new extension - smssUpdateValue = smssUpdateValue + engineName + "_Solr.txt"; - - solrTextFile = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER) - + "/" + smssUpdateValue; - } - File solrFile = new File(solrTextFile); - if(solrFile.exists()) { - solrFile.delete(); - } - - SolrDocumentExportWriter writer = new SolrDocumentExportWriter(solrFile); - SolrDocumentList docs = SolrIndexEngine.getInstance().getEngineInsights(engineName); - LOGGER.info("Found " + docs.getNumFound() + " documents to export"); - writer.writeSolrDocument(docs); - writer.closeExport(); - - // update the smss to know this solr text file exists - if(!overrideExistingSolrFile) { - Utility.updateSMSSFile(smssFile, Constants.SOLR_EXPORT, smssUpdateValue); - } - } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException | - IOException | SolrServerException e) { - e.printStackTrace(); - message = e.getMessage(); - if(message == null || message.isEmpty()) { - message = "Unknown error occured while exporting solr information"; - } - } finally { - if(fis != null) { - try { - fis.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - - return WebUtility.getSO(message); - } - - //////////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////// END SOLR ////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////////// } diff --git a/src/prerna/insights/admin/QuestionAdmin.java b/src/prerna/insights/admin/QuestionAdmin.java deleted file mode 100644 index db776fcc2..000000000 --- a/src/prerna/insights/admin/QuestionAdmin.java +++ /dev/null @@ -1,354 +0,0 @@ -/******************************************************************************* - * Copyright 2015 Defense Health Agency (DHA) - * - * If your use of this software does not include any GPLv2 components: - * Licensed 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. - * ---------------------------------------------------------------------------- - * If your use of this software includes any GPLv2 components: - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - *******************************************************************************/ -package prerna.insights.admin; - -import java.io.IOException; -import java.security.KeyManagementException; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.util.ArrayList; -import java.util.List; - -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.core.Context; -import javax.ws.rs.core.MultivaluedMap; -import javax.ws.rs.core.Response; - -import org.apache.solr.client.solrj.SolrServerException; - -import prerna.engine.impl.AbstractEngine; -import prerna.engine.impl.InsightAdministrator; -import prerna.solr.SolrIndexEngine; -import prerna.web.services.util.WebUtility; - -public class QuestionAdmin { - -// private static final Logger LOGGER = Logger.getLogger(QuestionAdmin.class.getName()); -// private static Gson gson = new Gson(); - - private AbstractEngine coreEngine; - - @Deprecated - public QuestionAdmin(AbstractEngine coreEngine) { - this.coreEngine = coreEngine; - } - - @POST - @Path("delete") - @Produces("application/json") - @Deprecated - public Response deleteInsight(MultivaluedMap form, @Context HttpServletRequest request) { - String insightID = form.getFirst("insightID"); - InsightAdministrator admin = new InsightAdministrator(this.coreEngine.getInsightDatabase()); - admin.dropInsight(insightID); - - try { - List removeList = new ArrayList(); - removeList.add(coreEngine.getEngineId() + "_" + insightID); - SolrIndexEngine.getInstance().removeInsight(removeList); - } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException | SolrServerException | IOException e) { - e.printStackTrace(); - } - return WebUtility.getResponse("Success", 200); - } - -// @POST -// @Path("addFromAction") -// @Produces("application/json") -// public Response addNewInsight(MultivaluedMap form, @Context HttpServletRequest request) { -// /* -// * FE passes the following keys -// * insightName - String - The name of the insight to save -// * layout - String - The final layout of the main panel -// * saveRecipe - Array - The pkql recipe that the user wants to save -// * description - String - The description describing the insight -// * tags - Array - The tags associated with the insight -// * url - String - The url that monolith is deployed as -// * runRecipe - Array - If the insight contains a parameter, we use these recipe steps to capture the image -// */ -// -// LOGGER.info("Adding new insight"); -// LOGGER.info("1) Add insight to insights engine"); -// -// String insightId = form.getFirst("insightID"); -// Insight in = InsightStore.getInstance().get(insightId); -// -// // grab the insight name -// String insightName = form.getFirst("insightName"); -// // grab the layout -// String layout = form.getFirst("layout"); -// // grab the recipe that we need to save -// String[] pkqlRecipeToSave = gson.fromJson(form.getFirst("saveRecipe"), String[].class); -// //TODO: get FE to fix this -// //TODO: get FE to fix this -// //TODO: get FE to fix this -// //TODO: get FE to fix this -//// if(!(in.getDataMaker() instanceof Dashboard)) { -//// pkqlRecipeToSave = fixCauseFeDumb(pkqlRecipeToSave); -//// } else { -// pkqlRecipeToSave = otherFixCauseFeDumb(pkqlRecipeToSave); -//// } -// -// // add the recipe to the insights database -// InsightAdministrator admin = new InsightAdministrator(this.coreEngine.getInsightDatabase()); -// String newRdbmsId = admin.addInsight(insightName, layout, pkqlRecipeToSave); -// LOGGER.info("1) Done"); -// -// LOGGER.info("2) Add insight to solr"); -// // now add it to solr -// // get the description -// String description = form.getFirst("description"); -// // get the tags -// String tagsString = form.getFirst("tags"); -// List tags = new Vector(); -// if (tagsString != null && !tagsString.isEmpty()) { -// tags = gson.fromJson(tagsString, new TypeToken>() {}.getType()); -// } -// // get the user id -// String userId = getUserId(request); -// addNewInsightToSolr(newRdbmsId, insightName, layout, description, tags, userId); -// LOGGER.info("2) Done"); -// -// // since we process the image on the BE -// // we need to start a new thread that will go ahead and save the image for the insight -// LOGGER.info("3) Starting new thread to add insgiht image"); -// String url = form.getFirst("url"); -// String[] runRecipe = gson.fromJson(form.getFirst("runRecipe"), String[].class); -// //TODO: get FE to fix this -// //TODO: get FE to fix this -// //TODO: get FE to fix this -// //TODO: get FE to fix this -//// if(!(in.getDataMaker() instanceof Dashboard)) { -//// pkqlRecipeToSave = fixCauseFeDumb(pkqlRecipeToSave); -//// } else { -// pkqlRecipeToSave = otherFixCauseFeDumb(pkqlRecipeToSave); -//// } -// -// LOGGER.info("3) Done - thread will be running async"); -// LOGGER.info("Done adding new insight"); -// -// Map retMap = new HashMap(); -// retMap.put("core_engine", this.coreEngine.getEngineName()); -// retMap.put("core_engine_id", newRdbmsId); -// retMap.put("insightName", insightName); -// if (newRdbmsId != null) { -// return WebUtility.getResponse(retMap, 200); -// } else { -// return WebUtility.getResponse("Error adding insight", 500); -// } -// } -// -// /** -// * Add metadata around the insight into solr for searching -// * @param insightIdToSave -// * @param insightName -// * @param layout -// * @param description -// * @param tags -// * @param userId -// */ -// private void addNewInsightToSolr(String insightIdToSave, String insightName, String layout, String description, List tags, String userId) { -// Map solrInsights = new HashMap<>(); -// DateFormat dateFormat = SolrIndexEngine.getDateFormat(); -// Date date = new Date(); -// String currDate = dateFormat.format(date); -// solrInsights.put(SolrIndexEngine.STORAGE_NAME, insightName); -// solrInsights.put(SolrIndexEngine.TAGS, tags); -// solrInsights.put(SolrIndexEngine.LAYOUT, layout); -// solrInsights.put(SolrIndexEngine.CREATED_ON, currDate); -// solrInsights.put(SolrIndexEngine.MODIFIED_ON, currDate); -// solrInsights.put(SolrIndexEngine.LAST_VIEWED_ON, currDate); -// solrInsights.put(SolrIndexEngine.DESCRIPTION, description); -// solrInsights.put(SolrIndexEngine.CORE_ENGINE_ID, Integer.parseInt(insightIdToSave)); -// solrInsights.put(SolrIndexEngine.USER_ID, userId); -// -// // TODO: figure out which engines are used within this insight -// String engineName = this.coreEngine.getEngineName(); -// solrInsights.put(SolrIndexEngine.CORE_ENGINE, this.coreEngine.getEngineName()); -// solrInsights.put(SolrIndexEngine.ENGINES, new HashSet().add(engineName)); -// -// try { -// SolrIndexEngine.getInstance().addInsight(engineName + "_" + insightIdToSave, solrInsights); -// } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException | SolrServerException | IOException e1) { -// e1.printStackTrace(); -// } -// } -// -// /** -// * Get the user id from the request or return "default" -// * @param request -// * @return -// */ -// private String getUserId(HttpServletRequest request) { -// HttpSession session = request.getSession(true); -// User user = ((User) session.getAttribute(Constants.SESSION_USER)); -// String userId = null; -// if(user!= null) { -// userId = user.getId(); -// } else { -// userId = "default"; -// } -// return userId; -// } -// -// @POST -// @Path("editFromAction") -// @Produces("application/json") -// public Response editInsight(MultivaluedMap form, @Context HttpServletRequest request) { -// /* -// * FE passes the following keys -// * insightId - String - the insight id for the in-memory insight -// * insightName - String - The name of the insight to save -// * layout - String - The final layout of the main panel -// * saveRecipe - Array - The pkql recipe that the user wants to save -// * description - String - The description describing the insight -// * tags - Array - The tags associated with the insight -// * url - String - The url that monolith is deployed as -// * runRecipe - Array - If the insight contains a parameter, we use these recipe steps to capture the image -// */ -// -// LOGGER.info("Updating existing insight"); -// LOGGER.info("1) Update insight in insights engine"); -// -// String insightId = form.getFirst("insightID"); -// Insight in = InsightStore.getInstance().get(insightId); -// String existingRdbmsId = in.getRdbmsId(); -// -// // grab the insight name -// String insightName = form.getFirst("insightName"); -// // grab the layout -// String layout = form.getFirst("layout"); -// // grab the recipe that we need to save -// String[] pkqlRecipeToSave = gson.fromJson(form.getFirst("saveRecipe"), String[].class); -// //TODO: get FE to fix this -// //TODO: get FE to fix this -// //TODO: get FE to fix this -// //TODO: get FE to fix this -//// if(!(in.getDataMaker() instanceof Dashboard)) { -//// pkqlRecipeToSave = fixCauseFeDumb(pkqlRecipeToSave); -//// } else { -// pkqlRecipeToSave = otherFixCauseFeDumb(pkqlRecipeToSave); -//// } -// -// // add the recipe to the insights database -// InsightAdministrator admin = new InsightAdministrator(this.coreEngine.getInsightDatabase()); -// admin.updateInsight(existingRdbmsId, insightName, layout, pkqlRecipeToSave); -// LOGGER.info("1) Done"); -// -// LOGGER.info("2) Add insight to solr"); -// // now add it to solr -// // get the description -// String description = form.getFirst("description"); -// // get the tags -// String tagsString = form.getFirst("tags"); -// List tags = new Vector(); -// if (tagsString != null && !tagsString.isEmpty()) { -// tags = gson.fromJson(tagsString, new TypeToken>() {}.getType()); -// } -// // get the user id -// String userId = getUserId(request); -// editExistingInsightInSolr(existingRdbmsId, insightName, layout, description, tags, userId); -// LOGGER.info("2) Done"); -// -// // since we process the image on the BE -// // we need to start a new thread that will go ahead and save the image for the insight -// LOGGER.info("3) Starting new thread to add insgiht image"); -// String url = form.getFirst("url"); -// String[] runRecipe = gson.fromJson(form.getFirst("runRecipe"), String[].class); -// //TODO: get FE to fix this -// //TODO: get FE to fix this -// //TODO: get FE to fix this -// //TODO: get FE to fix this -//// if(!(in.getDataMaker() instanceof Dashboard)) { -//// pkqlRecipeToSave = fixCauseFeDumb(pkqlRecipeToSave); -//// } else { -// pkqlRecipeToSave = otherFixCauseFeDumb(pkqlRecipeToSave); -//// } -// -// LOGGER.info("3) Done - thread will be running async"); -// LOGGER.info("Done adding new insight"); -// -// Map retMap = new HashMap(); -// retMap.put("core_engine", this.coreEngine.getEngineName()); -// retMap.put("core_engine_id", existingRdbmsId); -// retMap.put("insightName", insightName); -// if (existingRdbmsId != null) { -// return WebUtility.getResponse(retMap, 200); -// } else { -// return WebUtility.getResponse("Error adding insight", 500); -// } -// } -// -// /** -// * Edit an existing insight saved within solr -// * @param existingRdbmsId -// * @param insightName -// * @param layout -// * @param description -// * @param tags -// * @param userId -// */ -// private void editExistingInsightInSolr(String existingRdbmsId, String insightName, String layout, String description, List tags, String userId) { -// Map solrModifyInsights = new HashMap<>(); -// DateFormat dateFormat = SolrIndexEngine.getDateFormat(); -// Date date = new Date(); -// String currDate = dateFormat.format(date); -// solrModifyInsights.put(SolrIndexEngine.STORAGE_NAME, insightName); -// solrModifyInsights.put(SolrIndexEngine.TAGS, tags); -// solrModifyInsights.put(SolrIndexEngine.DESCRIPTION, description); -// solrModifyInsights.put(SolrIndexEngine.LAYOUT, layout); -// solrModifyInsights.put(SolrIndexEngine.MODIFIED_ON, currDate); -// solrModifyInsights.put(SolrIndexEngine.LAST_VIEWED_ON, currDate); -// -// // TODO: figure out which engines are used within this insight -// String engineName = this.coreEngine.getEngineName(); -// solrModifyInsights.put(SolrIndexEngine.CORE_ENGINE, this.coreEngine.getEngineName()); -// solrModifyInsights.put(SolrIndexEngine.ENGINES, new HashSet().add(engineName)); -// -// try { -// SolrIndexEngine.getInstance().modifyInsight(engineName + "_" + existingRdbmsId, solrModifyInsights); -// } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException | SolrServerException | IOException e1) { -// e1.printStackTrace(); -// } -// } -// -// -// private String[] otherFixCauseFeDumb(String[] pixelRecipe) { -// List fixForFe = new Vector(); -// fixForFe.add("data.frame('dashboard');"); -// for(int i = 0; i < pixelRecipe.length; i++) { -// fixForFe.add(pixelRecipe[i]); -// } -// // edit the reference -// return fixForFe.toArray(new String[]{}); -// } - -} diff --git a/src/prerna/semoss/web/services/AuthorizationResource.java b/src/prerna/semoss/web/services/AuthorizationResource.java index bd6c3283d..e2e8083ee 100644 --- a/src/prerna/semoss/web/services/AuthorizationResource.java +++ b/src/prerna/semoss/web/services/AuthorizationResource.java @@ -27,9 +27,7 @@ *******************************************************************************/ package prerna.semoss.web.services; -import java.io.IOException; import java.util.ArrayList; -import java.util.Arrays; import java.util.HashMap; import java.util.Hashtable; import java.util.Map; @@ -51,13 +49,9 @@ import com.google.gson.internal.StringMap; import prerna.auth.AuthProvider; -import prerna.auth.EngineAccessRequest; -import prerna.auth.User; import prerna.auth.User2; import prerna.auth.UserPermissionsMasterDB; -import prerna.auth.EnginePermission; import prerna.util.Constants; -import prerna.util.DIHelper; import prerna.web.services.util.WebUtility; @Path("/authorization") @@ -79,121 +73,6 @@ public StreamingOutput isSecurityEnabled() { return WebUtility.getSO(securityEnabled); } - /** - * Returns a list of engines the currently logged in user can access on the DB Admin page. - */ - @GET - @Produces("application/json") - @Path("dbAdminEngines") - public StreamingOutput getDBAdminEngines(@Context HttpServletRequest request) throws IOException { - Hashtable>> ret = new Hashtable>>(); - ArrayList> allEngines = new ArrayList>((ArrayList>)request.getSession().getAttribute(Constants.ENGINES)); - - if(!Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED))) { - ret.put("engines", allEngines); - return WebUtility.getSO(ret); - } - - EnginePermission[] permissionsList = new EnginePermission[] { EnginePermission.OWNER }; - - ArrayList accessibleEngines = permissions.getEnginesForUserAndPermissions(((User) request.getSession().getAttribute(Constants.SESSION_USER)).getId(), permissionsList); - ArrayList> engines = new ArrayList>(); - - for(Hashtable eng : allEngines) { - if(accessibleEngines.contains(eng.get("name"))) { - engines.add(eng); - } - } - - ret.put("engines", engines); - return WebUtility.getSO(ret); - } - - @GET - @Produces("application/json") - @Path("getEngineAccessRequests") - public Response getEngineAccessRequestsForUser(@Context HttpServletRequest request) throws IOException { - Hashtable>> ret = new Hashtable>>(); - ArrayList> requests = new ArrayList>(); - Hashtable requestdetails; - - User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - if(user != null && !user.getId().equals(Constants.ANONYMOUS_USER_ID)) { - ArrayList reqs = permissions.getEngineAccessRequestsForUser(user.getId()); - ArrayList allPermissionsList = new ArrayList(); -// for(EnginePermission ep : EnginePermission.values()) { -// allPermissionsList.add(ep.getPermission()); -// } - allPermissionsList.add(EnginePermission.READ_ONLY.getPermission()); - for(EngineAccessRequest req : reqs) { - requestdetails = new Hashtable(); - requestdetails.put("requestId", req.getRequestId()); - requestdetails.put("engine", req.getEngineRequested()); - requestdetails.put("user", req.getUser()); - requestdetails.put("allpermissions", allPermissionsList); - requests.add(requestdetails); - } - } - - ret.put("requests", requests); -// return Response.status(200).entity(WebUtility.getSO(ret)).build(); - return WebUtility.getResponse(ret, 200); - } - - @GET - @Produces("application/json") - @Path("getEngineAccessRequestsByUser") - public StreamingOutput getEngineAccessRequestsByUser(@Context HttpServletRequest request) throws IOException { - ArrayList enginesRequested = new ArrayList(); - - User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - if(user != null && !user.getId().equals(Constants.ANONYMOUS_USER_ID)) { - enginesRequested = permissions.getEngineAccessRequestsByUser(user.getId()); - } - - return WebUtility.getSO(enginesRequested); - } - - @POST - @Produces("application/json") - @Path("addEngineAccessRequest") - public Response addEngineAccessRequest(@Context HttpServletRequest request, MultivaluedMap form) { - HashMap ret = new HashMap(); - String engineName = form.getFirst("engine"); - String userId = ((User) request.getSession().getAttribute(Constants.SESSION_USER)).getId(); - Boolean success = false; - String error = ""; - - if(userId != null && !userId.isEmpty() && userId.equals(Constants.ANONYMOUS_USER_ID)) { - error = "Must be logged in to request access."; - } else if(engineName == null || engineName.isEmpty()) { - error = "No database selected."; - } else { - success = permissions.addEngineAccessRequest(engineName, userId); - } - - ret.put("success", success); - ret.put("error", error); -// return Response.status(200).entity(WebUtility.getSO(ret)).build(); - return WebUtility.getResponse(ret, 200); - } - - @POST - @Produces("application/json") - @Path("processEngineAccessRequest") - public Response approveEngineAccessRequest(@Context HttpServletRequest request, MultivaluedMap form) { - Hashtable ret = new Hashtable(); - String requestId = form.getFirst("requestId"); -// ArrayList enginePermissions = gson.fromJson(form.getFirst("permissions"), ArrayList.class); - ArrayList enginePermissions = new ArrayList(); - enginePermissions.add(EnginePermission.READ_ONLY.getPermission()); - - boolean success = permissions.processEngineAccessRequest(requestId, ((User) request.getSession().getAttribute(Constants.SESSION_USER)).getId(), enginePermissions.toArray(new String[enginePermissions.size()])); - - ret.put("success", success); -// return Response.status(200).entity(WebUtility.getSO(ret)).build(); - return WebUtility.getResponse(ret, 200); - } /** * Get all the grous the user is part of. @@ -212,37 +91,17 @@ public Response getGroupsAndMembers(@Context HttpServletRequest request) { } User2 user = (User2) request.getSession().getAttribute("semoss_user"); - String userId = user.getAccessToken(AuthProvider.NATIVE.name()).getId(); + String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); ArrayList> ret = permissions.getGroupsAndMembersForUser(userId); return WebUtility.getResponse(ret, 200); } - @GET - @Produces("application/json")//DONE - @Path("getOwnedDatabases") - public StreamingOutput getOwnedDatabases(@Context HttpServletRequest request) { - ArrayList engines = permissions.getUserOwnedEngines(((User) request.getSession().getAttribute(Constants.SESSION_USER)).getId()); - - return WebUtility.getSO(engines); - } - @GET @Produces("application/json") - @Path("getAllPermissionsForDatabase")//DONE - public StreamingOutput getAllPermissionsForDatabase(@Context HttpServletRequest request, @QueryParam("database") String engineName) { - HashMap>> ret = new HashMap>>(); - ret = permissions.getAllPermissionsGrantedByEngine(((User) request.getSession().getAttribute(Constants.SESSION_USER)).getId(), engineName.trim()); - - return WebUtility.getSO(ret); - } - - @GET - @Produces("application/json")//DONE @Path("searchForUser") public StreamingOutput searchForUser(@Context HttpServletRequest request, @QueryParam("searchTerm") String searchTerm) { ArrayList> ret = permissions.searchForUser(searchTerm.trim()); - return WebUtility.getSO(ret); } @@ -265,7 +124,7 @@ public Response getDatabases(@Context HttpServletRequest request) { } try{ User2 user = (User2) request.getSession().getAttribute("semoss_user"); - String userId = user.getAccessToken(AuthProvider.NATIVE.name()).getId(); + String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); ret = permissions.getUserDatabases(userId, false); return WebUtility.getResponse(ret, 200); } catch (IllegalArgumentException e){ @@ -292,7 +151,7 @@ public Response getAdminDatabases(@Context HttpServletRequest request) { ArrayList> ret = new ArrayList<>(); try{ User2 user = (User2) request.getSession().getAttribute("semoss_user"); - String userId = user.getAccessToken(AuthProvider.NATIVE.name()).getId(); + String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); ret = permissions.getUserDatabases(userId, true); return WebUtility.getResponse(ret, 200); } catch (IllegalArgumentException e){ @@ -319,7 +178,7 @@ public Response getAdminDatabaseUsersAndGroups(@Context HttpServletRequest reque StringMap>> ret = new StringMap<>(); try{ User2 user = (User2) request.getSession().getAttribute("semoss_user"); - String userId = user.getAccessToken(AuthProvider.NATIVE.name()).getId(); + String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); String engineId = form.getFirst("engineId"); ret = permissions.getDatabaseUsersAndGroups(userId, engineId, true); return WebUtility.getResponse(ret, 200); @@ -349,7 +208,7 @@ public Response getDatabaseUsersAndGroups(@Context HttpServletRequest request, M try{ String engineId = form.getFirst("engineId"); User2 user = (User2) request.getSession().getAttribute("semoss_user"); - String userId = user.getAccessToken(AuthProvider.NATIVE.name()).getId(); + String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); ret = permissions.getDatabaseUsersAndGroups(userId, engineId, false); return WebUtility.getResponse(ret, 200); } catch (IllegalArgumentException e){ @@ -363,15 +222,6 @@ public Response getDatabaseUsersAndGroups(@Context HttpServletRequest request, M } } - @GET - @Produces("application/json") - @Path("getAllDatabasesAndPermissions")//DONE - public StreamingOutput getAllDatabasesAndPermissions(@Context HttpServletRequest request) { - ArrayList> ret = permissions.getAllEnginesAndPermissionsForUser(((User) request.getSession().getAttribute(Constants.SESSION_USER)).getId()); - - return WebUtility.getSO(ret); - } - @POST @Produces("application/json") @Path("addGroup") @@ -379,7 +229,7 @@ public Response addNewGroup(@Context HttpServletRequest request, MultivaluedMap< Gson gson = new Gson(); ArrayList users = gson.fromJson(form.getFirst("users"), ArrayList.class); User2 user = (User2) request.getSession().getAttribute("semoss_user"); - String userId = user.getAccessToken(AuthProvider.NATIVE.name()).getId(); + String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); Boolean success = permissions.addGroup(userId, form.getFirst("groupName").trim(), users); if(success) { @@ -395,7 +245,7 @@ public Response addNewGroup(@Context HttpServletRequest request, MultivaluedMap< public Response removeGroup(@Context HttpServletRequest request, MultivaluedMap form) { String groupId = form.getFirst("groupId").trim(); User2 user = (User2) request.getSession().getAttribute("semoss_user"); - String userId = user.getAccessToken(AuthProvider.NATIVE.name()).getId(); + String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); Boolean success = permissions.removeGroup(userId, groupId); if(success) { @@ -416,7 +266,7 @@ public Response editGroup(@Context HttpServletRequest request, MultivaluedMap toRemove = gson.fromJson(form.getFirst("remove"), ArrayList.class); User2 user = (User2) request.getSession().getAttribute("semoss_user"); - String userId = user.getAccessToken(AuthProvider.NATIVE.name()).getId(); + String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); for(String add : toAdd) { permissions.addUserToGroup(userId, groupId, add); @@ -436,7 +286,7 @@ public Response savePermissions(@Context HttpServletRequest request, Multivalued Hashtable errorRet = new Hashtable(); try{ User2 user = (User2) request.getSession().getAttribute("semoss_user"); - String userId = user.getAccessToken(AuthProvider.NATIVE.name()).getId(); + String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); String engineId = form.getFirst("engineId").trim(); StringMap>> groups = gson.fromJson(form.getFirst("groups"), StringMap.class); StringMap>> users = gson.fromJson(form.getFirst("users"), StringMap.class); @@ -460,7 +310,7 @@ public Response isUserGroupAddedValid(@Context HttpServletRequest request, Multi Gson gson = new Gson(); try { User2 user = (User2) request.getSession().getAttribute("semoss_user"); - String userId = user.getAccessToken(AuthProvider.NATIVE.name()).getId(); + String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); String ret = "true"; userId = form.getFirst("userIdAdd").trim(); @@ -501,7 +351,7 @@ public Response isUserAddedToGroupValid(@Context HttpServletRequest request, Mul Gson gson = new Gson(); try { User2 user = (User2) request.getSession().getAttribute("semoss_user"); - String userId = user.getAccessToken(AuthProvider.NATIVE.name()).getId(); + String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); String ret = ""; String userIdAdd = form.getFirst("userIdAdd").trim(); @@ -523,67 +373,9 @@ public Response isUserAddedToGroupValid(@Context HttpServletRequest request, Mul @Produces("application/json") @Path("getInsightPermissions") public Response getInsightPermissions(@Context HttpServletRequest request, @QueryParam("database") String databaseName, @QueryParam("insight") String insightId) { -// return Response.status(200).entity(WebUtility.getSO(permissions.getUserPermissionsForInsight(databaseName, insightId))).build(); return WebUtility.getResponse(permissions.getUserPermissionsForInsight(databaseName, insightId), 200); } - @POST - @Produces("application/json") - @Path("saveInsightPermissions") - public Response saveInsightPermissions(@Context HttpServletRequest request, @QueryParam("userId") String userId, @QueryParam("database") String databaseName, @QueryParam("insight") String insightId) { - String loggedInUser = ((User) request.getSession().getAttribute(Constants.SESSION_USER)).getId(); - -// return Response.status(200).entity(WebUtility.getSO(permissions.addInsightPermissionsForUser(loggedInUser, userId, databaseName, insightId))).build(); - return WebUtility.getResponse(permissions.addInsightPermissionsForUser(loggedInUser, userId, databaseName, insightId), 200); - } - - @POST - @Produces("application/json") - @Path("removeInsightPermissions") - public Response removeInsightPermissions(@Context HttpServletRequest request, @QueryParam("userId") String userId, @QueryParam("database") String databaseName, @QueryParam("insight") String insightId) { - String loggedInUser = ((User) request.getSession().getAttribute(Constants.SESSION_USER)).getId(); - -// return Response.status(200).entity(WebUtility.getSO(permissions.removeInsightPermissionsForUser(loggedInUser, userId, databaseName, insightId))).build(); - return WebUtility.getResponse(permissions.removeInsightPermissionsForUser(loggedInUser, userId, databaseName, insightId), 200); - } - - //Seed and RLS Permissions - - @POST - @Produces("application/json") - @Path("/admin/saveSeed") - public void saveSeed(@Context HttpServletRequest request, MultivaluedMap form) { - String RLSValue = null; - String RLSJavaCode = null; - String userId = ((User) request.getSession().getAttribute(Constants.SESSION_USER)).getId(); - - if(form.getFirst("rlsValue") != null) { - RLSValue = form.getFirst("rlsValue"); - } else if(form.getFirst("rlsCustomPredicate") != null) { - RLSValue = form.getFirst("rlsCustomPredicate"); - } - - permissions.createSeed(form.getFirst("seedName"), form.getFirst("databaseName"), form.getFirst("tableName"), form.getFirst("columnName"), RLSValue, RLSJavaCode, userId); - } - - @POST - @Produces("application/json") - @Path("/admin/deleteSeed") - public void deleteSeed(@Context HttpServletRequest request, @QueryParam("seedName") String seedName) { - String userId = ((User) request.getSession().getAttribute(Constants.SESSION_USER)).getId(); - - permissions.deleteSeed(seedName, userId); - } - - @GET - @Produces("application/json") - @Path("/admin/getAllSeeds") - public Response getAllSeeds(@Context HttpServletRequest request) { - String userId = ((User) request.getSession().getAttribute(Constants.SESSION_USER)).getId(); - -// return Response.status(200).entity(WebUtility.getSO(permissions.getMetamodelSeedsForUser(userId, true))).build(); - return WebUtility.getResponse(permissions.getMetamodelSeedsForUser(userId, true), 200); - } @GET @Produces("application/json") @@ -593,25 +385,6 @@ public Response getAllSeedsForUser(@Context HttpServletRequest request, @QueryPa return WebUtility.getResponse(permissions.getMetamodelSeedsForUser(userId, false), 200); } - @POST - @Produces("application/json") - @Path("/admin/addSeedForUser") - public Response addSeedForUser(@Context HttpServletRequest request, @QueryParam("seedName") String seedName, @QueryParam("userId") String userId) { - String loggedInUser = ((User) request.getSession().getAttribute(Constants.SESSION_USER)).getId(); - -// return Response.status(200).entity(WebUtility.getSO(permissions.addUserToSeed(userId, seedName, loggedInUser))).build(); - return WebUtility.getResponse(permissions.addUserToSeed(userId, seedName, loggedInUser), 200); - } - - @POST - @Produces("application/json") - @Path("/admin/deleteSeedForUser") - public Response deleteSeedForUser(@Context HttpServletRequest request, @QueryParam("seedName") String seedName, @QueryParam("userId") String userId) { - String loggedInUser = ((User) request.getSession().getAttribute(Constants.SESSION_USER)).getId(); - -// return Response.status(200).entity(WebUtility.getSO(permissions.deleteUserFromSeed(userId, seedName, loggedInUser))).build(); - return WebUtility.getResponse(permissions.deleteUserFromSeed(userId, seedName, loggedInUser), 200); - } @GET @Path("/admin/isAdminUser") @@ -626,7 +399,7 @@ public Response isAdminUser(@Context HttpServletRequest request) { if(session.getAttribute("semoss_user") != null) { User2 user = (User2) request.getSession().getAttribute("semoss_user"); - String userId = user.getAccessToken(AuthProvider.NATIVE.name()).getId(); + String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); if(!userId.equals(Constants.ANONYMOUS_USER_ID) && permissions.isUserAdmin(userId)) { return WebUtility.getResponse(true, 200); } @@ -635,64 +408,6 @@ public Response isAdminUser(@Context HttpServletRequest request) { return WebUtility.getResponse(false, 200); } - @GET - @Path("/startTeamSession") - @Produces("application/json") - public Response startTeamSession(@Context HttpServletRequest request, @QueryParam("insightId") String insightId, @QueryParam("teamId") String teamId) { - StringMap retData = new StringMap(); - StringMap> teamShareMaps = new StringMap>(); - - //Get the existing team share mappings, if they exist - if(DIHelper.getInstance().getLocalProp("teamShareMaps") != null) { - teamShareMaps = (StringMap>) DIHelper.getInstance().getLocalProp("teamShareMaps"); - } - - if(teamShareMaps.containsKey(teamId)) { - retData.put("success", false); -// return Response.status(400).entity(WebUtility.getSO(retData)).build(); - return WebUtility.getResponse(retData, 200); - } else { - StringMap newTeamShareMap = new StringMap(); - newTeamShareMap.put("insightId", insightId); - newTeamShareMap.put("owner", ((User)request.getSession().getAttribute(Constants.SESSION_USER)).getId()); - teamShareMaps.put(teamId, newTeamShareMap); - } - DIHelper.getInstance().setLocalProperty("teamShareMaps", teamShareMaps); - - retData.put("success", true); -// return Response.status(200).entity(WebUtility.getSO(retData)).build(); - return WebUtility.getResponse(retData, 200); - } - - @GET - @Path("/endTeamSession") - @Produces("application/json") - public Response endTeamSession(@Context HttpServletRequest request, @QueryParam("teamId") String teamId) { - StringMap retData = new StringMap(); - String loggedInUser = ((User)request.getSession().getAttribute(Constants.SESSION_USER)).getId(); - StringMap> teamShareMaps = new StringMap>(); - - //Get the existing team share mappings, if they exist - if(DIHelper.getInstance().getLocalProp("teamShareMaps") != null) { - teamShareMaps = (StringMap>) DIHelper.getInstance().getLocalProp("teamShareMaps"); - } - - //If the map doesn't exist, or the teamId isn't in the map, or the logged in user isn't the owner of the team session, don't do anything - if(teamShareMaps == null || !teamShareMaps.containsKey(teamId) || !teamShareMaps.get(teamId).get("owner").equals(loggedInUser)) { - retData.put("success", false); -// return Response.status(400).entity(WebUtility.getSO(retData)).build(); - return WebUtility.getResponse(retData, 200); - } - - //Remove the team session information and replace the map in DIHelper - teamShareMaps.remove(teamId); - DIHelper.getInstance().setLocalProperty("teamShareMaps", teamShareMaps); - - retData.put("success", true); -// return Response.status(200).entity(WebUtility.getSO(retData)).build(); - return WebUtility.getResponse(retData, 200); - } - @GET @Path("/getAllDbUsers") @Produces("application/json") @@ -700,7 +415,7 @@ public Response getAllDbUsers(@Context HttpServletRequest request) { ArrayList> ret = new ArrayList<>(); Hashtable errorRet = new Hashtable(); User2 user = (User2) request.getSession().getAttribute("semoss_user"); - String userId = user.getAccessToken(AuthProvider.NATIVE.name()).getId(); + String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); try{ ret = permissions.getAllDbUsers(userId); } catch (IllegalArgumentException e){ @@ -720,7 +435,7 @@ public Response removeUserPermissionsbyDbId(@Context HttpServletRequest request, boolean ret = false; Hashtable errorRet = new Hashtable(); User2 user = (User2) request.getSession().getAttribute("semoss_user"); - String userId = user.getAccessToken(AuthProvider.NATIVE.name()).getId(); + String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); String engineId = form.getFirst("engineId"); try{ ret = permissions.removeUserPermissionsbyDbId(userId, engineId); @@ -749,7 +464,7 @@ public Response editUser(@Context HttpServletRequest request, MultivaluedMap errorRet = new Hashtable(); try{ User2 user = (User2) request.getSession().getAttribute("semoss_user"); - String userId = user.getAccessToken(AuthProvider.NATIVE.name()).getId(); + String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); StringMap userInfo = gson.fromJson(form.getFirst("user"), StringMap.class); ret = permissions.editUser(userId, userInfo); } catch (IllegalArgumentException e){ @@ -773,7 +488,7 @@ public Response savePermissionsAdmin(@Context HttpServletRequest request, Multiv try{ User2 user = (User2) request.getSession().getAttribute("semoss_user"); - String userId = user.getAccessToken(AuthProvider.NATIVE.name()).getId(); + String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); String engineId = form.getFirst("engineId").trim(); StringMap>> groups = gson.fromJson(form.getFirst("groups"), StringMap.class); StringMap>> users = gson.fromJson(form.getFirst("users"), StringMap.class); @@ -797,7 +512,7 @@ public Response setDbVisibility(@Context HttpServletRequest request, Multivalued Hashtable errorRet = new Hashtable(); try{ User2 user = (User2) request.getSession().getAttribute("semoss_user"); - String userId = user.getAccessToken(AuthProvider.NATIVE.name()).getId(); + String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); String engineId = form.getFirst("engineId"); String visibility = form.getFirst("visibility"); permissions.setDbVisibility(userId, engineId, visibility); @@ -813,6 +528,52 @@ public Response setDbVisibility(@Context HttpServletRequest request, Multivalued return WebUtility.getResponse(true, 200); } + @POST + @Produces("application/json") + @Path("/admin/setDbPublic") + public Response setAdminDbPublic(@Context HttpServletRequest request, MultivaluedMap form) { + Hashtable errorRet = new Hashtable(); + try{ + User2 user = (User2) request.getSession().getAttribute("semoss_user"); + String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); + String engineId = form.getFirst("engineId"); + String isPublic = form.getFirst("public"); + permissions.setDbPublic(userId, engineId, isPublic, true); + } catch (IllegalArgumentException e){ + e.printStackTrace(); + errorRet.put("error", e.getMessage()); + return WebUtility.getResponse(errorRet, 400); + } catch (Exception e){ + e.printStackTrace(); + errorRet.put("error", "An unexpected error happened. Please try again."); + return WebUtility.getResponse(errorRet, 500); + } + return WebUtility.getResponse(true, 200); + } + + @POST + @Produces("application/json") + @Path("setDbPublic") + public Response setDbPublic(@Context HttpServletRequest request, MultivaluedMap form) { + Hashtable errorRet = new Hashtable(); + try{ + User2 user = (User2) request.getSession().getAttribute("semoss_user"); + String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); + String engineId = form.getFirst("engineId"); + String isPublic = form.getFirst("public"); + permissions.setDbPublic(userId, engineId, isPublic, false); + } catch (IllegalArgumentException e){ + e.printStackTrace(); + errorRet.put("error", e.getMessage()); + return WebUtility.getResponse(errorRet, 400); + } catch (Exception e){ + e.printStackTrace(); + errorRet.put("error", "An unexpected error happened. Please try again."); + return WebUtility.getResponse(errorRet, 500); + } + return WebUtility.getResponse(true, 200); + } + @POST @Produces("application/json") @Path("/admin/deleteUser") @@ -820,7 +581,7 @@ public Response deleteUser(@Context HttpServletRequest request, MultivaluedMap errorRet = new Hashtable(); try{ User2 user = (User2) request.getSession().getAttribute("semoss_user"); - String adminId = user.getAccessToken(AuthProvider.NATIVE.name()).getId(); + String adminId = user.getAccessToken(AuthProvider.NATIVE).getId(); String userId = form.getFirst("userId"); permissions.deleteUser(adminId, userId); if(adminId.equals(userId)){ @@ -837,4 +598,65 @@ public Response deleteUser(@Context HttpServletRequest request, MultivaluedMap(); +// StringMap> teamShareMaps = new StringMap>(); +// +// //Get the existing team share mappings, if they exist +// if(DIHelper.getInstance().getLocalProp("teamShareMaps") != null) { +// teamShareMaps = (StringMap>) DIHelper.getInstance().getLocalProp("teamShareMaps"); +// } +// +// if(teamShareMaps.containsKey(teamId)) { +// retData.put("success", false); +//// return Response.status(400).entity(WebUtility.getSO(retData)).build(); +// return WebUtility.getResponse(retData, 200); +// } else { +// StringMap newTeamShareMap = new StringMap(); +// newTeamShareMap.put("insightId", insightId); +// newTeamShareMap.put("owner", ((User)request.getSession().getAttribute(Constants.SESSION_USER)).getId()); +// teamShareMaps.put(teamId, newTeamShareMap); +// } +// DIHelper.getInstance().setLocalProperty("teamShareMaps", teamShareMaps); +// +// retData.put("success", true); +//// return Response.status(200).entity(WebUtility.getSO(retData)).build(); +// return WebUtility.getResponse(retData, 200); +// } +// +// @GET +// @Path("/endTeamSession") +// @Produces("application/json") +// public Response endTeamSession(@Context HttpServletRequest request, @QueryParam("teamId") String teamId) { +// StringMap retData = new StringMap(); +// String loggedInUser = ((User)request.getSession().getAttribute(Constants.SESSION_USER)).getId(); +// StringMap> teamShareMaps = new StringMap>(); +// +// //Get the existing team share mappings, if they exist +// if(DIHelper.getInstance().getLocalProp("teamShareMaps") != null) { +// teamShareMaps = (StringMap>) DIHelper.getInstance().getLocalProp("teamShareMaps"); +// } +// +// //If the map doesn't exist, or the teamId isn't in the map, or the logged in user isn't the owner of the team session, don't do anything +// if(teamShareMaps == null || !teamShareMaps.containsKey(teamId) || !teamShareMaps.get(teamId).get("owner").equals(loggedInUser)) { +// retData.put("success", false); +//// return Response.status(400).entity(WebUtility.getSO(retData)).build(); +// return WebUtility.getResponse(retData, 200); +// } +// +// //Remove the team session information and replace the map in DIHelper +// teamShareMaps.remove(teamId); +// DIHelper.getInstance().setLocalProperty("teamShareMaps", teamShareMaps); +// +// retData.put("success", true); +//// return Response.status(200).entity(WebUtility.getSO(retData)).build(); +// return WebUtility.getResponse(retData, 200); +// } + + } \ No newline at end of file diff --git a/src/prerna/semoss/web/services/EngineResource.java b/src/prerna/semoss/web/services/EngineResource.java index d6f3651a2..715a31baf 100644 --- a/src/prerna/semoss/web/services/EngineResource.java +++ b/src/prerna/semoss/web/services/EngineResource.java @@ -27,7 +27,6 @@ *******************************************************************************/ package prerna.semoss.web.services; -import java.io.File; import java.util.HashMap; import java.util.Hashtable; import java.util.List; @@ -42,7 +41,6 @@ import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.Context; -import javax.ws.rs.core.MultivaluedHashMap; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; @@ -52,7 +50,6 @@ import com.google.gson.reflect.TypeToken; import prerna.auth.AuthProvider; -import prerna.auth.User; import prerna.auth.User2; import prerna.engine.api.IEngine; import prerna.engine.api.IEngine.ENGINE_TYPE; @@ -60,7 +57,6 @@ import prerna.forms.AbstractFormBuilder; import prerna.forms.FormBuilder; import prerna.forms.FormFactory; -import prerna.insights.admin.DBAdminResource; import prerna.om.Insight; import prerna.om.InsightStore; import prerna.rdf.engine.wrappers.WrapperManager; @@ -73,9 +69,7 @@ import prerna.sablecc2.reactor.legacy.playsheets.GetPlaysheetParamsReactor; import prerna.sablecc2.reactor.legacy.playsheets.RunPlaysheetReactor; import prerna.util.Constants; -import prerna.util.DIHelper; import prerna.util.Utility; -import prerna.util.ZipDatabase; import prerna.web.services.util.WebUtility; public class EngineResource { @@ -196,7 +190,7 @@ public Response getInsightParams(@QueryParam("insight") String insightId) public Response createOutput(MultivaluedMap form, @Context HttpServletRequest request) { HttpSession session = request.getSession(true); - User user = ((User) session.getAttribute(Constants.SESSION_USER)); + User2 user = ((User2) session.getAttribute(Constants.SESSION_USER)); Gson gson = new Gson(); String insightId = form.getFirst("insight"); @@ -214,7 +208,7 @@ public Response createOutput(MultivaluedMap form, @Context HttpS InsightStore.getInstance().put(dummyIn); InsightStore.getInstance().addToSessionHash(session.getId(), dummyIn.getInsightId()); dummyIn.getVarStore().put(JobReactor.SESSION_KEY, new NounMetadata(session.getId(), PixelDataType.CONST_STRING)); - dummyIn.setUser(user); + dummyIn.setUser2(user); playsheetRunReactor.setInsight(dummyIn); PixelPlanner planner = new PixelPlanner(); planner.setVarStore(dummyIn.getVarStore()); @@ -244,7 +238,7 @@ public Response commitFormData(@Context HttpServletRequest request, MultivaluedM try { HttpSession session = ((HttpServletRequest)request).getSession(false); User2 user = (User2) session.getAttribute("semoss_user"); - userId = user.getAccessToken(AuthProvider.CAC.toString()).getName(); + userId = user.getAccessToken(AuthProvider.CAC).getName(); } catch(Exception e) { Map err = new HashMap(); err.put("errorMessage", "Could not identify user"); @@ -294,35 +288,35 @@ public Response getAuditLogForEngine(MultivaluedMap form, @Conte return WebUtility.getResponse(gson.toJson(auditInfo), 200); } - @GET - @Path("/exportDatabase") - @Produces("application/zip") - public Response exportDatabase(@Context HttpServletRequest request) { - HttpSession session = request.getSession(); - String engineId = coreEngine.getEngineId(); - String engineName = coreEngine.getEngineName(); - - // we want to start exporting the solr documents as well - // since we want to move away from using the rdbms insights for that - DBAdminResource dbAdmin = new DBAdminResource(); - MultivaluedMap form = new MultivaluedHashMap(); - form.putSingle("engineName", engineId); - dbAdmin.exportDbSolrInfo(form , request); - - // close the engine so we can export it - session.removeAttribute(engineId); - DIHelper.getInstance().removeLocalProperty(engineId); - coreEngine.closeDB(); - - LOGGER.info("Attending to export engine = " + engineId); - File zip = ZipDatabase.zipEngine(engineId, engineName); - - Response resp = Response.ok(zip) - .header("x-filename", zip.getName()) - .header("content-type", "application/zip") - .header("Content-Disposition", "attachment; filename=\"" + zip.getName() + "\"" ).build(); - - return resp; - } +// @GET +// @Path("/exportDatabase") +// @Produces("application/zip") +// public Response exportDatabase(@Context HttpServletRequest request) { +// HttpSession session = request.getSession(); +// String engineId = coreEngine.getEngineId(); +// String engineName = coreEngine.getEngineName(); +// +// // we want to start exporting the solr documents as well +// // since we want to move away from using the rdbms insights for that +// DBAdminResource dbAdmin = new DBAdminResource(); +// MultivaluedMap form = new MultivaluedHashMap(); +// form.putSingle("engineName", engineId); +// dbAdmin.exportDbSolrInfo(form , request); +// +// // close the engine so we can export it +// session.removeAttribute(engineId); +// DIHelper.getInstance().removeLocalProperty(engineId); +// coreEngine.closeDB(); +// +// LOGGER.info("Attending to export engine = " + engineId); +// File zip = ZipDatabase.zipEngine(engineId, engineName); +// +// Response resp = Response.ok(zip) +// .header("x-filename", zip.getName()) +// .header("content-type", "application/zip") +// .header("Content-Disposition", "attachment; filename=\"" + zip.getName() + "\"" ).build(); +// +// return resp; +// } } \ No newline at end of file diff --git a/src/prerna/semoss/web/services/NameServer.java b/src/prerna/semoss/web/services/NameServer.java index 9aca1cc61..f30e50775 100644 --- a/src/prerna/semoss/web/services/NameServer.java +++ b/src/prerna/semoss/web/services/NameServer.java @@ -83,7 +83,6 @@ import com.google.gson.reflect.TypeToken; import prerna.auth.AuthProvider; -import prerna.auth.User; import prerna.auth.User2; import prerna.auth.UserPermissionsMasterDB; import prerna.engine.api.IEngine; @@ -442,7 +441,7 @@ public StreamingOutput getSearchInsightsResults(MultivaluedMap f HttpSession session = request.getSession(false); User2 user = ((User2) session.getAttribute("semoss_user")); if(user!= null) { - userId = user.getAccessToken(AuthProvider.NATIVE.name()).getId(); + userId = user.getAccessToken(AuthProvider.NATIVE).getId(); } HashSet userEngines = permissions.getUserAccessibleEngines(userId); @@ -563,86 +562,86 @@ public StreamingOutput getFacetInsightsResults(@QueryParam("searchTerm") String } - /** - * GroupBy based based on info from search. This groups documents based on specified field - * @param form - information passes in from the front end - * @return a string version of the results attained from the query/group by search - */ - // group based on info from the search - @POST - @Path("central/context/getGroupInsightsResults") - @Produces("application/json") - public StreamingOutput getGroupInsightsResults(MultivaluedMap form, @Context HttpServletRequest request) { - //text searched in search bar - String searchString = form.getFirst("searchString"); - logger.info("Searching based on input: " + searchString); - - //specifies the starting number for the list of insights to return - String groupOffset = form.getFirst("groupOffset"); - logger.info("Group offset is: " + groupOffset); - - //specifies the number of insights to return - String groupLimit = form.getFirst("groupLimit"); - logger.info("Group limit is: " + groupLimit); - - String groupSort = form.getFirst("groupSort"); - logger.info("Group sort is: " + groupSort); - - //specifies the single field to group by - String groupByField = form.getFirst("groupBy"); - logger.info("Group field is: " + groupByField); - - Integer groupLimitInt = null; - Integer groupOffsetInt = null; - if(groupLimit != null && !groupLimit.isEmpty()) { - groupLimitInt = Integer.parseInt(groupLimit); - } - if(groupOffset != null && !groupOffset.isEmpty()) { - groupOffsetInt = Integer.parseInt(groupOffset); - } - - //filter based on the boxes checked in the facet filter (filtered with an exact filter) - String filterDataStr = form.getFirst("filterData"); - Gson gson = new Gson(); - Map> filterData = gson.fromJson(filterDataStr, new TypeToken>>() {}.getType()); - - //If security is enabled, remove the engines in the filters that aren't accessible - if none in filters, add all accessible engines to filter list - if(Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED))) { - HttpSession session = request.getSession(false); - User user = ((User) session.getAttribute(Constants.SESSION_USER)); - String userId = ""; - if(user!= null) { - userId = user.getId(); - } - - HashSet userEngines = permissions.getUserAccessibleEngines(userId); - ArrayList filterEngines = new ArrayList(); - if(filterData.get(SolrIndexEngine.APP_ID) != null) { - filterEngines.addAll(filterData.get(SolrIndexEngine.APP_ID)); - } - if(filterEngines.size() > 0) { - for(String s : filterEngines) { - if(!userEngines.contains(s)) { - filterData.get(SolrIndexEngine.APP_ID).remove(s); - } - } - } else { - filterEngines.addAll(userEngines); - if(filterEngines.size() > 0) { - filterData.put(SolrIndexEngine.APP_ID, filterEngines); - } - } - } - - Map groupFieldMap = null; - try { - groupFieldMap = SolrIndexEngine.getInstance().executeQueryGroupBy(searchString, groupOffsetInt, groupLimitInt, groupByField, groupSort, filterData); - } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException | SolrServerException | IOException e) { - e.printStackTrace(); - } - - return WebUtility.getSO(groupFieldMap); - } +// /** +// * GroupBy based based on info from search. This groups documents based on specified field +// * @param form - information passes in from the front end +// * @return a string version of the results attained from the query/group by search +// */ +// // group based on info from the search +// @POST +// @Path("central/context/getGroupInsightsResults") +// @Produces("application/json") +// public StreamingOutput getGroupInsightsResults(MultivaluedMap form, @Context HttpServletRequest request) { +// //text searched in search bar +// String searchString = form.getFirst("searchString"); +// logger.info("Searching based on input: " + searchString); +// +// //specifies the starting number for the list of insights to return +// String groupOffset = form.getFirst("groupOffset"); +// logger.info("Group offset is: " + groupOffset); +// +// //specifies the number of insights to return +// String groupLimit = form.getFirst("groupLimit"); +// logger.info("Group limit is: " + groupLimit); +// +// String groupSort = form.getFirst("groupSort"); +// logger.info("Group sort is: " + groupSort); +// +// //specifies the single field to group by +// String groupByField = form.getFirst("groupBy"); +// logger.info("Group field is: " + groupByField); +// +// Integer groupLimitInt = null; +// Integer groupOffsetInt = null; +// if(groupLimit != null && !groupLimit.isEmpty()) { +// groupLimitInt = Integer.parseInt(groupLimit); +// } +// if(groupOffset != null && !groupOffset.isEmpty()) { +// groupOffsetInt = Integer.parseInt(groupOffset); +// } +// +// //filter based on the boxes checked in the facet filter (filtered with an exact filter) +// String filterDataStr = form.getFirst("filterData"); +// Gson gson = new Gson(); +// Map> filterData = gson.fromJson(filterDataStr, new TypeToken>>() {}.getType()); +// +// //If security is enabled, remove the engines in the filters that aren't accessible - if none in filters, add all accessible engines to filter list +// if(Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED))) { +// HttpSession session = request.getSession(false); +// User user = ((User) session.getAttribute(Constants.SESSION_USER)); +// String userId = ""; +// if(user!= null) { +// userId = user.getId(); +// } +// +// HashSet userEngines = permissions.getUserAccessibleEngines(userId); +// ArrayList filterEngines = new ArrayList(); +// if(filterData.get(SolrIndexEngine.APP_ID) != null) { +// filterEngines.addAll(filterData.get(SolrIndexEngine.APP_ID)); +// } +// if(filterEngines.size() > 0) { +// for(String s : filterEngines) { +// if(!userEngines.contains(s)) { +// filterData.get(SolrIndexEngine.APP_ID).remove(s); +// } +// } +// } else { +// filterEngines.addAll(userEngines); +// if(filterEngines.size() > 0) { +// filterData.put(SolrIndexEngine.APP_ID, filterEngines); +// } +// } +// } +// +// Map groupFieldMap = null; +// try { +// groupFieldMap = SolrIndexEngine.getInstance().executeQueryGroupBy(searchString, groupOffsetInt, groupLimitInt, groupByField, groupSort, filterData); +// } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException | SolrServerException | IOException e) { +// e.printStackTrace(); +// } +// +// return WebUtility.getSO(groupFieldMap); +// } //////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////// @@ -728,7 +727,7 @@ public Response getMetamodel(@Context HttpServletRequest request, @QueryParam("e Map ret = new HashMap(); if(Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED))) { User2 user = (User2) request.getSession().getAttribute("semoss_user"); - String userId = user.getAccessToken(AuthProvider.NATIVE.name()).getId(); + String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); HashMap> metamodelFilter = new HashMap>(); if(permissions.getMetamodelSeedsForUser(userId).get(engineName) != null) { metamodelFilter = permissions.getMetamodelSeedsForUser(userId).get(engineName); @@ -942,7 +941,7 @@ else if(insightID.equals("new")) // existingInsight = new Insight(null, dataFrameType, "Grid"); existingInsight = new Insight(); // set the user id into the insight - existingInsight.setUser( ((User) request.getSession().getAttribute(Constants.SESSION_USER)) ); + existingInsight.setUser2( ((User2) request.getSession().getAttribute(Constants.SESSION_USER)) ); InsightStore.getInstance().put(existingInsight); } // else if(insightID.equals("newDashboard")) { diff --git a/src/prerna/semoss/web/services/UserResource.java b/src/prerna/semoss/web/services/UserResource.java index ba957d721..3799d5b2f 100644 --- a/src/prerna/semoss/web/services/UserResource.java +++ b/src/prerna/semoss/web/services/UserResource.java @@ -31,87 +31,42 @@ import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; -import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.PrintStream; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; -import java.security.InvalidKeyException; -import java.security.NoSuchAlgorithmException; -import java.security.Principal; -import java.security.SignatureException; -import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Base64; -import java.util.Formatter; import java.util.HashMap; import java.util.Hashtable; import java.util.List; +import java.util.Map; import java.util.Properties; -import java.util.Scanner; import java.util.UUID; -import javax.crypto.Mac; -import javax.crypto.spec.SecretKeySpec; -import javax.naming.InvalidNameException; -import javax.naming.ldap.LdapName; -import javax.naming.ldap.Rdn; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; import javax.ws.rs.GET; -import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; -import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Context; import javax.ws.rs.core.Response; -import javax.ws.rs.core.StreamingOutput; -import org.apache.http.HttpEntity; import org.apache.http.NameValuePair; -import org.apache.http.client.ResponseHandler; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; -import org.apache.http.impl.client.BasicResponseHandler; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.message.BasicNameValuePair; -import org.apache.http.util.EntityUtils; - -import com.google.api.client.auth.oauth2.TokenResponseException; -import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeTokenRequest; -import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; -import com.google.api.client.googleapis.auth.oauth2.GoogleIdToken; -import com.google.api.client.googleapis.auth.oauth2.GoogleTokenResponse; -import com.google.api.client.http.HttpTransport; -import com.google.api.client.http.javanet.NetHttpTransport; -import com.google.api.client.json.jackson2.JacksonFactory; -import com.google.api.services.oauth2.Oauth2; -import com.google.api.services.oauth2.model.Userinfoplus; -import com.google.gson.Gson; -import com.google.gson.internal.StringMap; -import com.restfb.DefaultFacebookClient; -import com.restfb.FacebookClient; -import com.restfb.Parameter; -import com.sun.jna.platform.win32.Secur32; -import com.sun.jna.platform.win32.Secur32Util; import jodd.util.URLDecoder; import prerna.auth.AccessToken; import prerna.auth.AppTokens; import prerna.auth.AuthProvider; -import prerna.auth.CACReader; -import prerna.auth.User; import prerna.auth.User2; -import prerna.auth.UserPermissionsMasterDB; import prerna.io.connector.IConnectorIOp; import prerna.io.connector.google.GoogleEntityResolver; import prerna.io.connector.google.GoogleFileRetriever; @@ -125,58 +80,55 @@ import prerna.util.Constants; import prerna.util.DIHelper; import prerna.web.services.util.WebUtility; -import waffle.servlet.WindowsPrincipal; @Path("/auth") -public class UserResource -{ - String output = ""; - private final HttpTransport TRANSPORT = new NetHttpTransport(); - private final JacksonFactory JSON_FACTORY = new JacksonFactory(); - private final Gson GSON = new Gson(); - private UserPermissionsMasterDB permissions = new UserPermissionsMasterDB(); - private static AccessToken twitToken = null; - private static AccessToken googAppToken = null; +public class UserResource { private static Properties socialData = null; + + private static AccessToken twitToken = null; + private static AccessToken googAppToken = null; - private final String GOOGLE_CLIENT_SECRET = "***REMOVED***"; - - private final String FACEBOOK_APP_SECRET = "***REMOVED***"; - private final String FACEBOOK_ACCESS_TOKEN_NEW = "https://graph.facebook.com/oauth/access_token?code=%s&client_id=%s&redirect_uri=%s&client_secret=%s"; - - private static ArrayList userEmails = new ArrayList(); +// private static ArrayList userEmails = new ArrayList(); +// static { +// String whitelistPath = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER) + "/db/" + Constants.SECURITY_DB + "/" + Constants.AUTH_WHITELIST_FILE; +// try { +// File whitelistFile = new File(whitelistPath); +// if(whitelistFile.exists()) { +// Scanner whitelist = new Scanner(new FileReader(whitelistFile)); +// while(whitelist.hasNext()) { +// userEmails.add(whitelist.nextLine().trim()); +// } +// whitelist.close(); +// } +// } catch (FileNotFoundException e) { +// e.printStackTrace(); +// } +// loadConnectors(); +// } +// +// private boolean checkWhitelistForEmail(String email) { +// if(userEmails.isEmpty() || userEmails.contains(email)) { +// return true; +// } else { +// return false; +// } +// } static { - String whitelistPath = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER) + "/db/" + Constants.SECURITY_DB + "/" + Constants.AUTH_WHITELIST_FILE; - try { - File whitelistFile = new File(whitelistPath); - if(whitelistFile.exists()) { - Scanner whitelist = new Scanner(new FileReader(whitelistFile)); - while(whitelist.hasNext()) { - userEmails.add(whitelist.nextLine().trim()); - } - whitelist.close(); - } - } catch (FileNotFoundException e) { - e.printStackTrace(); - } - loadConnectors(); - } - - public static void loadConnectors() - { + FileInputStream fis = null; + File f = new File(DIHelper.getInstance().getProperty("SOCIAL")); try { - if(socialData == null) - { + if(socialData == null && f.exists()) { socialData = new Properties(); - socialData.load(new FileInputStream(new File(DIHelper.getInstance().getProperty("SOCIAL")))); - + fis = new FileInputStream(f); + socialData.load(fis); + loginTwitterApp(); loginGoogleApp(); // also make the twit token and such AppTokens.getInstance().setAccessToken(twitToken); - AppTokens.getInstance().setAccessToken(googAppToken); + AppTokens.getInstance().setAccessToken(googAppToken); } } catch (FileNotFoundException e) { e.printStackTrace(); @@ -184,337 +136,159 @@ public static void loadConnectors() e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); + } finally { + if(fis != null) { + try { + fis.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } } } - /** - * Logs user in through Google+. - */ - @POST - @Produces("application/json") - @Path("/login/google") - public Response loginGoogle(@Context HttpServletRequest request) throws IOException { - Hashtable ret = new Hashtable(); - - // Grab the request's payload - StringBuilder buffer = new StringBuilder(); - BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream())); - String line; - while ((line = reader.readLine()) != null) { - buffer.append(line); - } + private static void loginTwitterApp() throws IOException { + // getting the bearer token on twitter for app authentication is a lot simpler + // need to just combine the id and secret + // base 64 and send as authorization + + InputStream is = null; + InputStreamReader isr = null; + BufferedReader rd = null; + if(twitToken == null) { + try { + String prefix = "twitter_"; + String clientId = "***REMOVED***"; + String clientSecret = "***REMOVED***"; + if(socialData.containsKey(prefix+"client_id")) { + clientId = socialData.getProperty(prefix+"client_id"); + } + if(socialData.containsKey(prefix+"secret_key")) { + clientSecret = socialData.getProperty(prefix+"secret_key"); + } + + // make a joint string + String jointString = clientId + ":" + clientSecret; - HashMap h = GSON.fromJson(buffer.toString(), HashMap.class); + // encde this base 64 + String encodedJointString = new String(Base64.getEncoder().encode(jointString.getBytes())); + CloseableHttpClient httpclient = HttpClients.createDefault(); + HttpPost httppost = new HttpPost("https://api.twitter.com/oauth2/token"); + httppost.addHeader("Authorization", "Basic " + encodedJointString); - String clientId = h.get("clientId"); - request.getSession().setAttribute("clientId", clientId); - String code = h.get("code"); - String redirectUri = h.get("redirectUri"); + List paramList = new ArrayList(); + paramList.add(new BasicNameValuePair("grant_type", "client_credentials")); + httppost.setEntity(new UrlEncodedFormEntity(paramList)); - // Only connect a user that is not already connected. - String tokenData = (String) request.getSession().getAttribute("token"); - if (tokenData != null) { - ret.put("error", "User is already connected."); -// return Response.status(200).entity(WebUtility.getSO(ret)).build(); - return WebUtility.getResponse(ret, 200); - } - // Ensure that this is no request forgery going on, and that the user - // sending us this connect request is the user that was supposed to. - if (request.getParameter("state") != null && request.getSession().getAttribute("state") != null && - !request.getParameter("state").equals(request.getSession().getAttribute("state"))) { - ret.put("error", "Invalid state parameter."); -// return Response.status(400).entity(WebUtility.getSO(ret)).build(); - return WebUtility.getResponse(ret, 400); - } + CloseableHttpResponse authResp = httpclient.execute(httppost); - GoogleTokenResponse tokenResponse = new GoogleTokenResponse(); - try { - // Upgrade the authorization code into an access and refresh token. - tokenResponse = new GoogleAuthorizationCodeTokenRequest(TRANSPORT, JSON_FACTORY, clientId, GOOGLE_CLIENT_SECRET, code, redirectUri).execute(); - - // Grab the Google user info - GoogleCredential credential = new GoogleCredential.Builder() - .setTransport(this.TRANSPORT) - .setJsonFactory(this.JSON_FACTORY) - .setClientSecrets(clientId, GOOGLE_CLIENT_SECRET).build() - .setFromTokenResponse(tokenResponse); - Oauth2 oauth2 = new Oauth2.Builder(TRANSPORT, JSON_FACTORY, credential).setApplicationName("SEMOSS").build(); - Userinfoplus userinfo = oauth2.userinfo().get().execute(); - - // Parse out information from payload as needed and add it to User object and session - GoogleIdToken idToken = tokenResponse.parseIdToken(); - String gplusId = idToken.getPayload().getSubject(); - String email = idToken.getPayload().getEmail(); - String name = userinfo.getGivenName() + " " + userinfo.getFamilyName(); - String picture = userinfo.getPicture(); - - if(!checkWhitelistForEmail(email)) { -// return Response.status(401).entity(WebUtility.getSO("Not permitted to log in. Please contact administrator.")).build(); - return WebUtility.getResponse("Not permitted to log in. Please contact administrator", 401); - } - - ret.put("token", tokenResponse.getAccessToken()); - ret.put("id", gplusId); - ret.put("name", name); - ret.put("email", email); - User newUser; - if(picture != null && !picture.isEmpty()) { - ret.put("picture", picture); - newUser = new User(gplusId, name, User.LOGIN_TYPES.GOOGLE, email, picture); - } else { - newUser = new User(gplusId, name, User.LOGIN_TYPES.GOOGLE, email); - } - // also set the google id token - newUser.setAdditionalData("googleCredential", credential); - addUser(newUser); - - if(permissions.isUserAdmin(gplusId)) { - newUser.setAdmin(true); + System.out.println("Response Code " + authResp.getStatusLine().getStatusCode()); + + is = authResp.getEntity().getContent(); + isr = new InputStreamReader(is); + rd = new BufferedReader(isr); + StringBuffer result = new StringBuffer(); + String line = ""; + while ((line = rd.readLine()) != null) { + result.append(line); + } + + twitToken = AbstractHttpHelper.getJAccessToken(result.toString()); + twitToken.setProvider(AuthProvider.TWITTER); + } catch(Exception ex) { + ex.printStackTrace(); + } finally { + if(is != null) { + try { + is.close(); + } catch(IOException e) { + // ignore + } + } + if(isr != null) { + try { + isr.close(); + } catch(IOException e) { + // ignore + } + } + if(rd != null) { + try { + rd.close(); + } catch(IOException e) { + // ignore + } + } } - - request.getSession().setAttribute(Constants.SESSION_USER, newUser); - - // Store the token in the session for later use. - request.getSession().setAttribute("token", tokenResponse.toString()); - } catch (TokenResponseException e) { - ret.put("success", "false"); - ret.put("error", "Failed to upgrade the auth code: " + e.getMessage()); -// return Response.status(400).entity(WebUtility.getSO(ret)).build(); - return WebUtility.getResponse(ret, 400); - } catch (IOException e) { - ret.put("success", "false"); - ret.put("error", "Failed to read the token data from google: " + e.getMessage()); -// return Response.status(404).entity(WebUtility.getSO(ret)).build(); - return WebUtility.getResponse(ret, 404); + System.out.println("Access Token is.. " + twitToken.getAccess_token()); } - - ret.put("success", "true"); -// return Response.status(200).entity(WebUtility.getSO(ret)).build(); - return WebUtility.getResponse(ret, 200); } - /** - * Logs user in through Facebook. - */ - @POST - @Produces("application/json") - @Path("/login/facebook") - public Response loginFacebook(@Context HttpServletRequest request) throws IOException { - Hashtable ret = new Hashtable(); - - StringBuilder buffer = new StringBuilder(); - BufferedReader reader = null; - try { - reader = new BufferedReader(new InputStreamReader(request.getInputStream())); - String line; - while ((line = reader.readLine()) != null) { - buffer.append(line); - } - } catch (IOException e) { - e.printStackTrace(); - } finally { - if(reader != null) { - try { - reader.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - - HashMap h = GSON.fromJson(buffer.toString(), HashMap.class); - - String clientId = h.get("clientId"); - request.getSession().setAttribute("clientId", clientId); - String code = h.get("code"); - String redirectUri = h.get("redirectUri"); - String accessToken = ""; - - CloseableHttpClient httpclient = HttpClients.createDefault(); - String url = String.format(this.FACEBOOK_ACCESS_TOKEN_NEW, code, clientId, URLEncoder.encode(redirectUri, "UTF-8"), this.FACEBOOK_APP_SECRET); - HttpGet http = new HttpGet(url); - CloseableHttpResponse response = httpclient.execute(http); - - // Retrieve Facebook OAuth access token - try { - HttpEntity entity = response.getEntity(); - if (entity != null) { - InputStream is = entity.getContent(); - if (is != null) { - String resp = EntityUtils.toString(entity); - - if(resp.contains("access_token")) { - accessToken = resp.substring(resp.indexOf("=")+1, resp.indexOf("&expires")); - request.getSession().setAttribute("token", accessToken); - } else { - Gson gson = new Gson(); - HashMap> k = gson.fromJson(resp, HashMap.class); - - if(k.get("error") != null) { - ret.put("success", "false"); - ret.put("error", h.get("error").toString()); -// return Response.status(400).entity(WebUtility.getSO(ret)).build(); - return WebUtility.getResponse(ret, 400); - } - } - } - } - } finally { - response.close(); - httpclient.close(); - } - - // Retrieve Facebook account User object using OAuth access token - FacebookClient fb = new DefaultFacebookClient(accessToken, this.FACEBOOK_APP_SECRET); - com.restfb.types.User me = fb.fetchObject("me", com.restfb.types.User.class, Parameter.with("fields", "id, name, email, picture")); - - // Parse out information from return data as needed and add it to User object and session - String id = me.getId(); - String email = me.getEmail(); - String name = me.getName(); - - if(!checkWhitelistForEmail(email)) { -// return Response.status(401).entity(WebUtility.getSO("Not permitted to log in. Please contact administrator.")).build(); - return WebUtility.getResponse("Not permitted to log in. Please contact administrator.", 401); - } - - User newUser; - if(me.getPicture() != null) { - String picture = me.getPicture().getUrl(); - ret.put("picture", picture); - newUser = new User(id, name, User.LOGIN_TYPES.FACEBOOK, email, picture); - } else { - newUser = new User(id, name, User.LOGIN_TYPES.FACEBOOK, email); - } - - ret.put("token", accessToken); - ret.put("id", id); - ret.put("name", name); - ret.put("email", email); - - addUser(newUser); - - if(permissions.isUserAdmin(id)) { - newUser.setAdmin(true); + private static void loginGoogleApp() { + // nothing big here + // set the name on accesstoken + if(googAppToken == null) { + googAppToken = new AccessToken(); + googAppToken.setAccess_token(socialData.getProperty("google_maps_api")); + googAppToken.setProvider(AuthProvider.GOOGLE_MAP); } - - request.getSession().setAttribute(Constants.SESSION_USER, newUser); - - // Store the token in the session for later use. - request.getSession().setAttribute("token", accessToken); - - ret.put("success", "true"); -// return Response.status(200).entity(WebUtility.getSO(ret)).build(); - return WebUtility.getResponse(ret, 200); } + - /** - * Logs user out when authenticated through Facebook. - */ @GET - @Produces("application/json") - @Path("/logout/facebook") - public Response logoutFacebook(@Context HttpServletRequest request) throws IOException { - Hashtable ret = new Hashtable(); - - // Only disconnect a connected user. - String tokenData = (String) request.getSession().getAttribute("token"); - if (tokenData == null) { - ret.put("success", "false"); - ret.put("error", "User is not connected."); -// return Response.status(400).entity(WebUtility.getSO(ret)).build(); - return WebUtility.getResponse(ret, 400); + @Path("logins") + public Response getAllLogins(@Context HttpServletRequest request) { + User2 semossUser = (User2) request.getSession().getAttribute(Constants.SESSION_USER); + List logins = new ArrayList(); + if(semossUser != null) { + logins = semossUser.getLogins(); } - - request.getSession().invalidate(); - - ret.put("success", "true"); -// return Response.status(200).entity(WebUtility.getSO(ret)).build(); + Map> ret = new HashMap>(); + ret.put("logins", logins); return WebUtility.getResponse(ret, 200); } - private boolean checkWhitelistForEmail(String email) { - if(userEmails.isEmpty() || userEmails.contains(email)) { - return true; + @GET + @Produces("application/json") + @Path("/logout/{provider}") + public Response logout(@PathParam("provider") String provider, @Context HttpServletRequest request) throws IOException { + boolean removed = false; + if(provider.equalsIgnoreCase("ALL")) { + // remove the user from session call it a day + request.getSession().removeAttribute(Constants.SESSION_USER); + removed = true; } else { - return false; + User2 thisUser = (User2) request.getSession().getAttribute(Constants.SESSION_USER); + removed = thisUser.dropAccessToken(provider.toUpperCase()); + request.getSession().setAttribute(Constants.SESSION_USER, thisUser); } - } - - @POST - @Produces("application/json") - @Path("login/cac") - public StreamingOutput loginCAC(@Context HttpServletRequest request, @QueryParam("pin") String pin) { - CACReader reader = new CACReader(); - return WebUtility.getSO(reader.getCACName(pin)); + + Map ret = new Hashtable(); + ret.put("success", removed); + return WebUtility.getResponse(ret, 200); } /** - * Adds user to Local Master DB upon sign-in - * - * @param userId User ID of user retrieved from Identity Provider - * @param EMAIL Email address of user retrieved from Identity Provider + * Method to add an access token to a user + * @param token + * @param request */ - private void addUser(User newUser) { - permissions.addUser(newUser); - } - - @GET - @Path("isLoggedIn") - public Response isUserLoggedIn(@Context HttpServletRequest request) { - if(request.getSession().getAttribute(Constants.SESSION_USER) != null) { - User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - if(!user.getId().equals(Constants.ANONYMOUS_USER_ID)) { -// return Response.status(200).entity(WebUtility.getSO(true)).build(); - return WebUtility.getResponse(true, 200); - } - } - -// return Response.status(200).entity(WebUtility.getSO(false)).build(); - return WebUtility.getResponse(false, 200); - } - - - @GET - @Path("logins") - public Response getAllLogins(@Context HttpServletRequest request) { - + private void addAccessToken(AccessToken token, HttpServletRequest request) { User2 semossUser = null; - Object user = request.getSession().getAttribute("semoss_user"); - - List logins = new ArrayList(); - - if(user != null) - { + Object user = request.getSession().getAttribute(Constants.SESSION_USER); + if(user != null) { semossUser = (User2)user; -// return Response.status(200).entity(WebUtility.getSO(true)).build(); - logins = semossUser.getLogins(); - } - Hashtable params = new Hashtable(); - params.put("logins", logins); - return WebUtility.getResponse(params, 200); - } - - - - @GET - @Produces("application/json") - @Path("userinfo") - public Response getLoggedInUserInfo(@Context HttpServletRequest request) { - Hashtable ret = new Hashtable(); - - User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - if(user.getPicture() != null) { - String picture = user.getPicture(); - ret.put("picture", picture); + } else { + semossUser = new User2(); + if(twitToken != null) { + semossUser.setAccessToken(twitToken); + } + if(googAppToken != null) { + semossUser.setAccessToken(googAppToken); + } } - - ret.put("id", user.getId()); - ret.put("name", user.getName()); - ret.put("email", user.getEmail()); - -// return Response.status(200).entity(WebUtility.getSO(ret)).build(); - return WebUtility.getResponse(ret, 200); + semossUser.setAccessToken(token); + request.getSession().setAttribute(Constants.SESSION_USER, semossUser); } /** @@ -523,33 +297,26 @@ public Response getLoggedInUserInfo(@Context HttpServletRequest request) { @GET @Produces("application/json") @Path("/userinfo/google") - public Response userinfoGoogle(@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException - { - String queryString = request.getQueryString(); - Object userObj = request.getSession().getAttribute("semoss_user"); - Hashtable ret = new Hashtable(); + public Response userinfoGoogle(@Context HttpServletRequest request) { + Map ret = new Hashtable(); + User2 user = (User2) request.getSession().getAttribute(Constants.SESSION_USER); - String objectName = "prerna.auth.AccessToken"; // it will fill this object and return the data - String [] beanProps = {"name", "profile"}; // add is done when you have a list + String [] beanProps = {"name", "profile"}; String jsonPattern = "[name, picture]"; - - userObj = request.getSession().getAttribute("semoss_user"); - User2 user = (User2)userObj; - String accessString=null; - try{ - if(user==null){ + String accessString = null; + try { + if(user == null) { ret.put("ERROR", "Log into your Google account"); return WebUtility.getResponse(ret, 200); - } - else if (user != null) { - AccessToken googleToken = user.getAccessToken(AuthProvider.GOOGLE.name()); - accessString=googleToken.getAccess_token(); + } else { + AccessToken googleToken = user.getAccessToken(AuthProvider.GOOGLE); + accessString = googleToken.getAccess_token(); } - } - catch (Exception e) { + } catch (Exception e) { ret.put("ERROR", "Log into your Google account"); return WebUtility.getResponse(ret, 200); } + String url = "https://www.googleapis.com/oauth2/v3/userinfo"; Hashtable params = new Hashtable(); params.put("access_token", accessString); @@ -558,16 +325,15 @@ else if (user != null) { String output = AbstractHttpHelper.makeGetCall(url, accessString, params, true); AccessToken accessToken2 = (AccessToken)BeanFiller.fillFromJson(output, jsonPattern, beanProps, new AccessToken()); try { - if(accessToken2.getProfile() != null) { - ret.put("picture", accessToken2.getProfile()); - } ret.put("name", accessToken2.getName()); + if(accessToken2.getProfile() != null) { + ret.put("picture", accessToken2.getProfile()); + } } catch (Exception e) { - // TODO Auto-generated catch block e.printStackTrace(); } + return WebUtility.getResponse(ret, 200); - } /** @@ -576,26 +342,20 @@ else if (user != null) { @GET @Produces("application/json") @Path("/userinfo/ms") - public Response userinfoOneDrive(@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException - { - String queryString = request.getQueryString(); - Object userObj = request.getSession().getAttribute("semoss_user"); - Hashtable ret = new Hashtable(); + public Response userinfoOneDrive(@Context HttpServletRequest request) { + Map ret = new Hashtable(); + User2 user = (User2) request.getSession().getAttribute(Constants.SESSION_USER); - String objectName = "prerna.auth.AccessToken"; // it will fill this object and return the data - String [] beanProps = {"name"}; // add is done when you have a list + String [] beanProps = {"name"}; String jsonPattern = "[displayName]"; - userObj = request.getSession().getAttribute("semoss_user"); - User2 user = (User2)userObj; - String accessString=null; + String accessString = null; try{ - if(user==null){ + if(user == null) { ret.put("ERROR", "Log into your Microsoft account"); - } - else if (user != null) { - AccessToken msToken = user.getAccessToken(AuthProvider.AZURE_GRAPH.name()); - accessString=msToken.getAccess_token(); + } else { + AccessToken msToken = user.getAccessToken(AuthProvider.AZURE_GRAPH); + accessString = msToken.getAccess_token(); String url = "https://graph.microsoft.com/v1.0/me/"; String output = AbstractHttpHelper.makeGetCall(url, accessString, null, true); AccessToken accessToken2 = (AccessToken)BeanFiller.fillFromJson(output, jsonPattern, beanProps, new AccessToken()); @@ -616,26 +376,19 @@ else if (user != null) { @GET @Produces("application/json") @Path("/userinfo/dropbox") - public Response userinfoDropbox(@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException - { - String queryString = request.getQueryString(); - Object userObj = request.getSession().getAttribute("semoss_user"); - Hashtable ret = new Hashtable(); + public Response userinfoDropbox(@Context HttpServletRequest request) { + Map ret = new Hashtable(); + User2 user = (User2) request.getSession().getAttribute(Constants.SESSION_USER); - String objectName = "prerna.auth.AccessToken"; // it will fill this object and return the data String [] beanProps = {"name", "profile"}; // add is done when you have a list String jsonPattern = "[name.display_name, profile_photo_url]"; - - userObj = request.getSession().getAttribute("semoss_user"); - User2 user = (User2)userObj; - String accessString=null; - try{ - if(user==null){ + String accessString = null; + try { + if(user == null){ ret.put("ERROR", "Log into your DropBox account"); return WebUtility.getResponse(ret, 200); - } - else if (user != null) { - AccessToken dropToken = user.getAccessToken(AuthProvider.DROPBOX.name()); + } else { + AccessToken dropToken = user.getAccessToken(AuthProvider.DROPBOX); accessString=dropToken.getAccess_token(); } } @@ -645,22 +398,19 @@ else if (user != null) { } String url = "https://api.dropboxapi.com/2/users/get_current_account"; - String output = AbstractHttpHelper.makePostCall(url, accessString, null, true); AccessToken accessToken2 = (AccessToken)BeanFiller.fillFromJson(output, jsonPattern, beanProps, new AccessToken()); try { if(accessToken2.getProfile() == null||accessToken2.getProfile().equalsIgnoreCase("null")) { - ret.put("picture", ""); - } - else{ - ret.put("picture", accessToken2.getProfile()); - } - ret.put("name", accessToken2.getName()); - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); + ret.put("picture", ""); + } else { + ret.put("picture", accessToken2.getProfile()); } - return WebUtility.getResponse(ret, 200); + ret.put("name", accessToken2.getName()); + } catch (Exception e) { + e.printStackTrace(); + } + return WebUtility.getResponse(ret, 200); } @@ -670,33 +420,27 @@ else if (user != null) { @GET @Produces("application/json") @Path("/userinfo/git") - public Response userinfoGithub(@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException - { - String queryString = request.getQueryString(); - Object userObj = request.getSession().getAttribute("semoss_user"); - Hashtable ret = new Hashtable(); + public Response userinfoGithub(@Context HttpServletRequest request) { + Map ret = new Hashtable(); + User2 user = (User2) request.getSession().getAttribute(Constants.SESSION_USER); - String objectName = "prerna.auth.AccessToken"; // it will fill this object and return the data String [] beanProps = {"name", "profile"}; // add is done when you have a list String jsonPattern = "[name,login]"; - userObj = request.getSession().getAttribute("semoss_user"); - User2 user = (User2)userObj; - String accessString=null; + String accessString = null; try{ - if(user==null){ + if(user == null) { ret.put("ERROR", "Log into your Github account"); return WebUtility.getResponse(ret, 200); - } - else if (user != null) { - AccessToken gitToken = user.getAccessToken(AuthProvider.GIT.name()); + } else { + AccessToken gitToken = user.getAccessToken(AuthProvider.GIT); accessString=gitToken.getAccess_token(); } - } - catch (Exception e) { + } catch (Exception e) { ret.put("ERROR", "Log into your Github account"); return WebUtility.getResponse(ret, 200); } + String url = "https://api.github.com/user"; Hashtable params = new Hashtable(); params.put("access_token", accessString); @@ -704,150 +448,81 @@ else if (user != null) { String output = AbstractHttpHelper.makeGetCall(url, accessString, params, false); AccessToken accessToken2 = (AccessToken)BeanFiller.fillFromJson(output, jsonPattern, beanProps, new AccessToken()); try { - //ret.put("name", accessToken2.getName()); ret.put("name", accessToken2.getProfile()); - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - return WebUtility.getResponse(ret, 200); - - } - - @GET - @Produces("text/plain") - @Path("/whoami") - public StreamingOutput show(@Context HttpServletRequest request, @Context HttpServletResponse response) { - HttpSession session = request.getSession(); - System.err.println(" came into user resource"); - Principal principal = request.getUserPrincipal(); - output = "
";
-		output = request.getRemoteUser() + "\n" + request.getUserPrincipal().getName() + "\n";
-		output = output + "Session " + request.getSession().getId() + "\n";
-		output = output + "Impersonation " + Secur32Util.getUserNameEx(Secur32.EXTENDED_NAME_FORMAT.NameSamCompatible);
-		if (principal instanceof WindowsPrincipal) {
-			WindowsPrincipal windowsPrincipal = (WindowsPrincipal) principal;
-			for(waffle.windows.auth.WindowsAccount account : windowsPrincipal.getGroups().values()) {
-				output = output + account.getFqn() + account.getSidString() + "\n";
-			}
-		}
-		output = output + "
"; - return new StreamingOutput() { - public void write(OutputStream outputStream) throws IOException, WebApplicationException { - PrintStream ps = new PrintStream(outputStream); - ps.println(output); - } - }; - } - - @GET - @Produces("text/plain") - @Path("/getCert") - public StreamingOutput getCert(@Context HttpServletRequest request, @Context HttpServletResponse response) throws InvalidNameException { - X509Certificate[] certs = (X509Certificate[]) request.getAttribute("javax.servlet.request.X509Certificate"); - if(certs == null || certs.length == 0) { - output = "WE GOT NOTHING!!! :("; - } else { - for(int i = 0; i < certs.length; i++) { - X509Certificate cert = certs[i]; - - String dn = cert.getSubjectX500Principal().getName(); - LdapName ldapDN = new LdapName(dn); - for(Rdn rdn: ldapDN.getRdns()) { - if(rdn.getType().equals("CN")) { - output += "You are = " + rdn.getValue().toString() + "\n"; - } - } - } + } catch (Exception e) { + e.printStackTrace(); } - return new StreamingOutput() { - public void write(OutputStream outputStream) throws IOException, WebApplicationException { - PrintStream ps = new PrintStream(outputStream); - ps.println(output); - } - }; + return WebUtility.getResponse(ret, 200); } - + /** - * Logs user in through SalesForce + * Logs user in through salesforce */ @GET @Produces("application/json") @Path("/login/sf") - public Response loginSF(@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException - { - // redirect if query string not there - - Object userObj = request.getSession().getAttribute("semoss_user"); + public Response loginSF(@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException { + /* + * Try to log in the user + * If they are not logged in + * Redirect the FE + */ + + User2 userObj = (User2) request.getSession().getAttribute(Constants.SESSION_USER); Hashtable ret = new Hashtable(); - String queryString = request.getQueryString(); - - if(queryString != null && queryString.contains("code=")) - { - if(userObj == null || ((User2)userObj).getAccessToken(AuthProvider.GOOGLE.name()) == null) - { - String [] outputs = AbstractHttpHelper.getCodes(queryString); - - String prefix = "sf_"; - - String clientId = (String)socialData.getProperty(prefix+"client_id"); - String clientSecret = (String)socialData.getProperty(prefix+"secret_key"); - String redirectUri = (String)socialData.getProperty(prefix+"redirect_uri"); - - System.out.println(">> " + request.getQueryString()); - - Hashtable params = new Hashtable(); - params.put("client_id", clientId); - params.put("grant_type", "authorization_code"); - params.put("redirect_uri", redirectUri); - params.put("code", URLDecoder.decode(outputs[0])); - params.put("client_secret", clientSecret); - - String url = "https://login.salesforce.com/services/oauth2/token"; - - AccessToken accessToken = AbstractHttpHelper.getAccessToken(url, params, true, true); - - accessToken.setProvider(AuthProvider.SALESFORCE.name()); - addAccessToken(accessToken, request); - - System.out.println("Access Token is.. " + accessToken.getAccess_token()); - - ret.put("success", true); - // return Response.status(200).entity(WebUtility.getSO(ret)).build(); - return WebUtility.getResponse(ret, 200); - } - else - { + if(queryString != null && queryString.contains("code=")) { + if(userObj == null || userObj.getAccessToken(AuthProvider.SALESFORCE) == null) { + String[] outputs = AbstractHttpHelper.getCodes(queryString); + + String prefix = "sf_"; + String clientId = socialData.getProperty(prefix+"client_id"); + String clientSecret = socialData.getProperty(prefix+"secret_key"); + String redirectUri = socialData.getProperty(prefix+"redirect_uri"); + + System.out.println(">> " + request.getQueryString()); + + Hashtable params = new Hashtable(); + params.put("client_id", clientId); + params.put("grant_type", "authorization_code"); + params.put("redirect_uri", redirectUri); + params.put("code", URLDecoder.decode(outputs[0])); + params.put("client_secret", clientSecret); + + String url = "https://login.salesforce.com/services/oauth2/token"; + + AccessToken accessToken = AbstractHttpHelper.getAccessToken(url, params, true, true); + accessToken.setProvider(AuthProvider.SALESFORCE); + addAccessToken(accessToken, request); + + System.out.println("Access Token is.. " + accessToken.getAccess_token()); + ret.put("success", true); + return WebUtility.getResponse(ret, 200); + } else { ret.put("success", true); ret.put("Already_Authenticated", true); - // return Response.status(200).entity(WebUtility.getSO(ret)).build(); return WebUtility.getResponse(ret, 200); - } - } - else if(userObj == null || ((User2)userObj).getAccessToken(AuthProvider.SALESFORCE.name()) == null) - { + else if(userObj == null || userObj.getAccessToken(AuthProvider.SALESFORCE) == null) { // not authenticated response.setStatus(302); response.sendRedirect(getSFRedirect(request)); + } + else if(userObj != null && userObj.getAccessToken(AuthProvider.SALESFORCE) != null) { + ret.put("success", true); + return WebUtility.getResponse(ret, 200); } return null; } - private String getSFRedirect(HttpServletRequest request) - throws UnsupportedEncodingException { - + private String getSFRedirect(HttpServletRequest request) throws UnsupportedEncodingException { String prefix = "sf_"; - - String clientId = (String)socialData.getProperty(prefix+"client_id"); - String clientSecret = (String)socialData.getProperty(prefix+"secret_key"); - String redirectUri = (String)socialData.getProperty(prefix+"redirect_uri"); + String clientId = socialData.getProperty(prefix+"client_id"); + String redirectUri = socialData.getProperty(prefix+"redirect_uri"); - String redirectUrl = "https://login.salesforce.com/services/oauth2/authorize?" + "client_id=" + clientId + "&response_type=code" + @@ -855,78 +530,68 @@ private String getSFRedirect(HttpServletRequest request) "&scope=" + URLEncoder.encode("api", "UTF-8"); System.out.println("Sending redirect.. " + redirectUrl); - return redirectUrl; } /** - * Logs user in through GIT + * Logs user in through git + * https://developer.github.com/apps/building-oauth-apps/authorization-options-for-oauth-apps/ */ @GET @Produces("application/json") @Path("/login/git") - public Response loginGit(@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException - { - // redirect if query string not there - Object userObj = request.getSession().getAttribute("semoss_user"); - Hashtable ret = new Hashtable(); - - //https://developer.github.com/apps/building-oauth-apps/authorization-options-for-oauth-apps/ + public Response loginGit(@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException { + /* + * Try to log in the user + * If they are not logged in + * Redirect the FE + */ + + Map ret = new Hashtable(); + User2 userObj = (User2) request.getSession().getAttribute(Constants.SESSION_USER); + String queryString = request.getQueryString(); - - if(queryString != null && queryString.contains("code=")) - { - if(userObj == null || ((User2)userObj).getAccessToken(AuthProvider.GIT.name()) == null) - { + if(queryString != null && queryString.contains("code=")) { + if(userObj == null || userObj.getAccessToken(AuthProvider.GIT) == null) { + String [] outputs = AbstractHttpHelper.getCodes(queryString); - String [] outputs = AbstractHttpHelper.getCodes(queryString); - - String prefix = "git_"; - - String clientId = (String)socialData.getProperty(prefix+"client_id"); - String clientSecret = (String)socialData.getProperty(prefix+"secret_key"); - String redirectUri = (String)socialData.getProperty(prefix+"redirect_uri"); - - System.out.println(">> " + request.getQueryString()); - - Hashtable params = new Hashtable(); - params.put("client_id", clientId); - params.put("redirect_uri", redirectUri); - params.put("code", outputs[0]); - params.put("state", outputs[1]); - params.put("client_secret", clientSecret); + String prefix = "git_"; + String clientId = socialData.getProperty(prefix+"client_id"); + String clientSecret = socialData.getProperty(prefix+"secret_key"); + String redirectUri = socialData.getProperty(prefix+"redirect_uri"); - String url = "https://github.com/login/oauth/access_token"; - - AccessToken accessToken = AbstractHttpHelper.getAccessToken(url, params, false, true); - accessToken.setProvider(AuthProvider.GIT.name()); - addAccessToken(accessToken, request); - - System.out.println("Access Token is.. " + accessToken.getAccess_token()); - - ret.put("success", true); - // return Response.status(200).entity(WebUtility.getSO(ret)).build(); - return WebUtility.getResponse(ret, 200); - } - else - { + System.out.println(">> " + request.getQueryString()); + + Hashtable params = new Hashtable(); + params.put("client_id", clientId); + params.put("redirect_uri", redirectUri); + params.put("code", outputs[0]); + params.put("state", outputs[1]); + params.put("client_secret", clientSecret); + + String url = "https://github.com/login/oauth/access_token"; + + AccessToken accessToken = AbstractHttpHelper.getAccessToken(url, params, false, true); + accessToken.setProvider(AuthProvider.GIT); + addAccessToken(accessToken, request); + + System.out.println("Access Token is.. " + accessToken.getAccess_token()); + ret.put("success", true); + return WebUtility.getResponse(ret, 200); + } else { ret.put("success", true); ret.put("Already_Authenticated", true); - // return Response.status(200).entity(WebUtility.getSO(ret)).build(); return WebUtility.getResponse(ret, 200); - } } - else if(userObj == null || ((User2)userObj).getAccessToken(AuthProvider.GIT.name()) == null) - { + else if(userObj == null || userObj.getAccessToken(AuthProvider.GIT) == null) { // not authenticated - response.setStatus(302); response.sendRedirect(getGitRedirect(request)); - } + } // else if user object is there and git is there - else if(userObj != null && ((User2)userObj).getAccessToken(AuthProvider.GIT.name()) != null) + else if(userObj != null && userObj.getAccessToken(AuthProvider.GIT) != null) { ret.put("success", true); return WebUtility.getResponse(ret, 200); @@ -934,15 +599,11 @@ else if(userObj != null && ((User2)userObj).getAccessToken(AuthProvider.GIT.name return null; } - private String getGitRedirect(HttpServletRequest request) - throws UnsupportedEncodingException { - + private String getGitRedirect(HttpServletRequest request) throws UnsupportedEncodingException { String prefix = "git_"; - - String clientId = (String)socialData.getProperty(prefix+"client_id"); - String clientSecret = (String)socialData.getProperty(prefix+"secret_key"); - String redirectUri = (String)socialData.getProperty(prefix+"redirect_uri"); - String scope = (String)socialData.getProperty(prefix+"scope"); + String clientId = socialData.getProperty(prefix+"client_id"); + String redirectUri = socialData.getProperty(prefix+"redirect_uri"); + String scope = socialData.getProperty(prefix+"scope"); String redirectUrl = "https://github.com/login/oauth/authorize?" + "client_id=" + clientId + @@ -952,102 +613,84 @@ private String getGitRedirect(HttpServletRequest request) "&scope=" + URLEncoder.encode(scope, "UTF-8"); System.out.println("Sending redirect.. " + redirectUrl); - return redirectUrl; } /** - * Logs user in through SalesForce + * Logs user in through ms */ @GET @Produces("application/json") @Path("/login/ms") - public Response loginMS(@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException - { - // redirect if query string not there - - Object userObj = request.getSession().getAttribute("semoss_user"); - Hashtable ret = new Hashtable(); - - + public Response loginMS(@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException { + /* + * Try to log in the user + * If they are not logged in + * Redirect the FE + */ + + Map ret = new Hashtable(); + User2 userObj = (User2) request.getSession().getAttribute(Constants.SESSION_USER); + String queryString = request.getQueryString(); - - if(queryString != null && queryString.contains("code=")) - { - if(userObj == null || ((User2)userObj).getAccessToken(AuthProvider.AZURE_GRAPH.name()) == null) - { - String [] outputs = AbstractHttpHelper.getCodes(queryString); - - String prefix = "ms_"; - - String clientId = (String)socialData.getProperty(prefix+"client_id"); - String clientSecret = (String)socialData.getProperty(prefix+"secret_key"); - String redirectUri = (String)socialData.getProperty(prefix+"redirect_uri"); - String tenant = (String)socialData.getProperty(prefix+"tenant"); - String scope = (String)socialData.getProperty(prefix+"scope"); - - System.out.println(">> " + request.getQueryString()); - - Hashtable params = new Hashtable(); + if(queryString != null && queryString.contains("code=")) { + if(userObj == null || ((User2)userObj).getAccessToken(AuthProvider.AZURE_GRAPH) == null) { + String [] outputs = AbstractHttpHelper.getCodes(queryString); - params.put("client_id", clientId); - params.put("scope", scope); - params.put("redirect_uri", redirectUri); - params.put("code", outputs[0]); - params.put("grant_type", "authorization_code"); - params.put("client_secret", clientSecret); + String prefix = "ms_"; + String clientId = socialData.getProperty(prefix+"client_id"); + String clientSecret = socialData.getProperty(prefix+"secret_key"); + String redirectUri = socialData.getProperty(prefix+"redirect_uri"); + String tenant = socialData.getProperty(prefix+"tenant"); + String scope = socialData.getProperty(prefix+"scope"); - String url = "https://login.microsoftonline.com/" + tenant + "/oauth2/v2.0/token"; - - - AccessToken accessToken = AbstractHttpHelper.getAccessToken(url, params, true, true); - accessToken.setProvider(AuthProvider.AZURE_GRAPH.name()); - addAccessToken(accessToken, request); + System.out.println(">> " + request.getQueryString()); - System.out.println("Access Token is.. " + accessToken.getAccess_token()); - - ret.put("success", true); - // return Response.status(200).entity(WebUtility.getSO(ret)).build(); - return WebUtility.getResponse(ret, 200); - } - else - { + Hashtable params = new Hashtable(); + params.put("client_id", clientId); + params.put("scope", scope); + params.put("redirect_uri", redirectUri); + params.put("code", outputs[0]); + params.put("grant_type", "authorization_code"); + params.put("client_secret", clientSecret); + + String url = "https://login.microsoftonline.com/" + tenant + "/oauth2/v2.0/token"; + + AccessToken accessToken = AbstractHttpHelper.getAccessToken(url, params, true, true); + accessToken.setProvider(AuthProvider.AZURE_GRAPH); + addAccessToken(accessToken, request); + + System.out.println("Access Token is.. " + accessToken.getAccess_token()); + + ret.put("success", true); + return WebUtility.getResponse(ret, 200); + } else { ret.put("success", true); ret.put("Already_Authenticated", true); - // return Response.status(200).entity(WebUtility.getSO(ret)).build(); return WebUtility.getResponse(ret, 200); - } - } - else if(userObj == null || ((User2)userObj).getAccessToken(AuthProvider.AZURE_GRAPH.name()) == null) - { + } else if(userObj == null || userObj.getAccessToken(AuthProvider.AZURE_GRAPH) == null) { // not authenticated response.setStatus(302); response.sendRedirect(getMSRedirect(request)); } // else if user object is there and ms is there - else if(userObj != null && ((User2)userObj).getAccessToken(AuthProvider.AZURE_GRAPH.name()) != null) - { + else if(userObj != null && userObj.getAccessToken(AuthProvider.AZURE_GRAPH) != null) { ret.put("success", true); return WebUtility.getResponse(ret, 200); } - + return null; } - private String getMSRedirect(HttpServletRequest request) - throws UnsupportedEncodingException { - + private String getMSRedirect(HttpServletRequest request) throws UnsupportedEncodingException { String prefix = "ms_"; - - String clientId = (String)socialData.getProperty(prefix+"client_id"); - String clientSecret = (String)socialData.getProperty(prefix+"secret_key"); - String redirectUri = (String)socialData.getProperty(prefix+"redirect_uri"); - String tenant = (String)socialData.getProperty(prefix+"tenant"); - String scope = (String)socialData.getProperty(prefix+"scope"); // need to set this up and reuse + String clientId = socialData.getProperty(prefix+"client_id"); + String redirectUri = socialData.getProperty(prefix+"redirect_uri"); + String tenant = socialData.getProperty(prefix+"tenant"); + String scope = socialData.getProperty(prefix+"scope"); // need to set this up and reuse String state = UUID.randomUUID().toString(); - String redirectUrl = "https://login.microsoftonline.com/" + tenant + "/oauth2/v2.0/authorize?" + "client_id=" + clientId + "&response_type=code" + "&redirect_uri=" @@ -1055,100 +698,80 @@ private String getMSRedirect(HttpServletRequest request) + "&response_mode=query" + "&scope=" + URLEncoder.encode(scope) + "&state=" + state; - System.out.println("Sending redirect.. " + redirectUrl); return redirectUrl; } /** - * Logs user in through SalesForce + * Logs user in through drop box */ @GET @Produces("application/json") @Path("/login/dropbox") - public Response loginDropBox(@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException - { - // redirect if query string not there - - Object userObj = request.getSession().getAttribute("semoss_user"); - Hashtable ret = new Hashtable(); + public Response loginDropBox(@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException { + /* + * Try to log in the user + * If they are not logged in + * Redirect the FE + */ + Map ret = new Hashtable(); + User2 userObj = (User2) request.getSession().getAttribute(Constants.SESSION_USER); String queryString = request.getQueryString(); - - if(queryString != null && queryString.contains("code=")) - { - if(userObj == null || ((User2)userObj).getAccessToken(AuthProvider.DROPBOX.name()) == null) - { + if(queryString != null && queryString.contains("code=")) { + if(userObj == null || userObj.getAccessToken(AuthProvider.DROPBOX) == null) { String [] outputs = AbstractHttpHelper.getCodes(queryString); - + String prefix = "dropbox_"; - - String clientId = (String)socialData.getProperty(prefix+"client_id"); - String clientSecret = (String)socialData.getProperty(prefix+"secret_key"); - String redirectUri = (String)socialData.getProperty(prefix+"redirect_uri"); - + String clientId = socialData.getProperty(prefix+"client_id"); + String clientSecret = socialData.getProperty(prefix+"secret_key"); + String redirectUri = socialData.getProperty(prefix+"redirect_uri"); + System.out.println(">> " + request.getQueryString()); - + Hashtable params = new Hashtable(); - params.put("client_id", clientId); params.put("redirect_uri", redirectUri); params.put("code", outputs[0]); params.put("grant_type", "authorization_code"); params.put("client_secret", clientSecret); - + String url = "https://www.dropbox.com/oauth2/token"; - - + AccessToken accessToken = AbstractHttpHelper.getAccessToken(url, params, true, true); - accessToken.setProvider(AuthProvider.DROPBOX.name()); + accessToken.setProvider(AuthProvider.DROPBOX); addAccessToken(accessToken, request); - + System.out.println("Access Token is.. " + accessToken.getAccess_token()); - ret.put("success", true); - // return Response.status(200).entity(WebUtility.getSO(ret)).build(); - return WebUtility.getResponse(ret, 200); - } - else - { + ret.put("success", true); + return WebUtility.getResponse(ret, 200); + } else { ret.put("success", true); ret.put("Already_Authenticated", true); - // return Response.status(200).entity(WebUtility.getSO(ret)).build(); return WebUtility.getResponse(ret, 200); - } - } - else if(userObj == null || ((User2)userObj).getAccessToken(AuthProvider.DROPBOX.name()) == null) - { + else if(userObj == null || userObj.getAccessToken(AuthProvider.DROPBOX) == null) { // not authenticated response.setStatus(302); response.sendRedirect(getDBRedirect(request)); } // else if user object is there and dropbox is there - else if(userObj != null && ((User2)userObj).getAccessToken(AuthProvider.DROPBOX.name()) != null) - { + else if(userObj != null && userObj.getAccessToken(AuthProvider.DROPBOX) != null) { ret.put("success", true); return WebUtility.getResponse(ret, 200); } return null; } - private String getDBRedirect(HttpServletRequest request) - throws UnsupportedEncodingException { - + private String getDBRedirect(HttpServletRequest request) throws UnsupportedEncodingException { String prefix = "dropbox_"; - String clientId = (String)socialData.getProperty(prefix+"client_id"); - String clientSecret = (String)socialData.getProperty(prefix+"secret_key"); - String redirectUri = (String)socialData.getProperty(prefix+"redirect_uri"); - String scope = (String)socialData.getProperty(prefix+"scope"); // need to set this up and reuse - String role = (String)socialData.getProperty(prefix+"role"); // need to set this up and reuse - - String state = UUID.randomUUID().toString(); - + String clientId = socialData.getProperty(prefix+"client_id"); + String redirectUri = socialData.getProperty(prefix+"redirect_uri"); + String role = socialData.getProperty(prefix+"role"); // need to set this up and reuse String redirectUrl = "https://www.dropbox.com/oauth2/authorize?" + "client_id=" + clientId+ "&response_type=code" + @@ -1157,43 +780,39 @@ private String getDBRedirect(HttpServletRequest request) "&disable_signup=false"; System.out.println("Sending redirect.. " + redirectUrl); - return redirectUrl; } - /** - * Logs user in through SalesForce + * Logs user in through google + * https://developers.google.com/api-client-library/java/google-api-java-client/oauth2 */ @GET @Produces("application/json") @Path("/login/google2") - public Response loginGoogle2(@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException - { - // redirect if query string not there - + public Response loginGoogle2(@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException { + /* + * Try to log in the user + * If they are not logged in + * Redirect the FE + */ + + Map ret = new Hashtable(); + User2 userObj = (User2) request.getSession().getAttribute(Constants.SESSION_USER); + String queryString = request.getQueryString(); - Object userObj = request.getSession().getAttribute("semoss_user"); - Hashtable ret = new Hashtable(); - - // if the code is there - if(queryString != null && queryString.contains("code=")) - { - // if the user is not logged in - if(userObj == null || ((User2)userObj).getAccessToken(AuthProvider.GOOGLE.name()) == null) - { + if(queryString != null && queryString.contains("code=")) { + if(userObj == null || userObj.getAccessToken(AuthProvider.GOOGLE) == null) { String [] outputs = AbstractHttpHelper.getCodes(queryString); String prefix = "google_"; - - String clientId = (String)socialData.getProperty(prefix+"client_id"); - String clientSecret = (String)socialData.getProperty(prefix+"secret_key"); - String redirectUri = (String)socialData.getProperty(prefix+"redirect_uri"); + String clientId = socialData.getProperty(prefix+"client_id"); + String clientSecret = socialData.getProperty(prefix+"secret_key"); + String redirectUri = socialData.getProperty(prefix+"redirect_uri"); System.out.println(">> " + request.getQueryString()); Hashtable params = new Hashtable(); - params.put("client_id", clientId); params.put("redirect_uri", redirectUri); params.put("code", outputs[0]); @@ -1201,71 +820,73 @@ public Response loginGoogle2(@Context HttpServletRequest request, @Context HttpS params.put("client_secret", clientSecret); String url = "https://www.googleapis.com/oauth2/v4/token"; - - System.out.println("Temp.. "); - - AccessToken accessToken = AbstractHttpHelper.getAccessToken(url, params, true, true); //https://developers.google.com/api-client-library/java/google-api-java-client/oauth2 // Shows how to make a google credential from an access token System.out.println("Access Token is.. " + accessToken.getAccess_token()); - accessToken.setProvider(AuthProvider.GOOGLE.name()); + accessToken.setProvider(AuthProvider.GOOGLE); addAccessToken(accessToken, request); + + // this is just for testing... + // but i will get yelled at if i remove it so here it is... + performGoogleOps(request, ret); + } else { + ret.put("success", true); + ret.put("Already_Authenticated", true); + return WebUtility.getResponse(ret, 200); } - - userObj = request.getSession().getAttribute("semoss_user"); - User2 user = (User2)userObj; - AccessToken accessToken = user.getAccessToken(AuthProvider.GOOGLE.name()); - - performGoogleOps(request, ret); ret.put("success", true); - try { - //ret.put("user", BeanFiller.getJson(accessToken)); - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - // return Response.status(200).entity(WebUtility.getSO(ret)).build(); return WebUtility.getResponse(ret, 200); } // else if the user object is there, but there is no google - else if(userObj == null || ((User2)userObj).getAccessToken(AuthProvider.GOOGLE.name()) == null) - { + else if(userObj == null || userObj.getAccessToken(AuthProvider.GOOGLE) == null) { // not authenticated response.setStatus(302); response.sendRedirect(getGoogleRedirect(request)); } // else if user object is there and google is there - else if(userObj != null && ((User2)userObj).getAccessToken(AuthProvider.GOOGLE.name()) != null) - { + else if(userObj != null && userObj.getAccessToken(AuthProvider.GOOGLE) != null) { ret.put("success", true); - User2 user = (User2)userObj; - AccessToken accessToken = user.getAccessToken(AuthProvider.GOOGLE.name()); - - // performGoogleOps(request, ret); - try { - //ret.put("user", BeanFiller.getJson(accessToken)); - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - return WebUtility.getResponse(ret, 200); - } + return null; } - private void performGoogleOps(HttpServletRequest request, Hashtable ret) + private String getGoogleRedirect(HttpServletRequest request) throws UnsupportedEncodingException { + String prefix = "google_"; + String clientId = socialData.getProperty(prefix+"client_id"); + String redirectUri = socialData.getProperty(prefix+"redirect_uri"); + String scope = socialData.getProperty(prefix+"scope"); // need to set this up and reuse + String accessType = socialData.getProperty(prefix+"access_type"); // need to set this up and reuse + String state = UUID.randomUUID().toString(); + + String redirectUrl = "https://accounts.google.com/o/oauth2/v2/auth?" + + "client_id=" + clientId + + "&response_type=code" + + "&redirect_uri=" + URLEncoder.encode(redirectUri, "UTF-8") + + "&access_type=" + accessType + + "&scope=" + URLEncoder.encode(scope, "UTF-8") + + "&state=" + state; + + System.out.println("Sending redirect.. " + redirectUrl); + return redirectUrl; + } + + /** + * METHOD IS USED FOR TESTING + * @param request + * @param ret + */ + private void performGoogleOps(HttpServletRequest request, Map ret) { // get the user details IConnectorIOp prof = new GoogleProfile(); - prof.execute((User2)request.getSession().getAttribute("semoss_user"), null); + prof.execute((User2)request.getSession().getAttribute(Constants.SESSION_USER), null); IConnectorIOp lister = new GoogleListFiles(); - List fileList = (List)lister.execute((User2)request.getSession().getAttribute("semoss_user"), null); + List fileList = (List)lister.execute((User2)request.getSession().getAttribute(Constants.SESSION_USER), null); // get the file IConnectorIOp getter = new GoogleFileRetriever(); @@ -1274,7 +895,7 @@ private void performGoogleOps(HttpServletRequest request, Hashtable ret) params2.put("id", "1it40jNFcRo1ur2dHIYUk18XmXdd37j4gmJm_Sg7KLjI"); params2.put("target", "c:\\users\\pkapaleeswaran\\workspacej3\\datasets\\googlefile.csv"); - getter.execute((User2)request.getSession().getAttribute("semoss_user"), params2); + getter.execute((User2)request.getSession().getAttribute(Constants.SESSION_USER), params2); IConnectorIOp ner = new GoogleEntityResolver(); @@ -1288,7 +909,7 @@ private void performGoogleOps(HttpServletRequest request, Hashtable ret) params2.put("document", docInput); //params2.put("input", docInputShell); - ner.execute((User2)request.getSession().getAttribute("semoss_user"), params2); + ner.execute((User2)request.getSession().getAttribute(Constants.SESSION_USER), params2); try { ret.put("files", BeanFiller.getJson(fileList)); @@ -1301,7 +922,7 @@ private void performGoogleOps(HttpServletRequest request, Hashtable ret) params2 = new Hashtable(); params2.put("address", "1919 N Lynn Street, Arlington, VA"); - lat.execute((User2)request.getSession().getAttribute("semoss_user"), params2); + lat.execute((User2)request.getSession().getAttribute(Constants.SESSION_USER), params2); IConnectorIOp ts = new TwitterSearcher(); params2 = new Hashtable(); @@ -1309,84 +930,31 @@ private void performGoogleOps(HttpServletRequest request, Hashtable ret) params2.put("lang", "en"); params2.put("count", "10"); - Object vp = ts.execute((User2)request.getSession().getAttribute("semoss_user"), params2); - - - } - - private String getGoogleRedirect(HttpServletRequest request) - throws UnsupportedEncodingException { - - String prefix = "google_"; - - String clientId = (String)socialData.getProperty(prefix+"client_id"); - String clientSecret = (String)socialData.getProperty(prefix+"secret_key"); - String redirectUri = (String)socialData.getProperty(prefix+"redirect_uri"); - String scope = (String)socialData.getProperty(prefix+"scope"); // need to set this up and reuse - String accessType = (String)socialData.getProperty(prefix+"access_type"); // need to set this up and reuse - - String state = UUID.randomUUID().toString(); - - String redirectUrl = "https://accounts.google.com/o/oauth2/v2/auth?" - + "client_id=" + clientId - + "&response_type=code" - + "&redirect_uri=" + URLEncoder.encode(redirectUri, "UTF-8") - + "&access_type=" + accessType - + "&scope=" + URLEncoder.encode(scope, "UTF-8") - + "&state=" + state; - - - System.out.println("Sending redirect.. " + redirectUrl); - - return redirectUrl; - } - - // add this user to session - private void addAccessToken(AccessToken token, HttpServletRequest request) - { - User2 semossUser = null; - Object user = request.getSession().getAttribute("semoss_user"); - if(user != null) - semossUser = (User2)user; - else - { - semossUser = new User2(); - if(twitToken != null) - semossUser.setAccessToken(twitToken); - if(googAppToken != null) - semossUser.setAccessToken(googAppToken); - - } - - semossUser.setAccessToken(token); - - request.getSession().setAttribute("semoss_user",semossUser); + Object vp = ts.execute((User2)request.getSession().getAttribute(Constants.SESSION_USER), params2); } @GET @Produces("application/json") @Path("/login/producthunt") - public Response loginProducthunt(@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException - { - // redirect if query string not there - - Object userObj = request.getSession().getAttribute("semoss_user"); - Hashtable ret = new Hashtable(); + public Response loginProducthunt(@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException { + /* + * Try to log in the user + * If they are not logged in + * Redirect the FE + */ + Map ret = new Hashtable(); + User2 userObj = (User2) request.getSession().getAttribute(Constants.SESSION_USER); String queryString = request.getQueryString(); - - if(queryString != null && queryString.contains("code=")) - { - if(userObj == null || ((User2)userObj).getAccessToken(AuthProvider.PRODUCT_HUNT.name()) == null) - { + if(queryString != null && queryString.contains("code=")) { + if(userObj == null || userObj.getAccessToken(AuthProvider.PRODUCT_HUNT) == null) { String [] outputs = AbstractHttpHelper.getCodes(queryString); String prefix = "producthunt_"; - - String clientId = (String)socialData.getProperty(prefix+"client_id"); - String clientSecret = (String)socialData.getProperty(prefix+"secret_key"); - String redirectUri = (String)socialData.getProperty(prefix+"redirect_uri"); + String clientId = socialData.getProperty(prefix+"client_id"); + String clientSecret = socialData.getProperty(prefix+"secret_key"); + String redirectUri = socialData.getProperty(prefix+"redirect_uri"); System.out.println(">> " + request.getQueryString()); @@ -1397,49 +965,37 @@ public Response loginProducthunt(@Context HttpServletRequest request, @Context H params.put("code", outputs[0]); params.put("grant_type", "authorization_code"); params.put("client_secret", clientSecret); - + String url = "https://api.producthunt.com/v1/oauth/token"; - - + AccessToken accessToken = AbstractHttpHelper.getAccessToken(url, params, true, true); - accessToken.setProvider(AuthProvider.PRODUCT_HUNT.name()); + accessToken.setProvider(AuthProvider.PRODUCT_HUNT); addAccessToken(accessToken, request); - + System.out.println("Access Token is.. " + accessToken.getAccess_token()); - ret.put("success", true); - // return Response.status(200).entity(WebUtility.getSO(ret)).build(); - return WebUtility.getResponse(ret, 200); - } - else - { + ret.put("success", true); + return WebUtility.getResponse(ret, 200); + } else { ret.put("success", true); ret.put("Already_Authenticated", true); - // return Response.status(200).entity(WebUtility.getSO(ret)).build(); return WebUtility.getResponse(ret, 200); - } - } - else if(userObj == null || ((User2)userObj).getAccessToken(AuthProvider.PRODUCT_HUNT.name()) == null) + else if(userObj == null || userObj.getAccessToken(AuthProvider.PRODUCT_HUNT) == null) { - // not authenticated response.setStatus(302); response.sendRedirect(getProducthuntRedirect(request)); } return null; } - private String getProducthuntRedirect(HttpServletRequest request) - throws UnsupportedEncodingException { - + private String getProducthuntRedirect(HttpServletRequest request) throws UnsupportedEncodingException { String prefix = "producthunt_"; - String clientId = (String)socialData.getProperty(prefix+"client_id"); - String clientSecret = (String)socialData.getProperty(prefix+"secret_key"); - String redirectUri = (String)socialData.getProperty(prefix+"redirect_uri"); - String scope = (String)socialData.getProperty(prefix+"scope"); + String clientId = socialData.getProperty(prefix+"client_id"); + String redirectUri = socialData.getProperty(prefix+"redirect_uri"); + String scope = socialData.getProperty(prefix+"scope"); - String redirectUrl = "https://api.producthunt.com/v1/oauth/authorize?" + "client_id=" + clientId+ "&response_type=code" + @@ -1447,94 +1003,102 @@ private String getProducthuntRedirect(HttpServletRequest request) "&scope=" + URLEncoder.encode(scope, "UTF-8") ; System.out.println("Sending redirect.. " + redirectUrl); - return redirectUrl; } - - public static void loginTwitterApp() throws IOException - { - // redirect if query string not there - Hashtable ret = new Hashtable(); + /** + * Logs user in through linkedin + */ + @GET + @Produces("application/json") + @Path("/login/linkedin") + public Response loginIn(@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException { + /* + * Try to log in the user + * If they are not logged in + * Redirect the FE + */ - // getting the bearer token on twitter for app authentication is a lot simpler - // need to just combine the id and secret - // base 64 and send as authorization + Map ret = new Hashtable(); + User2 userObj = (User2) request.getSession().getAttribute(Constants.SESSION_USER); + + String queryString = request.getQueryString(); + if(queryString != null && queryString.contains("code=")) { + if(userObj == null || userObj.getAccessToken(AuthProvider.IN) == null) { + String [] outputs = AbstractHttpHelper.getCodes(queryString); - if(twitToken == null) - { - try { - String prefix = "twitter_"; - - - String clientId = "***REMOVED***"; - String clientSecret = "***REMOVED***"; - - clientId = (String)socialData.getProperty(prefix+"client_id"); - clientSecret = (String)socialData.getProperty(prefix+"secret_key"); + String prefix = "in_"; + String clientId = socialData.getProperty(prefix+"client_id"); + String clientSecret = socialData.getProperty(prefix+"secret_key"); + String redirectUri = socialData.getProperty(prefix+"redirect_uri"); - - // make a joint string - String jointString = clientId + ":" + clientSecret; - - // encde this base 64 - String encodedJointString = new String(Base64.getEncoder().encode(jointString.getBytes())); - CloseableHttpClient httpclient = HttpClients.createDefault(); - HttpPost httppost = new HttpPost("https://api.twitter.com/oauth2/token"); - - httppost.addHeader("Authorization", "Basic " + encodedJointString); - //httppost.addHeader("Content-Type","application/json; charset=utf-8"); + System.out.println(">> " + request.getQueryString()); - List paramList = new ArrayList(); - - paramList.add(new BasicNameValuePair("grant_type", "client_credentials")); - - httppost.setEntity(new UrlEncodedFormEntity(paramList)); - - ResponseHandler handler = new BasicResponseHandler(); - CloseableHttpResponse authResp = httpclient.execute(httppost); - - System.out.println("Response Code " + authResp.getStatusLine().getStatusCode()); - - int status = authResp.getStatusLine().getStatusCode(); - - BufferedReader rd = new BufferedReader( - new InputStreamReader(authResp.getEntity().getContent())); - - StringBuffer result = new StringBuffer(); - String line = ""; - while ((line = rd.readLine()) != null) { - result.append(line); - } - - twitToken = AbstractHttpHelper.getJAccessToken(result.toString()); - twitToken.setProvider(AuthProvider.TWITTER.name()); - - //addAccessToken(twitToken, request); - - }catch(Exception ex) - { - ex.printStackTrace(); + Hashtable params = new Hashtable(); + params.put("client_id", clientId); + params.put("redirect_uri", redirectUri); + params.put("code", outputs[0]); + params.put("grant_type", "authorization_code"); + params.put("client_secret", clientSecret); + + String url = "https://www.linkedin.com/oauth/v2/accessToken"; + + AccessToken accessToken = AbstractHttpHelper.getAccessToken(url, params, true, true); + accessToken.setProvider(AuthProvider.IN); + addAccessToken(accessToken, request); + + System.out.println("Access Token is.. " + accessToken.getAccess_token()); + + ret.put("success", true); + return WebUtility.getResponse(ret, 200); + } else { + ret.put("success", true); + ret.put("Already_Authenticated", true); + return WebUtility.getResponse(ret, 200); } - System.out.println("Access Token is.. " + twitToken.getAccess_token()); - } + } + else if(userObj == null || userObj.getAccessToken(AuthProvider.IN) == null) { + response.setStatus(302); + response.sendRedirect(getInRedirect(request)); + } + return null; } - private static void loginGoogleApp() - { - // nothing big here - // set the name on accesstoken - if(googAppToken == null) - { - googAppToken = new AccessToken(); - googAppToken.setAccess_token(socialData.getProperty("google_maps_api")); - googAppToken.setProvider(AuthProvider.GOOGLE_MAP.name()); - } + private String getInRedirect(HttpServletRequest request) throws UnsupportedEncodingException { + String prefix = "in_"; + String clientId = socialData.getProperty(prefix+"client_id"); + String redirectUri = socialData.getProperty(prefix+"redirect_uri"); + String scope = socialData.getProperty(prefix+"scope"); + + String redirectUrl = "https://www.linkedin.com/oauth/v2/authorization?" + + "client_id=" + clientId + + "&redirect_uri=" + redirectUri + + "&state=" + UUID.randomUUID().toString() + + "&response_type=code" + + "&scope=" + URLEncoder.encode(scope, "UTF-8"); + + System.out.println("Sending redirect.. " + redirectUrl); + return redirectUrl; } + + + + + /** - * Logs user in through GIT + * WHY IS THIS GIT?!?!?! + * WHY IS THIS GIT?!?!?! + * WHY IS THIS GIT?!?!?! + * WHY IS THIS GIT?!?!?! + * WHY IS THIS GIT?!?!?! + * WHY IS THIS GIT?!?!?! + * WHY IS THIS GIT?!?!?! + * @param request + * @param response + * @return + * @throws IOException */ @GET @Produces("application/json") @@ -1542,7 +1106,7 @@ private static void loginGoogleApp() public Response loginTwitter(@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException { // redirect if query string not there - Object userObj = request.getSession().getAttribute("semoss_user"); + Object userObj = request.getSession().getAttribute(Constants.SESSION_USER); Hashtable ret = new Hashtable(); // getting the bearer token on twitter for app authentication is a lot simpler @@ -1555,16 +1119,16 @@ public Response loginTwitter(@Context HttpServletRequest request, @Context HttpS if(queryString != null && queryString.contains("code=")) { - if(userObj == null || ((User2)userObj).getAccessToken(AuthProvider.GIT.name()) == null) + if(userObj == null || ((User2)userObj).getAccessToken(AuthProvider.GIT) == null) { String [] outputs = AbstractHttpHelper.getCodes(queryString); String prefix = "git_"; - String clientId = (String)socialData.getProperty(prefix+"client_id"); - String clientSecret = (String)socialData.getProperty(prefix+"secret_key"); - String redirectUri = (String)socialData.getProperty(prefix+"redirect_uri"); + String clientId = socialData.getProperty(prefix+"client_id"); + String clientSecret = socialData.getProperty(prefix+"secret_key"); + String redirectUri = socialData.getProperty(prefix+"redirect_uri"); System.out.println(">> " + request.getQueryString()); @@ -1578,7 +1142,7 @@ public Response loginTwitter(@Context HttpServletRequest request, @Context HttpS String url = "https://github.com/login/oauth/access_token"; AccessToken accessToken = AbstractHttpHelper.getAccessToken(url, params, false, true); - accessToken.setProvider(AuthProvider.GIT.name()); + accessToken.setProvider(AuthProvider.GIT); addAccessToken(accessToken, request); System.out.println("Access Token is.. " + accessToken.getAccess_token()); @@ -1596,7 +1160,7 @@ public Response loginTwitter(@Context HttpServletRequest request, @Context HttpS } } - else if(userObj == null || ((User2)userObj).getAccessToken(AuthProvider.GIT.name()) == null) + else if(userObj == null || ((User2)userObj).getAccessToken(AuthProvider.GIT) == null) { // not authenticated @@ -1606,15 +1170,13 @@ else if(userObj == null || ((User2)userObj).getAccessToken(AuthProvider.GIT.name return null; } - private String getTwitterRedirect(HttpServletRequest request) - throws UnsupportedEncodingException { - + private String getTwitterRedirect(HttpServletRequest request) throws UnsupportedEncodingException { String prefix = "twitter_"; - String clientId = (String)socialData.getProperty(prefix+"client_id"); - String clientSecret = (String)socialData.getProperty(prefix+"secret_key"); - String redirectUri = (String)socialData.getProperty(prefix+"redirect_uri"); - String scope = (String)socialData.getProperty(prefix+"scope"); + String clientId = socialData.getProperty(prefix+"client_id"); + String clientSecret = socialData.getProperty(prefix+"secret_key"); + String redirectUri = socialData.getProperty(prefix+"redirect_uri"); + String scope = socialData.getProperty(prefix+"scope"); String nonce = UUID.randomUUID().toString() ; String timestamp = System.currentTimeMillis() +""; @@ -1644,156 +1206,19 @@ private String getTwitterRedirect(HttpServletRequest request) return redirectUrl; } - - /** - * Logs user in through GIT - */ - @GET - @Produces("application/json") - @Path("/login/linkedin") - public Response loginIn(@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException - { - // redirect if query string not there - Object userObj = request.getSession().getAttribute("semoss_user"); - Hashtable ret = new Hashtable(); - - //https://developer.github.com/apps/building-oauth-apps/authorization-options-for-oauth-apps/ - String queryString = request.getQueryString(); - - if(queryString != null && queryString.contains("code=")) - { - if(userObj == null || ((User2)userObj).getAccessToken(AuthProvider.IN.name()) == null) - { - - String [] outputs = AbstractHttpHelper.getCodes(queryString); - - String prefix = "in_"; - - String clientId = (String)socialData.getProperty(prefix+"client_id"); - String clientSecret = (String)socialData.getProperty(prefix+"secret_key"); - String redirectUri = (String)socialData.getProperty(prefix+"redirect_uri"); - - System.out.println(">> " + request.getQueryString()); - - Hashtable params = new Hashtable(); - params.put("client_id", clientId); - params.put("redirect_uri", redirectUri); - params.put("code", outputs[0]); - params.put("grant_type", "authorization_code"); - params.put("client_secret", clientSecret); - - String url = "https://www.linkedin.com/oauth/v2/accessToken"; - - AccessToken accessToken = AbstractHttpHelper.getAccessToken(url, params, true, true); - accessToken.setProvider(AuthProvider.IN.name()); - addAccessToken(accessToken, request); - - System.out.println("Access Token is.. " + accessToken.getAccess_token()); - - ret.put("success", true); - // return Response.status(200).entity(WebUtility.getSO(ret)).build(); - return WebUtility.getResponse(ret, 200); - } - else - { - ret.put("success", true); - ret.put("Already_Authenticated", true); - // return Response.status(200).entity(WebUtility.getSO(ret)).build(); - return WebUtility.getResponse(ret, 200); - - } - } - else if(userObj == null || ((User2)userObj).getAccessToken(AuthProvider.IN.name()) == null) - { - // not authenticated - - response.setStatus(302); - response.sendRedirect(getInRedirect(request)); - } - return null; - } - - private String getInRedirect(HttpServletRequest request) - throws UnsupportedEncodingException { - - String prefix = "in_"; - - String clientId = (String)socialData.getProperty(prefix+"client_id"); - String clientSecret = (String)socialData.getProperty(prefix+"secret_key"); - String redirectUri = (String)socialData.getProperty(prefix+"redirect_uri"); - String scope = (String)socialData.getProperty(prefix+"scope"); - - String redirectUrl = "https://www.linkedin.com/oauth/v2/authorization?" + - "client_id=" + clientId + - "&redirect_uri=" + redirectUri + - "&state=" + UUID.randomUUID().toString() + - "&response_type=code" + - "&scope=" + URLEncoder.encode(scope, "UTF-8"); - - System.out.println("Sending redirect.. " + redirectUrl); - - return redirectUrl; - } - - - public static String calculateRFC2104HMAC(String data, String key) - throws SignatureException, NoSuchAlgorithmException, InvalidKeyException - { - SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), "HmacSHA1"); - Mac mac = Mac.getInstance("HmacSHA1"); - mac.init(signingKey); - return toHexString(mac.doFinal(data.getBytes())); - } - - private static String toHexString(byte[] bytes) { - Formatter formatter = new Formatter(); - - for (byte b : bytes) { - formatter.format("%02x", b); - } - - return formatter.toString(); - } - - @GET - @Produces("application/json") - @Path("/logout/{provider}") - public Response logout(@PathParam("provider") String provider, @Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException - { - boolean removed = false; - if(provider.equalsIgnoreCase("ALL")) { - // remove the user from session call it a day - request.getSession().removeAttribute("semoss_user"); - removed = true; - } else { - User2 thisUser = (User2)request.getSession().getAttribute("semoss_user"); - removed = thisUser.dropAccessToken(provider.toUpperCase()); - request.getSession().setAttribute("semoss_user", thisUser); - } - - Hashtable ret = new Hashtable(); - ret.put("success", removed); - return WebUtility.getResponse(ret, 200); - } - - -// /** -// * Logs user in through Google+. -// */ -// @POST -// @Produces("application/json") -// @Path("/login/github") -// public Response loginGithub(@Context HttpServletRequest request) throws IOException { -// final String YOUR_API_KEY = "0d45001167302b65c68f"; // client id -// final String YOUR_API_SECRET = "***REMOVED***"; // client secret -// -// OAuthService service = new ServiceBuilder(YOUR_API_KEY) -// .apiSecret(YOUR_API_SECRET) -// .build(GitHubApi.instance()); -// -// System.out.println(service); -// -// return WebUtility.getResponse(true, 200); +// public static String calculateRFC2104HMAC(String data, String key) throws SignatureException, NoSuchAlgorithmException, InvalidKeyException { +// SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), "HmacSHA1"); +// Mac mac = Mac.getInstance("HmacSHA1"); +// mac.init(signingKey); +// return toHexString(mac.doFinal(data.getBytes())); // } - +// +// private static String toHexString(byte[] bytes) { +// Formatter formatter = new Formatter(); +// for (byte b : bytes) { +// formatter.format("%02x", b); +// } +// return formatter.toString(); +// } + } diff --git a/src/prerna/upload/DatabaseUploader.java b/src/prerna/upload/DatabaseUploader.java index 2d4f75351..66d4e13c0 100644 --- a/src/prerna/upload/DatabaseUploader.java +++ b/src/prerna/upload/DatabaseUploader.java @@ -35,7 +35,8 @@ import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; -import prerna.auth.User; +import prerna.auth.AuthProvider; +import prerna.auth.User2; import prerna.auth.UserPermissionsMasterDB; import prerna.engine.impl.SmssUtilities; import prerna.engine.impl.solr.SolrEngine; @@ -601,9 +602,10 @@ public Response uploadCSVFile(MultivaluedMap form, @Context Http // add engine owner for permissions if(this.securityEnabled) { - Object user = request.getSession().getAttribute(Constants.SESSION_USER); - if(user != null && !((User) user).getId().equals(Constants.ANONYMOUS_USER_ID)) { - addEngineOwner(options.getDbName(), ((User) user).getId()); + User2 user = (User2) request.getSession().getAttribute("semoss_user"); + String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); + if(user != null && !userId.equals(Constants.ANONYMOUS_USER_ID)) { + addEngineOwner(options.getEngineID(), options.getDbName(), userId); } else { Map errorHash = new HashMap(); errorHash.put("errorMessage", "Please log in to upload data."); @@ -935,9 +937,10 @@ public Response processExcelFile(@Context HttpServletRequest request) // add engine owner for permissions if(this.securityEnabled) { - Object user = request.getSession().getAttribute(Constants.SESSION_USER); - if(user != null && !((User) user).getId().equals(Constants.ANONYMOUS_USER_ID)) { - addEngineOwner(options.getDbName(), ((User) user).getId()); + User2 user = (User2) request.getSession().getAttribute("semoss_user"); + String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); + if(user != null && !userId.equals(Constants.ANONYMOUS_USER_ID)) { + addEngineOwner(options.getEngineID(), options.getDbName(), userId); } else { Map errorHash = new HashMap(); errorHash.put("errorMessage", "Please log in to upload data."); @@ -1026,9 +1029,10 @@ public Response uploadExcelPOIFormat(@Context HttpServletRequest request) // add engine owner for permissions if(this.securityEnabled) { - Object user = request.getSession().getAttribute(Constants.SESSION_USER); - if(user != null && !((User) user).getId().equals(Constants.ANONYMOUS_USER_ID)) { - addEngineOwner(options.getDbName(), ((User) user).getId()); + User2 user = (User2) request.getSession().getAttribute("semoss_user"); + String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); + if(user != null && !userId.equals(Constants.ANONYMOUS_USER_ID)) { + addEngineOwner(options.getEngineID(), options.getDbName(), userId); } else { Map errorHash = new HashMap(); errorHash.put("errorMessage", "Please log in to upload data."); @@ -1226,9 +1230,10 @@ public Response uploadNLPFile(@Context HttpServletRequest request) { // add engine owner for permissions if(this.securityEnabled) { - Object user = request.getSession().getAttribute(Constants.SESSION_USER); - if(user != null && !((User) user).getId().equals(Constants.ANONYMOUS_USER_ID)) { - addEngineOwner(options.getDbName(), ((User) user).getId()); + User2 user = (User2) request.getSession().getAttribute("semoss_user"); + String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); + if(user != null && !userId.equals(Constants.ANONYMOUS_USER_ID)) { + addEngineOwner(options.getEngineID(), options.getDbName(), userId); } else { Map errorHash = new HashMap(); errorHash.put("errorMessage", "Please log in to upload data."); @@ -1417,19 +1422,20 @@ public Response connectExistingRDBMS(@Context HttpServletRequest request, Multiv options.put("dbName", Utility.makeAlphaNumeric(databaseOptions.get("databaseName"))); ImportOptions importOptions = setupImportOptionsForExternalConnection(options, metamodel); + String appID = UUID.randomUUID().toString(); + importOptions.setEngineID(appID); // add engine owner for permissions if(this.securityEnabled) { - Object user = request.getSession().getAttribute(Constants.SESSION_USER); - if(user != null && !((User) user).getId().equals(Constants.ANONYMOUS_USER_ID)) { - addEngineOwner(options.get("dbName") + "", ((User) user).getId()); + User2 user = (User2) request.getSession().getAttribute("semoss_user"); + String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); + if(user != null && !userId.equals(Constants.ANONYMOUS_USER_ID)) { + addEngineOwner(appID, options.get("dbName"), userId); } else { Map errorHash = new HashMap(); errorHash.put("errorMessage", "Please log in to upload data."); return Response.status(400).entity(gson.toJson(errorHash)).build(); } } - String appID = UUID.randomUUID().toString(); - importOptions.setEngineID(appID); boolean success = true; try { @@ -1523,9 +1529,9 @@ private String processOpenRefine(String dbName, String cleanedValues) { return filename; } - public void addEngineOwner(String engine, String userId) { + public void addEngineOwner(String engineId, String engine, String userId) { UserPermissionsMasterDB masterDB = new UserPermissionsMasterDB(); - masterDB.addEngineAndOwner(engine, userId); + masterDB.addEngineAndOwner(engineId, engine, userId); } @POST diff --git a/src/prerna/web/conf/CACFilter.java b/src/prerna/web/conf/CACFilter.java index ecabd4825..50f7d1ddc 100644 --- a/src/prerna/web/conf/CACFilter.java +++ b/src/prerna/web/conf/CACFilter.java @@ -33,7 +33,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 user = new User2(); AccessToken token = new AccessToken(); - token.setProvider(AuthProvider.CAC.toString()); + token.setProvider(AuthProvider.CAC); for(int i = 0; i < certs.length; i++) { X509Certificate cert = certs[i]; diff --git a/src/prerna/web/conf/UserDBFilter.java b/src/prerna/web/conf/UserDBFilter.java index 58f8dd215..295d62ea8 100644 --- a/src/prerna/web/conf/UserDBFilter.java +++ b/src/prerna/web/conf/UserDBFilter.java @@ -46,8 +46,8 @@ import com.ibm.icu.util.StringTokenizer; import it.unimi.dsi.util.Properties; -import prerna.auth.User; -import prerna.auth.User.LOGIN_TYPES; +//import prerna.auth.User; +//import prerna.auth.User.LOGIN_TYPES; import prerna.auth.UserPermissionsMasterDB; import prerna.util.Constants; import prerna.util.DIHelper; @@ -55,7 +55,7 @@ public class UserDBFilter implements Filter { FilterConfig config; - User user = new User(Constants.ANONYMOUS_USER_ID, "Anonymous", LOGIN_TYPES.ANONYMOUS, "Anonymous"); +// User user = new User(Constants.ANONYMOUS_USER_ID, "Anonymous", LOGIN_TYPES.ANONYMOUS, "Anonymous"); @Override public void destroy() { @@ -71,13 +71,13 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, ServletContext context = getFilterConfig().getServletContext(); boolean securityEnabled = Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED)); HttpSession session = ((HttpServletRequest)arg0).getSession(false); - if(session != null) { - if(session.getAttribute(Constants.SESSION_USER) == null) { - session.setAttribute(Constants.SESSION_USER, user); - } else { - user = (User) session.getAttribute(Constants.SESSION_USER); - } - } +// if(session != null) { +// if(session.getAttribute(Constants.SESSION_USER) == null) { +// session.setAttribute(Constants.SESSION_USER, user); +// } else { +// user = (User) session.getAttribute(Constants.SESSION_USER); +// } +// } boolean dbInitialized = session != null && session.getAttribute(Constants.ENGINES+"unused") != null; if(!dbInitialized) // this is our new friend { @@ -85,7 +85,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, session = ((HttpServletRequest)arg0).getSession(true); if(securityEnabled) { UserPermissionsMasterDB permissions = new UserPermissionsMasterDB(); - userEngines = permissions.getUserAccessibleEngines(user.getId()); +// userEngines = permissions.getUserAccessibleEngines(user.getId()); } // get all the engines and add the top engines String engineNames = (String)DIHelper.getInstance().getLocalProp(Constants.ENGINES); diff --git a/src/prerna/web/conf/UserDBInsightFilter.java b/src/prerna/web/conf/UserDBInsightFilter.java index f750971a4..36540bf10 100644 --- a/src/prerna/web/conf/UserDBInsightFilter.java +++ b/src/prerna/web/conf/UserDBInsightFilter.java @@ -44,11 +44,12 @@ import com.google.gson.internal.StringMap; -import prerna.auth.User; +//import prerna.auth.User; import prerna.auth.UserPermissionsMasterDB; import prerna.util.Constants; public class UserDBInsightFilter implements Filter { + FilterConfig config; String engineAPIPath = "/e-"; @@ -58,32 +59,32 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 HttpSession session = ((HttpServletRequest)arg0).getSession(true); boolean securityEnabled = Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED)); - if(securityEnabled) { - HttpServletRequest request = (HttpServletRequest) arg0; - String requestURI = request.getRequestURI(); - if(requestURI.contains(engineAPIPath)) { - String requestPathWithEngine = requestURI.substring(requestURI.indexOf(engineAPIPath) + engineAPIPath.length()); - String engineName = requestPathWithEngine.substring(0, requestPathWithEngine.indexOf("/")); - - User user = ((User) session.getAttribute(Constants.SESSION_USER)); - String userId = ""; - if(user!= null) { - userId = user.getId(); - } - UserPermissionsMasterDB permissions = new UserPermissionsMasterDB(); - HashSet userEngines = permissions.getUserAccessibleEngines(userId); - if(!engineName.equals(Constants.LOCAL_MASTER_DB_NAME) && !userEngines.contains(engineName)) { - StringMap> insightPermissions = permissions.getInsightPermissionsForUser(userId); - - if(!insightPermissions.containsKey(engineName)) { - HttpServletResponse response = (HttpServletResponse) arg1; - response.addHeader("userId", userId); - response.sendError(HttpServletResponse.SC_UNAUTHORIZED); - return; - } - } - } - } +// if(securityEnabled) { +// HttpServletRequest request = (HttpServletRequest) arg0; +// String requestURI = request.getRequestURI(); +// if(requestURI.contains(engineAPIPath)) { +// String requestPathWithEngine = requestURI.substring(requestURI.indexOf(engineAPIPath) + engineAPIPath.length()); +// String engineName = requestPathWithEngine.substring(0, requestPathWithEngine.indexOf("/")); +// +// User user = ((User) session.getAttribute(Constants.SESSION_USER)); +// String userId = ""; +// if(user!= null) { +// userId = user.getId(); +// } +// UserPermissionsMasterDB permissions = new UserPermissionsMasterDB(); +// HashSet userEngines = permissions.getUserAccessibleEngines(userId); +// if(!engineName.equals(Constants.LOCAL_MASTER_DB_NAME) && !userEngines.contains(engineName)) { +// StringMap> insightPermissions = permissions.getInsightPermissionsForUser(userId); +// +// if(!insightPermissions.containsKey(engineName)) { +// HttpServletResponse response = (HttpServletResponse) arg1; +// response.addHeader("userId", userId); +// response.sendError(HttpServletResponse.SC_UNAUTHORIZED); +// return; +// } +// } +// } +// } arg2.doFilter(arg0, arg1); } diff --git a/src/prerna/web/conf/UserSessionLoader.java b/src/prerna/web/conf/UserSessionLoader.java index 077ec63d5..f321fcd84 100644 --- a/src/prerna/web/conf/UserSessionLoader.java +++ b/src/prerna/web/conf/UserSessionLoader.java @@ -8,8 +8,8 @@ import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; -import prerna.auth.User; -import prerna.auth.User.LOGIN_TYPES; +//import prerna.auth.User; +//import prerna.auth.User.LOGIN_TYPES; import prerna.auth.UserPermissionsMasterDB; import prerna.ds.h2.H2Frame; import prerna.ds.r.RDataTable; @@ -23,7 +23,7 @@ public class UserSessionLoader implements HttpSessionListener { public void sessionCreated(HttpSessionEvent sessionEvent) { - sessionEvent.getSession().setAttribute(Constants.SESSION_USER, new User(Constants.ANONYMOUS_USER_ID, "Anonymous", LOGIN_TYPES.ANONYMOUS, "Anonymous")); +// sessionEvent.getSession().setAttribute(Constants.SESSION_USER, new User(Constants.ANONYMOUS_USER_ID, "Anonymous", LOGIN_TYPES.ANONYMOUS, "Anonymous")); } public void sessionDestroyed(HttpSessionEvent sessionEvent) { @@ -50,19 +50,19 @@ public void sessionDestroyed(HttpSessionEvent sessionEvent) { String inEngine = in.getEngineName(); String inRdbmsId = in.getRdbmsId(); - if(inEngine != null && inRdbmsId != null) { - HttpSession session = sessionEvent.getSession(); - User user = ((User) session.getAttribute(Constants.SESSION_USER)); - String userId = ""; - if(user!= null) { - userId = user.getId(); - } - - UserPermissionsMasterDB permissions = new UserPermissionsMasterDB(); - isReadOnlyInsight = permissions.isUserReadOnlyInsights(userId, inEngine, inRdbmsId); - } - - if(!isReadOnlyInsight) { +// if(inEngine != null && inRdbmsId != null) { +// HttpSession session = sessionEvent.getSession(); +// User user = ((User) session.getAttribute(Constants.SESSION_USER)); +// String userId = ""; +// if(user!= null) { +// userId = user.getId(); +// } +// +// UserPermissionsMasterDB permissions = new UserPermissionsMasterDB(); +// isReadOnlyInsight = permissions.isUserReadOnlyInsights(userId, inEngine, inRdbmsId); +// } +// +// if(!isReadOnlyInsight) { IDataMaker dm = in.getDataMaker(); if(dm instanceof H2Frame) { H2Frame frame = (H2Frame)dm; @@ -84,7 +84,7 @@ public void sessionDestroyed(HttpSessionEvent sessionEvent) { inStore.remove(id); inStore.removeFromSessionHash(sessionID, id); - } +// } } System.out.println("successfully removed qStore information for session"); } From f5d608ce0119ee76303139f1e031f6ac9576faeb Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 12 Jun 2018 16:43:44 +0000 Subject: [PATCH 0081/1906] UPDATE ::: Switching name of User2 to User and subsequent method names within code git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28648 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 2790a39a19aa589ed4bed09edbecaad59fbc6cf4 --- .../web/services/AuthorizationResource.java | 42 +++++++-------- .../semoss/web/services/EngineResource.java | 8 +-- .../semoss/web/services/NameServer.java | 22 ++++---- .../semoss/web/services/UserResource.java | 52 +++++++++---------- src/prerna/upload/DatabaseUploader.java | 12 ++--- src/prerna/web/conf/CACFilter.java | 6 +-- 6 files changed, 71 insertions(+), 71 deletions(-) diff --git a/src/prerna/semoss/web/services/AuthorizationResource.java b/src/prerna/semoss/web/services/AuthorizationResource.java index e2e8083ee..f24f0b67a 100644 --- a/src/prerna/semoss/web/services/AuthorizationResource.java +++ b/src/prerna/semoss/web/services/AuthorizationResource.java @@ -49,7 +49,7 @@ import com.google.gson.internal.StringMap; import prerna.auth.AuthProvider; -import prerna.auth.User2; +import prerna.auth.User; import prerna.auth.UserPermissionsMasterDB; import prerna.util.Constants; import prerna.web.services.util.WebUtility; @@ -90,7 +90,7 @@ public Response getGroupsAndMembers(@Context HttpServletRequest request) { return WebUtility.getResponse(errorMap, 401); } - User2 user = (User2) request.getSession().getAttribute("semoss_user"); + User user = (User) request.getSession().getAttribute("semoss_user"); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); ArrayList> ret = permissions.getGroupsAndMembersForUser(userId); @@ -123,7 +123,7 @@ public Response getDatabases(@Context HttpServletRequest request) { return WebUtility.getResponse(errorMap, 401); } try{ - User2 user = (User2) request.getSession().getAttribute("semoss_user"); + User user = (User) request.getSession().getAttribute("semoss_user"); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); ret = permissions.getUserDatabases(userId, false); return WebUtility.getResponse(ret, 200); @@ -150,7 +150,7 @@ public Response getAdminDatabases(@Context HttpServletRequest request) { Hashtable errorRet = new Hashtable(); ArrayList> ret = new ArrayList<>(); try{ - User2 user = (User2) request.getSession().getAttribute("semoss_user"); + User user = (User) request.getSession().getAttribute("semoss_user"); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); ret = permissions.getUserDatabases(userId, true); return WebUtility.getResponse(ret, 200); @@ -177,7 +177,7 @@ public Response getAdminDatabaseUsersAndGroups(@Context HttpServletRequest reque Hashtable errorRet = new Hashtable(); StringMap>> ret = new StringMap<>(); try{ - User2 user = (User2) request.getSession().getAttribute("semoss_user"); + User user = (User) request.getSession().getAttribute("semoss_user"); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); String engineId = form.getFirst("engineId"); ret = permissions.getDatabaseUsersAndGroups(userId, engineId, true); @@ -207,7 +207,7 @@ public Response getDatabaseUsersAndGroups(@Context HttpServletRequest request, M StringMap>> ret = new StringMap<>(); try{ String engineId = form.getFirst("engineId"); - User2 user = (User2) request.getSession().getAttribute("semoss_user"); + User user = (User) request.getSession().getAttribute("semoss_user"); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); ret = permissions.getDatabaseUsersAndGroups(userId, engineId, false); return WebUtility.getResponse(ret, 200); @@ -228,7 +228,7 @@ public Response getDatabaseUsersAndGroups(@Context HttpServletRequest request, M public Response addNewGroup(@Context HttpServletRequest request, MultivaluedMap form) { Gson gson = new Gson(); ArrayList users = gson.fromJson(form.getFirst("users"), ArrayList.class); - User2 user = (User2) request.getSession().getAttribute("semoss_user"); + User user = (User) request.getSession().getAttribute("semoss_user"); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); Boolean success = permissions.addGroup(userId, form.getFirst("groupName").trim(), users); @@ -244,7 +244,7 @@ public Response addNewGroup(@Context HttpServletRequest request, MultivaluedMap< @Path("removeGroup") public Response removeGroup(@Context HttpServletRequest request, MultivaluedMap form) { String groupId = form.getFirst("groupId").trim(); - User2 user = (User2) request.getSession().getAttribute("semoss_user"); + User user = (User) request.getSession().getAttribute("semoss_user"); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); Boolean success = permissions.removeGroup(userId, groupId); @@ -265,7 +265,7 @@ public Response editGroup(@Context HttpServletRequest request, MultivaluedMap toAdd = gson.fromJson(form.getFirst("add"), ArrayList.class); ArrayList toRemove = gson.fromJson(form.getFirst("remove"), ArrayList.class); - User2 user = (User2) request.getSession().getAttribute("semoss_user"); + User user = (User) request.getSession().getAttribute("semoss_user"); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); for(String add : toAdd) { @@ -285,7 +285,7 @@ public Response savePermissions(@Context HttpServletRequest request, Multivalued Gson gson = new Gson(); Hashtable errorRet = new Hashtable(); try{ - User2 user = (User2) request.getSession().getAttribute("semoss_user"); + User user = (User) request.getSession().getAttribute("semoss_user"); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); String engineId = form.getFirst("engineId").trim(); StringMap>> groups = gson.fromJson(form.getFirst("groups"), StringMap.class); @@ -309,7 +309,7 @@ public Response savePermissions(@Context HttpServletRequest request, Multivalued public Response isUserGroupAddedValid(@Context HttpServletRequest request, MultivaluedMap form) { Gson gson = new Gson(); try { - User2 user = (User2) request.getSession().getAttribute("semoss_user"); + User user = (User) request.getSession().getAttribute("semoss_user"); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); String ret = "true"; @@ -350,7 +350,7 @@ public Response isUserGroupAddedValid(@Context HttpServletRequest request, Multi public Response isUserAddedToGroupValid(@Context HttpServletRequest request, MultivaluedMap form) { Gson gson = new Gson(); try { - User2 user = (User2) request.getSession().getAttribute("semoss_user"); + User user = (User) request.getSession().getAttribute("semoss_user"); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); String ret = ""; @@ -398,7 +398,7 @@ public Response isAdminUser(@Context HttpServletRequest request) { } if(session.getAttribute("semoss_user") != null) { - User2 user = (User2) request.getSession().getAttribute("semoss_user"); + User user = (User) request.getSession().getAttribute("semoss_user"); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); if(!userId.equals(Constants.ANONYMOUS_USER_ID) && permissions.isUserAdmin(userId)) { return WebUtility.getResponse(true, 200); @@ -414,7 +414,7 @@ public Response isAdminUser(@Context HttpServletRequest request) { public Response getAllDbUsers(@Context HttpServletRequest request) { ArrayList> ret = new ArrayList<>(); Hashtable errorRet = new Hashtable(); - User2 user = (User2) request.getSession().getAttribute("semoss_user"); + User user = (User) request.getSession().getAttribute("semoss_user"); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); try{ ret = permissions.getAllDbUsers(userId); @@ -434,7 +434,7 @@ public Response getAllDbUsers(@Context HttpServletRequest request) { public Response removeUserPermissionsbyDbId(@Context HttpServletRequest request, MultivaluedMap form) { boolean ret = false; Hashtable errorRet = new Hashtable(); - User2 user = (User2) request.getSession().getAttribute("semoss_user"); + User user = (User) request.getSession().getAttribute("semoss_user"); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); String engineId = form.getFirst("engineId"); try{ @@ -463,7 +463,7 @@ public Response editUser(@Context HttpServletRequest request, MultivaluedMap errorRet = new Hashtable(); try{ - User2 user = (User2) request.getSession().getAttribute("semoss_user"); + User user = (User) request.getSession().getAttribute("semoss_user"); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); StringMap userInfo = gson.fromJson(form.getFirst("user"), StringMap.class); ret = permissions.editUser(userId, userInfo); @@ -487,7 +487,7 @@ public Response savePermissionsAdmin(@Context HttpServletRequest request, Multiv Hashtable errorRet = new Hashtable(); try{ - User2 user = (User2) request.getSession().getAttribute("semoss_user"); + User user = (User) request.getSession().getAttribute("semoss_user"); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); String engineId = form.getFirst("engineId").trim(); StringMap>> groups = gson.fromJson(form.getFirst("groups"), StringMap.class); @@ -511,7 +511,7 @@ public Response savePermissionsAdmin(@Context HttpServletRequest request, Multiv public Response setDbVisibility(@Context HttpServletRequest request, MultivaluedMap form) { Hashtable errorRet = new Hashtable(); try{ - User2 user = (User2) request.getSession().getAttribute("semoss_user"); + User user = (User) request.getSession().getAttribute("semoss_user"); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); String engineId = form.getFirst("engineId"); String visibility = form.getFirst("visibility"); @@ -534,7 +534,7 @@ public Response setDbVisibility(@Context HttpServletRequest request, Multivalued public Response setAdminDbPublic(@Context HttpServletRequest request, MultivaluedMap form) { Hashtable errorRet = new Hashtable(); try{ - User2 user = (User2) request.getSession().getAttribute("semoss_user"); + User user = (User) request.getSession().getAttribute("semoss_user"); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); String engineId = form.getFirst("engineId"); String isPublic = form.getFirst("public"); @@ -557,7 +557,7 @@ public Response setAdminDbPublic(@Context HttpServletRequest request, Multivalue public Response setDbPublic(@Context HttpServletRequest request, MultivaluedMap form) { Hashtable errorRet = new Hashtable(); try{ - User2 user = (User2) request.getSession().getAttribute("semoss_user"); + User user = (User) request.getSession().getAttribute("semoss_user"); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); String engineId = form.getFirst("engineId"); String isPublic = form.getFirst("public"); @@ -580,7 +580,7 @@ public Response setDbPublic(@Context HttpServletRequest request, MultivaluedMap< public Response deleteUser(@Context HttpServletRequest request, MultivaluedMap form) { Hashtable errorRet = new Hashtable(); try{ - User2 user = (User2) request.getSession().getAttribute("semoss_user"); + User user = (User) request.getSession().getAttribute("semoss_user"); String adminId = user.getAccessToken(AuthProvider.NATIVE).getId(); String userId = form.getFirst("userId"); permissions.deleteUser(adminId, userId); diff --git a/src/prerna/semoss/web/services/EngineResource.java b/src/prerna/semoss/web/services/EngineResource.java index 715a31baf..9cd604074 100644 --- a/src/prerna/semoss/web/services/EngineResource.java +++ b/src/prerna/semoss/web/services/EngineResource.java @@ -50,7 +50,7 @@ import com.google.gson.reflect.TypeToken; import prerna.auth.AuthProvider; -import prerna.auth.User2; +import prerna.auth.User; import prerna.engine.api.IEngine; import prerna.engine.api.IEngine.ENGINE_TYPE; import prerna.engine.api.IRawSelectWrapper; @@ -190,7 +190,7 @@ public Response getInsightParams(@QueryParam("insight") String insightId) public Response createOutput(MultivaluedMap form, @Context HttpServletRequest request) { HttpSession session = request.getSession(true); - User2 user = ((User2) session.getAttribute(Constants.SESSION_USER)); + User user = ((User) session.getAttribute(Constants.SESSION_USER)); Gson gson = new Gson(); String insightId = form.getFirst("insight"); @@ -208,7 +208,7 @@ public Response createOutput(MultivaluedMap form, @Context HttpS InsightStore.getInstance().put(dummyIn); InsightStore.getInstance().addToSessionHash(session.getId(), dummyIn.getInsightId()); dummyIn.getVarStore().put(JobReactor.SESSION_KEY, new NounMetadata(session.getId(), PixelDataType.CONST_STRING)); - dummyIn.setUser2(user); + dummyIn.setUser(user); playsheetRunReactor.setInsight(dummyIn); PixelPlanner planner = new PixelPlanner(); planner.setVarStore(dummyIn.getVarStore()); @@ -237,7 +237,7 @@ public Response commitFormData(@Context HttpServletRequest request, MultivaluedM String userId = null; try { HttpSession session = ((HttpServletRequest)request).getSession(false); - User2 user = (User2) session.getAttribute("semoss_user"); + User user = (User) session.getAttribute("semoss_user"); userId = user.getAccessToken(AuthProvider.CAC).getName(); } catch(Exception e) { Map err = new HashMap(); diff --git a/src/prerna/semoss/web/services/NameServer.java b/src/prerna/semoss/web/services/NameServer.java index f30e50775..449d6a167 100644 --- a/src/prerna/semoss/web/services/NameServer.java +++ b/src/prerna/semoss/web/services/NameServer.java @@ -83,7 +83,7 @@ import com.google.gson.reflect.TypeToken; import prerna.auth.AuthProvider; -import prerna.auth.User2; +import prerna.auth.User; import prerna.auth.UserPermissionsMasterDB; import prerna.engine.api.IEngine; import prerna.engine.impl.rdf.RemoteSemossSesameEngine; @@ -439,7 +439,7 @@ public StreamingOutput getSearchInsightsResults(MultivaluedMap f if(securityEnabled) { HttpSession session = request.getSession(false); - User2 user = ((User2) session.getAttribute("semoss_user")); + User user = ((User) session.getAttribute(Constants.SESSION_USER)); if(user!= null) { userId = user.getAccessToken(AuthProvider.NATIVE).getId(); } @@ -726,7 +726,7 @@ public Response getMetamodel(@Context HttpServletRequest request, @QueryParam("e Map ret = new HashMap(); if(Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED))) { - User2 user = (User2) request.getSession().getAttribute("semoss_user"); + User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); HashMap> metamodelFilter = new HashMap>(); if(permissions.getMetamodelSeedsForUser(userId).get(engineName) != null) { @@ -941,7 +941,7 @@ else if(insightID.equals("new")) // existingInsight = new Insight(null, dataFrameType, "Grid"); existingInsight = new Insight(); // set the user id into the insight - existingInsight.setUser2( ((User2) request.getSession().getAttribute(Constants.SESSION_USER)) ); + existingInsight.setUser( ((User) request.getSession().getAttribute(Constants.SESSION_USER)) ); InsightStore.getInstance().put(existingInsight); } // else if(insightID.equals("newDashboard")) { @@ -1070,7 +1070,7 @@ public Response runPixelSync(MultivaluedMap form, @Context HttpS HttpSession session; String sessionId; - User2 user2; + User user; boolean securityEnabled = Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED)); //If security is enabled try to get an existing session. @@ -1079,7 +1079,7 @@ public Response runPixelSync(MultivaluedMap form, @Context HttpS session = request.getSession(false); if(session != null){ sessionId = session.getId(); - user2 = ((User2) session.getAttribute("semoss_user")); + user = ((User) session.getAttribute(Constants.SESSION_USER)); } else { Map errorMap = new HashMap(); errorMap.put("error", "User session is invalid"); @@ -1088,7 +1088,7 @@ public Response runPixelSync(MultivaluedMap form, @Context HttpS } } else { session = request.getSession(true); - user2 = ((User2) session.getAttribute("semoss_user")); + user = ((User) session.getAttribute(Constants.SESSION_USER)); sessionId = session.getId(); } @@ -1133,7 +1133,7 @@ public Response runPixelSync(MultivaluedMap form, @Context HttpS } synchronized(insight) { // set the user - insight.setUser2(user2); + insight.setUser(user); JobManager manager = JobManager.getManager(); JobThread jt = null; if(insightId.equals(tempInsightId)) { @@ -1162,10 +1162,10 @@ public Response runPixelSync(MultivaluedMap form, @Context HttpS public Response runPixelAsync(MultivaluedMap form, @Context HttpServletRequest request) { boolean securityEnabled = Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED)); HttpSession session = null; - User2 user2 = null; + User user = null; if(securityEnabled){ session = request.getSession(false); - user2 = ((User2) session.getAttribute("semoss_user")); + user = ((User) session.getAttribute(Constants.SESSION_USER)); } else { session = request.getSession(true); } @@ -1208,7 +1208,7 @@ public Response runPixelAsync(MultivaluedMap form, @Context Http if(insight != null) { synchronized(insight) { - insight.setUser2(user2); + insight.setUser(user); JobManager manager = JobManager.getManager(); JobThread jt = manager.makeJob(); jobId = jt.getJobId(); diff --git a/src/prerna/semoss/web/services/UserResource.java b/src/prerna/semoss/web/services/UserResource.java index 3799d5b2f..4eb471276 100644 --- a/src/prerna/semoss/web/services/UserResource.java +++ b/src/prerna/semoss/web/services/UserResource.java @@ -66,7 +66,7 @@ import prerna.auth.AccessToken; import prerna.auth.AppTokens; import prerna.auth.AuthProvider; -import prerna.auth.User2; +import prerna.auth.User; import prerna.io.connector.IConnectorIOp; import prerna.io.connector.google.GoogleEntityResolver; import prerna.io.connector.google.GoogleFileRetriever; @@ -238,7 +238,7 @@ private static void loginGoogleApp() { @GET @Path("logins") public Response getAllLogins(@Context HttpServletRequest request) { - User2 semossUser = (User2) request.getSession().getAttribute(Constants.SESSION_USER); + User semossUser = (User) request.getSession().getAttribute(Constants.SESSION_USER); List logins = new ArrayList(); if(semossUser != null) { logins = semossUser.getLogins(); @@ -258,7 +258,7 @@ public Response logout(@PathParam("provider") String provider, @Context HttpServ request.getSession().removeAttribute(Constants.SESSION_USER); removed = true; } else { - User2 thisUser = (User2) request.getSession().getAttribute(Constants.SESSION_USER); + User thisUser = (User) request.getSession().getAttribute(Constants.SESSION_USER); removed = thisUser.dropAccessToken(provider.toUpperCase()); request.getSession().setAttribute(Constants.SESSION_USER, thisUser); } @@ -274,12 +274,12 @@ public Response logout(@PathParam("provider") String provider, @Context HttpServ * @param request */ private void addAccessToken(AccessToken token, HttpServletRequest request) { - User2 semossUser = null; + User semossUser = null; Object user = request.getSession().getAttribute(Constants.SESSION_USER); if(user != null) { - semossUser = (User2)user; + semossUser = (User)user; } else { - semossUser = new User2(); + semossUser = new User(); if(twitToken != null) { semossUser.setAccessToken(twitToken); } @@ -299,7 +299,7 @@ private void addAccessToken(AccessToken token, HttpServletRequest request) { @Path("/userinfo/google") public Response userinfoGoogle(@Context HttpServletRequest request) { Map ret = new Hashtable(); - User2 user = (User2) request.getSession().getAttribute(Constants.SESSION_USER); + User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); String [] beanProps = {"name", "profile"}; String jsonPattern = "[name, picture]"; @@ -344,7 +344,7 @@ public Response userinfoGoogle(@Context HttpServletRequest request) { @Path("/userinfo/ms") public Response userinfoOneDrive(@Context HttpServletRequest request) { Map ret = new Hashtable(); - User2 user = (User2) request.getSession().getAttribute(Constants.SESSION_USER); + User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); String [] beanProps = {"name"}; String jsonPattern = "[displayName]"; @@ -378,7 +378,7 @@ public Response userinfoOneDrive(@Context HttpServletRequest request) { @Path("/userinfo/dropbox") public Response userinfoDropbox(@Context HttpServletRequest request) { Map ret = new Hashtable(); - User2 user = (User2) request.getSession().getAttribute(Constants.SESSION_USER); + User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); String [] beanProps = {"name", "profile"}; // add is done when you have a list String jsonPattern = "[name.display_name, profile_photo_url]"; @@ -422,7 +422,7 @@ public Response userinfoDropbox(@Context HttpServletRequest request) { @Path("/userinfo/git") public Response userinfoGithub(@Context HttpServletRequest request) { Map ret = new Hashtable(); - User2 user = (User2) request.getSession().getAttribute(Constants.SESSION_USER); + User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); String [] beanProps = {"name", "profile"}; // add is done when you have a list String jsonPattern = "[name,login]"; @@ -468,7 +468,7 @@ public Response loginSF(@Context HttpServletRequest request, @Context HttpServle * Redirect the FE */ - User2 userObj = (User2) request.getSession().getAttribute(Constants.SESSION_USER); + User userObj = (User) request.getSession().getAttribute(Constants.SESSION_USER); Hashtable ret = new Hashtable(); String queryString = request.getQueryString(); @@ -549,7 +549,7 @@ public Response loginGit(@Context HttpServletRequest request, @Context HttpServl */ Map ret = new Hashtable(); - User2 userObj = (User2) request.getSession().getAttribute(Constants.SESSION_USER); + User userObj = (User) request.getSession().getAttribute(Constants.SESSION_USER); String queryString = request.getQueryString(); if(queryString != null && queryString.contains("code=")) { @@ -630,11 +630,11 @@ public Response loginMS(@Context HttpServletRequest request, @Context HttpServle */ Map ret = new Hashtable(); - User2 userObj = (User2) request.getSession().getAttribute(Constants.SESSION_USER); + User userObj = (User) request.getSession().getAttribute(Constants.SESSION_USER); String queryString = request.getQueryString(); if(queryString != null && queryString.contains("code=")) { - if(userObj == null || ((User2)userObj).getAccessToken(AuthProvider.AZURE_GRAPH) == null) { + if(userObj == null || ((User)userObj).getAccessToken(AuthProvider.AZURE_GRAPH) == null) { String [] outputs = AbstractHttpHelper.getCodes(queryString); String prefix = "ms_"; @@ -717,7 +717,7 @@ public Response loginDropBox(@Context HttpServletRequest request, @Context HttpS */ Map ret = new Hashtable(); - User2 userObj = (User2) request.getSession().getAttribute(Constants.SESSION_USER); + User userObj = (User) request.getSession().getAttribute(Constants.SESSION_USER); String queryString = request.getQueryString(); if(queryString != null && queryString.contains("code=")) { @@ -798,7 +798,7 @@ public Response loginGoogle2(@Context HttpServletRequest request, @Context HttpS */ Map ret = new Hashtable(); - User2 userObj = (User2) request.getSession().getAttribute(Constants.SESSION_USER); + User userObj = (User) request.getSession().getAttribute(Constants.SESSION_USER); String queryString = request.getQueryString(); if(queryString != null && queryString.contains("code=")) { @@ -883,10 +883,10 @@ private void performGoogleOps(HttpServletRequest request, Map ret) { // get the user details IConnectorIOp prof = new GoogleProfile(); - prof.execute((User2)request.getSession().getAttribute(Constants.SESSION_USER), null); + prof.execute((User)request.getSession().getAttribute(Constants.SESSION_USER), null); IConnectorIOp lister = new GoogleListFiles(); - List fileList = (List)lister.execute((User2)request.getSession().getAttribute(Constants.SESSION_USER), null); + List fileList = (List)lister.execute((User)request.getSession().getAttribute(Constants.SESSION_USER), null); // get the file IConnectorIOp getter = new GoogleFileRetriever(); @@ -895,7 +895,7 @@ private void performGoogleOps(HttpServletRequest request, Map ret) params2.put("id", "1it40jNFcRo1ur2dHIYUk18XmXdd37j4gmJm_Sg7KLjI"); params2.put("target", "c:\\users\\pkapaleeswaran\\workspacej3\\datasets\\googlefile.csv"); - getter.execute((User2)request.getSession().getAttribute(Constants.SESSION_USER), params2); + getter.execute((User)request.getSession().getAttribute(Constants.SESSION_USER), params2); IConnectorIOp ner = new GoogleEntityResolver(); @@ -909,7 +909,7 @@ private void performGoogleOps(HttpServletRequest request, Map ret) params2.put("document", docInput); //params2.put("input", docInputShell); - ner.execute((User2)request.getSession().getAttribute(Constants.SESSION_USER), params2); + ner.execute((User)request.getSession().getAttribute(Constants.SESSION_USER), params2); try { ret.put("files", BeanFiller.getJson(fileList)); @@ -922,7 +922,7 @@ private void performGoogleOps(HttpServletRequest request, Map ret) params2 = new Hashtable(); params2.put("address", "1919 N Lynn Street, Arlington, VA"); - lat.execute((User2)request.getSession().getAttribute(Constants.SESSION_USER), params2); + lat.execute((User)request.getSession().getAttribute(Constants.SESSION_USER), params2); IConnectorIOp ts = new TwitterSearcher(); params2 = new Hashtable(); @@ -930,7 +930,7 @@ private void performGoogleOps(HttpServletRequest request, Map ret) params2.put("lang", "en"); params2.put("count", "10"); - Object vp = ts.execute((User2)request.getSession().getAttribute(Constants.SESSION_USER), params2); + Object vp = ts.execute((User)request.getSession().getAttribute(Constants.SESSION_USER), params2); } @GET @@ -944,7 +944,7 @@ public Response loginProducthunt(@Context HttpServletRequest request, @Context H */ Map ret = new Hashtable(); - User2 userObj = (User2) request.getSession().getAttribute(Constants.SESSION_USER); + User userObj = (User) request.getSession().getAttribute(Constants.SESSION_USER); String queryString = request.getQueryString(); if(queryString != null && queryString.contains("code=")) { @@ -1020,7 +1020,7 @@ public Response loginIn(@Context HttpServletRequest request, @Context HttpServle */ Map ret = new Hashtable(); - User2 userObj = (User2) request.getSession().getAttribute(Constants.SESSION_USER); + User userObj = (User) request.getSession().getAttribute(Constants.SESSION_USER); String queryString = request.getQueryString(); if(queryString != null && queryString.contains("code=")) { @@ -1119,7 +1119,7 @@ public Response loginTwitter(@Context HttpServletRequest request, @Context HttpS if(queryString != null && queryString.contains("code=")) { - if(userObj == null || ((User2)userObj).getAccessToken(AuthProvider.GIT) == null) + if(userObj == null || ((User)userObj).getAccessToken(AuthProvider.GIT) == null) { String [] outputs = AbstractHttpHelper.getCodes(queryString); @@ -1160,7 +1160,7 @@ public Response loginTwitter(@Context HttpServletRequest request, @Context HttpS } } - else if(userObj == null || ((User2)userObj).getAccessToken(AuthProvider.GIT) == null) + else if(userObj == null || ((User)userObj).getAccessToken(AuthProvider.GIT) == null) { // not authenticated diff --git a/src/prerna/upload/DatabaseUploader.java b/src/prerna/upload/DatabaseUploader.java index 66d4e13c0..24e39f045 100644 --- a/src/prerna/upload/DatabaseUploader.java +++ b/src/prerna/upload/DatabaseUploader.java @@ -36,7 +36,7 @@ import com.google.gson.reflect.TypeToken; import prerna.auth.AuthProvider; -import prerna.auth.User2; +import prerna.auth.User; import prerna.auth.UserPermissionsMasterDB; import prerna.engine.impl.SmssUtilities; import prerna.engine.impl.solr.SolrEngine; @@ -602,7 +602,7 @@ public Response uploadCSVFile(MultivaluedMap form, @Context Http // add engine owner for permissions if(this.securityEnabled) { - User2 user = (User2) request.getSession().getAttribute("semoss_user"); + User user = (User) request.getSession().getAttribute("semoss_user"); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); if(user != null && !userId.equals(Constants.ANONYMOUS_USER_ID)) { addEngineOwner(options.getEngineID(), options.getDbName(), userId); @@ -937,7 +937,7 @@ public Response processExcelFile(@Context HttpServletRequest request) // add engine owner for permissions if(this.securityEnabled) { - User2 user = (User2) request.getSession().getAttribute("semoss_user"); + User user = (User) request.getSession().getAttribute("semoss_user"); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); if(user != null && !userId.equals(Constants.ANONYMOUS_USER_ID)) { addEngineOwner(options.getEngineID(), options.getDbName(), userId); @@ -1029,7 +1029,7 @@ public Response uploadExcelPOIFormat(@Context HttpServletRequest request) // add engine owner for permissions if(this.securityEnabled) { - User2 user = (User2) request.getSession().getAttribute("semoss_user"); + User user = (User) request.getSession().getAttribute("semoss_user"); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); if(user != null && !userId.equals(Constants.ANONYMOUS_USER_ID)) { addEngineOwner(options.getEngineID(), options.getDbName(), userId); @@ -1230,7 +1230,7 @@ public Response uploadNLPFile(@Context HttpServletRequest request) { // add engine owner for permissions if(this.securityEnabled) { - User2 user = (User2) request.getSession().getAttribute("semoss_user"); + User user = (User) request.getSession().getAttribute("semoss_user"); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); if(user != null && !userId.equals(Constants.ANONYMOUS_USER_ID)) { addEngineOwner(options.getEngineID(), options.getDbName(), userId); @@ -1426,7 +1426,7 @@ public Response connectExistingRDBMS(@Context HttpServletRequest request, Multiv importOptions.setEngineID(appID); // add engine owner for permissions if(this.securityEnabled) { - User2 user = (User2) request.getSession().getAttribute("semoss_user"); + User user = (User) request.getSession().getAttribute("semoss_user"); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); if(user != null && !userId.equals(Constants.ANONYMOUS_USER_ID)) { addEngineOwner(appID, options.get("dbName"), userId); diff --git a/src/prerna/web/conf/CACFilter.java b/src/prerna/web/conf/CACFilter.java index 50f7d1ddc..16432a520 100644 --- a/src/prerna/web/conf/CACFilter.java +++ b/src/prerna/web/conf/CACFilter.java @@ -18,7 +18,7 @@ import prerna.auth.AccessToken; import prerna.auth.AuthProvider; -import prerna.auth.User2; +import prerna.auth.User; public class CACFilter implements Filter { @@ -28,9 +28,9 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 HttpSession session = ((HttpServletRequest)arg0).getSession(true); if(certs != null) { - User2 user = (User2) session.getAttribute("semoss_user"); + User user = (User) session.getAttribute("semoss_user"); if(user == null) { - user = new User2(); + user = new User(); AccessToken token = new AccessToken(); token.setProvider(AuthProvider.CAC); From 876e184184fca4de4ef90c2e7bc008bd7a47d978 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 12 Jun 2018 18:35:44 +0000 Subject: [PATCH 0082/1906] UPDATE ::: Switch from google2 to google git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28654 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 3beb1577c336414a8a68274e3580f92d250941a6 --- src/prerna/semoss/web/services/UserResource.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/prerna/semoss/web/services/UserResource.java b/src/prerna/semoss/web/services/UserResource.java index 4eb471276..3ef0db770 100644 --- a/src/prerna/semoss/web/services/UserResource.java +++ b/src/prerna/semoss/web/services/UserResource.java @@ -789,8 +789,8 @@ private String getDBRedirect(HttpServletRequest request) throws UnsupportedEncod */ @GET @Produces("application/json") - @Path("/login/google2") - public Response loginGoogle2(@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException { + @Path("/login/google") + public Response loginGoogle(@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException { /* * Try to log in the user * If they are not logged in From 19fe0838bab32cb53e9bafb92de78530029ea95f Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 12 Jun 2018 22:52:01 +0000 Subject: [PATCH 0083/1906] UPDATE ::: Returning raw headers in task return git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28661 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 8ae5ced350c5f3829529ef27f7ed96ac5aa0b88e --- src/prerna/web/services/util/PixelWebUtility.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/prerna/web/services/util/PixelWebUtility.java b/src/prerna/web/services/util/PixelWebUtility.java index b5bd6038a..ec4c0d092 100644 --- a/src/prerna/web/services/util/PixelWebUtility.java +++ b/src/prerna/web/services/util/PixelWebUtility.java @@ -209,6 +209,7 @@ private static void processNounMetadata(Insight in, PrintStream ps, Gson gson, N // right now, only grid will work boolean first = true; String[] headers = null; + String[] rawHeaders = null; int count = 0; // we need to use a try catch @@ -222,6 +223,7 @@ private static void processNounMetadata(Insight in, PrintStream ps, Gson gson, N // need to set the headers if(headers == null) { headers = row.getHeaders(); + rawHeaders = row.getRawHeaders(); ps.print("\"output\":{"); ps.print("\"data\":{" ); ps.print("\"values\":["); @@ -265,6 +267,7 @@ private static void processNounMetadata(Insight in, PrintStream ps, Gson gson, N } // end the values and add the headers ps.print("],\"headers\":" + gson.toJson(headers)); + ps.print(",\"rawHeaders\":" + gson.toJson(rawHeaders)); ps.print("}" ); } else if(formatType.equals("GRAPH")){ From 7df3799227c2c4a2eb394cf166ac699e6c2905e3 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 13 Jun 2018 01:17:02 +0000 Subject: [PATCH 0084/1906] BUGFIX ::: Hotfixes pushed for working with TOPAZ git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28666 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 97aa3ca4e6d96ce317b080e2b54ba9063d08ea40 --- src/prerna/web/conf/CACFilter.java | 35 +++++++++++++++---- .../web/services/util/PixelWebUtility.java | 10 ++++++ 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/src/prerna/web/conf/CACFilter.java b/src/prerna/web/conf/CACFilter.java index 16432a520..d0d3031da 100644 --- a/src/prerna/web/conf/CACFilter.java +++ b/src/prerna/web/conf/CACFilter.java @@ -13,37 +13,58 @@ import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; +import org.apache.log4j.LogManager; +import org.apache.log4j.Logger; + import prerna.auth.AccessToken; import prerna.auth.AuthProvider; import prerna.auth.User; +import prerna.util.Constants; public class CACFilter implements Filter { + private static final Logger LOGGER = LogManager.getLogger(CACFilter.class.getName()); + @Override public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { X509Certificate[] certs = (X509Certificate[]) arg0.getAttribute("javax.servlet.request.X509Certificate"); HttpSession session = ((HttpServletRequest)arg0).getSession(true); if(certs != null) { - User user = (User) session.getAttribute("semoss_user"); + User user = (User) session.getAttribute(Constants.SESSION_USER); if(user == null) { user = new User(); AccessToken token = new AccessToken(); token.setProvider(AuthProvider.CAC); - for(int i = 0; i < certs.length; i++) { + // loop thorugh all the certs + CERT_LOOP : for(int i = 0; i < certs.length; i++) { X509Certificate cert = certs[i]; String fullName = cert.getSubjectX500Principal().getName(); + System.out.println("REQUEST COMING FROM " + fullName); + System.out.println("REQUEST COMING FROM " + fullName); LdapName ldapDN; try { ldapDN = new LdapName(fullName); for(Rdn rdn: ldapDN.getRdns()) { if(rdn.getType().equals("CN")) { String value = rdn.getValue().toString(); + + if(value.equals("topazbpm001.mhse2e.med.osd.mil")) { + // THIS IS FOR TOPAZ HITTING MHS + // GIVE IT ACCESS + token.setName(value); + // now set the other properties + token.setToken_type(cert.getIssuerDN().getName()); + token.setExpires_in((int) cert.getNotAfter().getTime()); + LOGGER.info("Request coming from TOPAZ"); + break CERT_LOOP; + } + + String[] split = value.split("\\."); if(split.length == 3 || split.length == 4) { // no idea if middle name is always there or not @@ -55,6 +76,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 // now set the other properties token.setToken_type(cert.getIssuerDN().getName()); token.setExpires_in((int) cert.getNotAfter().getTime()); + break CERT_LOOP; } else { continue; } @@ -64,12 +86,13 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 } } } catch (InvalidNameException e) { - token.setName(fullName); + LOGGER.error("ERROR WITH PARSING CAC INFORMATION!"); e.printStackTrace(); } } if(token.getName() != null) { + LOGGER.info("Valid request coming from user " + token.getName()); user.setAccessToken(token); session.setAttribute("semoss_user", user); } @@ -77,9 +100,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 } if(session.getAttribute("semoss_user") == null) { - //TOOD: figure out redirect - HttpServletResponse httpResponse = (HttpServletResponse) arg1; - httpResponse.sendRedirect( ((HttpServletRequest)arg0).getHeader("Referer") + "TestRedirect/test.html"); + LOGGER.error("COULDN'T AUTHORIZE USER!"); return; } diff --git a/src/prerna/web/services/util/PixelWebUtility.java b/src/prerna/web/services/util/PixelWebUtility.java index ec4c0d092..310422421 100644 --- a/src/prerna/web/services/util/PixelWebUtility.java +++ b/src/prerna/web/services/util/PixelWebUtility.java @@ -338,6 +338,16 @@ else if(nounT == PixelDataType.REMOVE_VARIABLE) { } + // remove insight + else if(nounT == PixelDataType.CLEAR_INSIGHT) { + NounMetadata newNoun = InsightUtility.clearInsight(in); + ps.print("\"output\":"); + ps.print(gson.toJson(newNoun.getValue())); + ps.print(",\"operationType\":"); + ps.print(gson.toJson(newNoun.getOpType())); + + } + else if(nounT == PixelDataType.REMOVE_TASK) { // we only remove variables at the end // because the user may want to get the task and then From 402e524c4e3f4464e3cfeac1bc565f5db9deadaf Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 13 Jun 2018 18:21:18 +0000 Subject: [PATCH 0085/1906] BUGFIX ::: Fixing error with tinker joining via properties UPDATE ::: Pushing more optimized way to send graph data UPDATE ::: Adding new query struct datasource iterator to match new iterator construct git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28682 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 60daa3e01e0c9d5bb8ca0c3d7cf09cf1909e1283 --- .../web/services/util/PixelWebUtility.java | 59 +++++++++++++++++-- 1 file changed, 54 insertions(+), 5 deletions(-) diff --git a/src/prerna/web/services/util/PixelWebUtility.java b/src/prerna/web/services/util/PixelWebUtility.java index 310422421..150151724 100644 --- a/src/prerna/web/services/util/PixelWebUtility.java +++ b/src/prerna/web/services/util/PixelWebUtility.java @@ -25,6 +25,7 @@ import prerna.sablecc2.om.task.AbstractTask; import prerna.sablecc2.om.task.ConstantDataTask; import prerna.sablecc2.om.task.ITask; +import prerna.sablecc2.reactor.export.GraphFormatter; import prerna.sablecc2.reactor.frame.FrameFactory; import prerna.util.insight.InsightUtility; @@ -271,17 +272,22 @@ private static void processNounMetadata(Insight in, PrintStream ps, Gson gson, N ps.print("}" ); } else if(formatType.equals("GRAPH")){ - // format type is probably graph +// // format type is probably graph +// ps.print("\"output\":{"); +// ps.print("\"data\":" ); +// // this is a map return +// ps.print(gson.toJson( ((AbstractTask) task).getData())); + + // format type is graph ps.print("\"output\":{"); - ps.print("\"data\":" ); - // this is a map return - ps.print(gson.toJson( ((AbstractTask) task).getData())); + printMapData(ps, (Map) ((AbstractTask) task).getData(), gson); } for(String taskMetaKey : taskMeta.keySet()) { ps.print(",\"" + taskMetaKey + "\":" + gson.toJson(taskMeta.get(taskMetaKey))); ps.flush(); } + ps.print(",\"taskId\":\"" + task.getId() + "\""); ps.print("}"); ps.print(",\"operationType\":"); @@ -294,7 +300,20 @@ private static void processNounMetadata(Insight in, PrintStream ps, Gson gson, N // sometimes there is just data to send // dont need to do anything special ps.print("\"output\":"); - ps.print(gson.toJson(noun.getValue())); + Object obj = noun.getValue(); + if(obj instanceof Map && ((Map) obj).containsKey("type") && ((Map) obj).get("type").equals("GRAPH")) { + ps.print("{"); + Map mapObj = (Map) obj; + Map retData = (Map) mapObj.remove("data"); + printMapData(ps, retData, gson); + // print the rest of the stuff + for(Object key : mapObj.keySet()) { + ps.println(",\"" + key + ":" + gson.toJson(mapObj.get(key))); + } + ps.print("}"); + } else { + ps.print(gson.toJson(noun.getValue())); + } ps.print(",\"operationType\":"); ps.print(gson.toJson(noun.getOpType())); } @@ -381,4 +400,34 @@ else if(nounT == PixelDataType.REMOVE_TASK) { ps.flush(); } + /** + * Logic to more efficiently print out the map formatted data + * @param ps + * @param retData + * @param gson + */ + private static void printMapData(PrintStream ps, Map retData, Gson gson) { + ps.print("\"data\":" ); + // this is a map return + ps.print("{\"" + GraphFormatter.GRAPH_META + "\":" + gson.toJson(retData.get(GraphFormatter.GRAPH_META))); + ps.print(", \"" + GraphFormatter.NODES + "\":["); + + List nodeList = (List) retData.get(GraphFormatter.NODES); + // print first node + if(!nodeList.isEmpty()) { + ps.print(gson.toJson(nodeList.remove(0))); + } + // print rest of nodes + nodeList.stream().forEach(node -> ps.print("," + gson.toJson(node))); + ps.print("], \"" + GraphFormatter.EDGES + "\":["); + List edgeList = (List) retData.get(GraphFormatter.EDGES); + // print first node + if(!edgeList.isEmpty()) { + ps.print(gson.toJson(edgeList.remove(0))); + } + // print rest of nodes + edgeList.stream().forEach(edge -> ps.print("," + gson.toJson(edge))); + ps.print("]}"); + } + } From a688361e626ace75090df2e993e2497a2ceddfb7 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 13 Jun 2018 19:03:22 +0000 Subject: [PATCH 0086/1906] UPDATE ::: Closing steams in tinker in hopes of improving query performance on the same frame multiple times UPDATE ::: Adding to RDatasourceIterator git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28683 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: e6f618967ad87175fbb1a87799edab11c94a9110 --- src/prerna/web/services/util/PixelWebUtility.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/prerna/web/services/util/PixelWebUtility.java b/src/prerna/web/services/util/PixelWebUtility.java index 150151724..1c479269c 100644 --- a/src/prerna/web/services/util/PixelWebUtility.java +++ b/src/prerna/web/services/util/PixelWebUtility.java @@ -50,6 +50,7 @@ public void write(OutputStream outputStream) throws IOException, WebApplicationE try(PrintStream ps = new PrintStream(outputStream)) { // we want to ignore the first index since it will be a job processPixelRunner(ps, gson, runner, true); + ps.close(); } }}; } catch (Exception e) { From fc3fec13d83a8d236ed7d30a554e7706ccb1b926 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 15 Jun 2018 19:50:28 +0000 Subject: [PATCH 0087/1906] UPDATE ::: Adding end point to get the timeout value on the server git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28709 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: dea814f3ad0f3bdbb110cfa557b635b03b1490ba --- src/prerna/semoss/web/services/NameServer.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/prerna/semoss/web/services/NameServer.java b/src/prerna/semoss/web/services/NameServer.java index 449d6a167..7b5715169 100644 --- a/src/prerna/semoss/web/services/NameServer.java +++ b/src/prerna/semoss/web/services/NameServer.java @@ -1421,10 +1421,13 @@ public void killJob(@QueryParam("jobId") String jobId, @Context HttpServletReque */ //return thread.getOutput() + ""; } - - + @GET + @Path("/sessionTimeout") + @Produces("application/json") + public Response getTimeoutValue(@Context HttpServletRequest request) { + return WebUtility.getResponse((double) request.getSession().getMaxInactiveInterval() / 60, 200); + } - } From 4c59650df646d004aba9e2803c3998b358fdaf23 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 18 Jun 2018 17:26:44 +0000 Subject: [PATCH 0088/1906] UPDATE ::: Commenting out compilation error git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28725 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 51507a308d2829f0674008731abf91f0bb7c162d --- src/prerna/semoss/web/services/EngineRemoteResource.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/prerna/semoss/web/services/EngineRemoteResource.java b/src/prerna/semoss/web/services/EngineRemoteResource.java index cae29d9fa..6bc535761 100644 --- a/src/prerna/semoss/web/services/EngineRemoteResource.java +++ b/src/prerna/semoss/web/services/EngineRemoteResource.java @@ -218,7 +218,8 @@ public StreamingOutput hasNext(@FormParam("id") String id) // if(wrapper instanceof SesameJenaSelectCheater) // retValue = ((SesameJenaSelectCheater)wrapper).hasNext(); - retValue = ((IEngineWrapper)wrapper).hasNext(); + //TODO: this shouldnt' be commented out!!! +// retValue = ((IEngineWrapper) wrapper).hasNext(); if(!retValue) // cleanup QueryResultHash.getInstance().cleanObject(id); } From 7735234c36a8cb0bf5381f0737538c292336c8a1 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 18 Jun 2018 17:46:57 +0000 Subject: [PATCH 0089/1906] UPDATE ::: Renaming for consistent convention - headers and rawheaders instead of var and displayvar git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28726 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: ed0d01b71088e739cfbd079ddf81e230f3cf1c5c --- src/prerna/web/services/util/QueryResultHash.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prerna/web/services/util/QueryResultHash.java b/src/prerna/web/services/util/QueryResultHash.java index a1a8f818c..e4e9f59f3 100644 --- a/src/prerna/web/services/util/QueryResultHash.java +++ b/src/prerna/web/services/util/QueryResultHash.java @@ -56,7 +56,7 @@ public String addObject(IRemoteQueryable maObject) if(prefix == null) prefix = "QueryNo"; String key = prefix + runner; - maObject.setRemoteID(key); + maObject.setRemoteId(key); objHash.put(key, maObject); runner++; return key; From 31f2a12697383291759d18806c1b5d9c5a72bc84 Mon Sep 17 00:00:00 2001 From: tbanach Date: Tue, 19 Jun 2018 21:51:51 +0000 Subject: [PATCH 0090/1906] BUGFIX ::: UTF-8 encoding made explicit - so that it can be built on Unix CI runner git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28783 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 16447a20be8262e4ec6af6e8878e8061ea4365b8 --- pom.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/pom.xml b/pom.xml index 8ce53f7c5..1ec61a965 100644 --- a/pom.xml +++ b/pom.xml @@ -16,6 +16,7 @@ 1.8 1.8 + UTF-8 From a0c87401790e020f8898ec36e28a78e938eb78d1 Mon Sep 17 00:00:00 2001 From: tbanach Date: Tue, 19 Jun 2018 22:05:53 +0000 Subject: [PATCH 0091/1906] BUGFIX ::: Some java classes contain non UTF-8 characters, so specifying other encoding in pom.xml git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28784 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 69068aae56f5897ca27893d616a70ba278f1fe0b --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1ec61a965..7bce8b046 100644 --- a/pom.xml +++ b/pom.xml @@ -16,7 +16,7 @@ 1.8 1.8 - UTF-8 + cp1252 From 3d193ecbb26aac6a1c6255294e6d07e295264b9b Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 20 Jun 2018 12:01:25 +0000 Subject: [PATCH 0092/1906] UPDATE ::: Pushing code cleanup + using logger git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28795 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: cb9b8baab7f1d816c0e892c9602a8ab3a9a1d4d9 --- .../semoss/web/services/UserResource.java | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/prerna/semoss/web/services/UserResource.java b/src/prerna/semoss/web/services/UserResource.java index 3ef0db770..57423ad91 100644 --- a/src/prerna/semoss/web/services/UserResource.java +++ b/src/prerna/semoss/web/services/UserResource.java @@ -61,6 +61,8 @@ import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.message.BasicNameValuePair; +import org.kohsuke.github.GHMyself; +import org.kohsuke.github.GitHub; import jodd.util.URLDecoder; import prerna.auth.AccessToken; @@ -573,7 +575,21 @@ public Response loginGit(@Context HttpServletRequest request, @Context HttpServl String url = "https://github.com/login/oauth/access_token"; AccessToken accessToken = AbstractHttpHelper.getAccessToken(url, params, false, true); + if(accessToken == null) { + // not authenticated + response.setStatus(302); + response.sendRedirect(getGoogleRedirect(request)); + return null; + } accessToken.setProvider(AuthProvider.GIT); + + // add specific Git values + GHMyself myGit = GitHub.connectUsingOAuth(accessToken.getAccess_token()).getMyself(); + accessToken.setId(myGit.getId() + ""); + accessToken.setEmail(myGit.getEmail()); + accessToken.setName(myGit.getName()); + accessToken.setLocale(myGit.getLocation()); + accessToken.setUsername(myGit.getLogin()); addAccessToken(accessToken, request); System.out.println("Access Token is.. " + accessToken.getAccess_token()); @@ -657,6 +673,13 @@ public Response loginMS(@Context HttpServletRequest request, @Context HttpServle String url = "https://login.microsoftonline.com/" + tenant + "/oauth2/v2.0/token"; AccessToken accessToken = AbstractHttpHelper.getAccessToken(url, params, true, true); + if(accessToken == null) { + // not authenticated + response.setStatus(302); + response.sendRedirect(getGoogleRedirect(request)); + return null; + } + accessToken.setProvider(AuthProvider.AZURE_GRAPH); addAccessToken(accessToken, request); @@ -821,6 +844,12 @@ public Response loginGoogle(@Context HttpServletRequest request, @Context HttpSe String url = "https://www.googleapis.com/oauth2/v4/token"; AccessToken accessToken = AbstractHttpHelper.getAccessToken(url, params, true, true); + if(accessToken == null) { + // not authenticated + response.setStatus(302); + response.sendRedirect(getGoogleRedirect(request)); + return null; + } //https://developers.google.com/api-client-library/java/google-api-java-client/oauth2 // Shows how to make a google credential from an access token System.out.println("Access Token is.. " + accessToken.getAccess_token()); From 432bb66ded0d0ce262bd4e17b5c01a1b5363fee4 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 21 Jun 2018 17:38:51 +0000 Subject: [PATCH 0093/1906] UPDATE ::: Cleanup of the errors being returned to the FE git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28828 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: f68e72d035cd65b2ca2048747e8be26274e9f61b --- src/prerna/web/services/util/PixelWebUtility.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/prerna/web/services/util/PixelWebUtility.java b/src/prerna/web/services/util/PixelWebUtility.java index 1c479269c..a6d58dd60 100644 --- a/src/prerna/web/services/util/PixelWebUtility.java +++ b/src/prerna/web/services/util/PixelWebUtility.java @@ -394,6 +394,17 @@ else if(nounT == PixelDataType.REMOVE_TASK) { ps.print(gson.toJson(noun.getValue())); ps.print(",\"operationType\":"); ps.print(gson.toJson(noun.getOpType())); + + // add additional outputs + List addReturns = noun.getAdditionalReturn(); + int numOutputs = addReturns.size(); + if(numOutputs > 0) { + ps.print(",\"additionalOutput\":["); + for(int i = 0; i < numOutputs; i++) { + processNounMetadata(in, ps, gson, addReturns.get(i), null, null); + } + ps.print("]"); + } } // close the map From 0c73c98c06c973c8ad0c4349decdf5800372dc75 Mon Sep 17 00:00:00 2001 From: tbanach Date: Fri, 22 Jun 2018 15:00:17 +0000 Subject: [PATCH 0094/1906] REQUIREMENT ::: Maven update both Semoss and Monolith UPDATE ::: pom.xml cleanup, with appropriate RDF runtime dependencies and logging corrections git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28843 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 0b90ec6c8b2c04671f53e4ce7d21c5f322b1524a --- pom.xml | 651 ++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 415 insertions(+), 236 deletions(-) diff --git a/pom.xml b/pom.xml index 7bce8b046..36a2d58af 100644 --- a/pom.xml +++ b/pom.xml @@ -121,7 +121,8 @@ - + + + + com.blazegraph + bigdata-runtime + 2.0.0 com.blazegraph @@ -143,7 +149,8 @@ - + + org.apache.commons commons-collections4 @@ -209,6 +216,16 @@ + + commons-collections + commons-collections + 3.2.1 + + + commons-beanutils + commons-beanutils + 1.9.2 + org.apache.commons commons-dbcp2 @@ -319,7 +336,8 @@ - + + + + + + + + com.google.apis google-api-services-oauth2 @@ -385,7 +406,8 @@ - + + + + com.google.oauth-client google-oauth-client @@ -418,7 +441,8 @@ - + + + + + + + + + + + + + + org.apache.tinkerpop tinkergraph-gremlin @@ -561,7 +591,8 @@ - + + org.codehaus.groovy groovy-jsr223 @@ -584,7 +615,8 @@ - + + com.google.code.gson gson @@ -618,6 +650,12 @@ + + + com.google.guava + guava-collections + r03 + com.github.spullara.mustache.java compiler @@ -634,6 +672,7 @@ + com.github.stephenc.high-scale-lib high-scale-lib @@ -645,7 +684,8 @@ - + + org.apache.httpcomponents httpclient @@ -667,7 +707,8 @@ - + + + + org.apache.httpcomponents httpcore @@ -700,7 +742,8 @@ - + + com.ibm.icu icu4j @@ -722,7 +765,8 @@ - + + com.itextpdf itextpdf @@ -744,7 +788,8 @@ - + + + + + + org.javatuples javatuples @@ -799,7 +846,8 @@ - + + + + + + redis.clients jedis @@ -865,7 +915,8 @@ - + + org.apache.jena jena-larq @@ -887,7 +938,8 @@ - + + + + org.python @@ -932,7 +985,8 @@ - + + org.jgrapht jgrapht-core @@ -976,7 +1030,8 @@ - + + + + + + + + org.jsoup jsoup @@ -1042,7 +1100,8 @@ - + + net.sf.jung jung-algorithms @@ -1097,7 +1156,8 @@ - + + log4j log4j @@ -1130,7 +1190,8 @@ - + + org.apache.lucene lucene-core @@ -1185,7 +1246,8 @@ - + + mysql mysql-connector-java @@ -1207,7 +1269,8 @@ - + + + + + + + + com.oracle ojdbc6 @@ -1284,7 +1350,8 @@ - + + + + org.jboss.resteasy resteasy-jaxrs @@ -1350,7 +1418,8 @@ - + + + + + + + + + + + + + + + + + + org.apache.solr solr-core 4.7.0 - + - + + + + + + + + + + + + org.apache.solr solr-solrj 4.7.0 - + - + + + + + + edu.stanford.nlp stanford-corenlp @@ -1593,7 +1679,8 @@ - + + net.sf.supercsv super-csv @@ -1637,7 +1724,8 @@ - + + com.github.dblock.waffle waffle-jna @@ -1686,7 +1774,8 @@ - + + + + + + + + + + + it.unimi.dsi + dsiutils + 2.4.2 + + + + ch.qos.logback + logback-classic + + + ch.qos.logback + logback-core + + + + + aurelionribon.ui css-engine-swing-api @@ -1763,7 +1873,8 @@ - + + + + + + + + + + com.teamdev.jxbrowser jxbrowser @@ -1829,7 +1944,8 @@ - + + + + + + + + + + org.rednoise rita @@ -1895,7 +2015,8 @@ - + + com.microsoft sqlserver @@ -1917,7 +2038,8 @@ - + + edu.cmu ws4j @@ -1973,36 +2095,41 @@ + - + + - + - + + - + + - + + org.scala-lang @@ -2010,11 +2137,12 @@ 2.11.7 - + + org.apache.hadoop @@ -2022,11 +2150,12 @@ 2.6.0 - + + org.javassist @@ -2064,33 +2193,38 @@ extjwnl 1.9.2 - + + + + - + + + + + + org.quartz-scheduler quartz @@ -2106,11 +2240,12 @@ mail 1.4 - + + org.mariadb.jdbc @@ -2127,16 +2262,18 @@ postgresql 42.1.1 - + + + + org.apache.tinkerpop @@ -2155,35 +2292,39 @@ commons-validator 1.4.0 - + + + - + org.eclipse.jgit org.eclipse.jgit 4.8.0.201706111038-r + - + - + + org.kohsuke @@ -2196,7 +2337,8 @@ 2.1.5 - + + + + com.cloudera impala4 @@ -2229,7 +2372,8 @@ - + + + + + + + + - + + + + + + org.json + json + 20160810 com.fasterxml.jackson.core @@ -2288,7 +2447,7 @@ com.fasterxml.jackson.core jackson-annotations 2.9.0 - + com.amazon.redshift redshift-jdbc41 @@ -2300,12 +2459,13 @@ j2v8_win32_x86_64 4.4.0 + - + com.corundumstudio.socketio @@ -2313,16 +2473,18 @@ 1.7.12 - + + + + black.ninia jep @@ -2339,16 +2501,21 @@ json-flattener 0.4.1 - - org.xerial - sqlite-jdbc - 3.14.2 - + + org.xerial + sqlite-jdbc + 3.14.2 + com.jayway.jsonpath json-path 2.3.0 + + net.minidev + json-smart + 1.0.9 + io.burt jmespath-jackson @@ -2360,11 +2527,12 @@ google-api-services-sheets v4-rev506-1.23.0 - + + com.google.apis google-api-services-drive @@ -2391,6 +2559,17 @@ jsoup 1.11.3 - + + + au.com.bytecode + opencsv + 2.4 + + + + org.jodd + jodd-core + 3.6.2 + \ No newline at end of file From 97194b291423548ada5b124ddc36f6f166730e71 Mon Sep 17 00:00:00 2001 From: tbanach Date: Fri, 22 Jun 2018 15:33:48 +0000 Subject: [PATCH 0095/1906] UPDATE ::: CI - build config for Monolith git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28845 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 67c4c24f613a0aa2a2b797aad659310e25303177 --- .gitlab-ci.yml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 .gitlab-ci.yml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 000000000..d03c81374 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,25 @@ +image: maven:3.5-jdk-8 + +stages: + - build + +before_script: + - apt-get update + - apt-get install -y openjfx + +variables: + MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=WARN -Dorg.slf4j.simpleLogger.showDateTime=true -Djava.awt.headless=true" + MAVEN_CLI_OPTS: "--batch-mode" + +cache: + paths: + - .m2/repository/ + key: ${CI_BUILD_REF_NAME} + +build: + stage: build + script: + - mvn $MAVEN_CLI_OPTS clean install + artifacts: + paths: + - target/ From e1e228fe9bf69aca235f0f6df3ad42aae3f4968b Mon Sep 17 00:00:00 2001 From: tbanach Date: Fri, 22 Jun 2018 15:44:14 +0000 Subject: [PATCH 0096/1906] UPDATE ::: CI - referencing local artifactory for now to get Semoss into Monolith git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28846 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: cfa97091952c8e57ea8ef5ecbd1f7a310bbb3f51 --- .gitlab-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d03c81374..76c126975 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -6,6 +6,7 @@ stages: before_script: - apt-get update - apt-get install -y openjfx + - wget https://repo.semoss.org/semoss/Semoss/-/jobs/artifacts/svn/dev/raw/target/semoss-0.0.1-SNAPSHOT.jar?job=build variables: MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=WARN -Dorg.slf4j.simpleLogger.showDateTime=true -Djava.awt.headless=true" From 0aa4aebec25fb05dd3cb10973be0baef1d1fbac2 Mon Sep 17 00:00:00 2001 From: tbanach Date: Fri, 22 Jun 2018 15:50:59 +0000 Subject: [PATCH 0097/1906] BUGFIX ::: Proper m2 folder location git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28847 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: dbbbe10e76aeec75314323adcedcb66c96634b81 --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 76c126975..db84a0826 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -6,7 +6,7 @@ stages: before_script: - apt-get update - apt-get install -y openjfx - - wget https://repo.semoss.org/semoss/Semoss/-/jobs/artifacts/svn/dev/raw/target/semoss-0.0.1-SNAPSHOT.jar?job=build + - wget https://repo.semoss.org/semoss/Semoss/-/jobs/artifacts/svn/dev/raw/target/semoss-0.0.1-SNAPSHOT.jar?job=build -P .m2/repository/org/semoss variables: MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=WARN -Dorg.slf4j.simpleLogger.showDateTime=true -Djava.awt.headless=true" From 0ea420fc06240b4ad5fc5459bca73f74d2f62f13 Mon Sep 17 00:00:00 2001 From: tbanach Date: Fri, 22 Jun 2018 15:54:16 +0000 Subject: [PATCH 0098/1906] BUGFIX ::: CI - Maven install from file git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28848 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: ab52e50122eaa6416a1a9c808eda83c3d8c0a421 --- .gitlab-ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index db84a0826..fd3445e13 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -6,7 +6,8 @@ stages: before_script: - apt-get update - apt-get install -y openjfx - - wget https://repo.semoss.org/semoss/Semoss/-/jobs/artifacts/svn/dev/raw/target/semoss-0.0.1-SNAPSHOT.jar?job=build -P .m2/repository/org/semoss + - wget https://repo.semoss.org/semoss/Semoss/-/jobs/artifacts/svn/dev/raw/target/semoss-0.0.1-SNAPSHOT.jar?job=build + - mvn install:install-file -Dfile=semoss-0.0.1-SNAPSHOT.jar -DgroupId=org.semoss -DartifactId=semoss -Dversion=0.0.1-SNAPSHOT -Dpackaging=jar variables: MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=WARN -Dorg.slf4j.simpleLogger.showDateTime=true -Djava.awt.headless=true" From b72462ecd50dff805490127ec8f6428fa1a32c63 Mon Sep 17 00:00:00 2001 From: tbanach Date: Fri, 22 Jun 2018 16:00:00 +0000 Subject: [PATCH 0099/1906] BUGFIX ::: CI - temp folder to avoid conflict with Monolith's pom when mvn installing semoss from file git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28849 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 66cdc3c1d18fdcfe9e6d10b11a0d31a90d533885 --- .gitlab-ci.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index fd3445e13..ce6b972e8 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -6,8 +6,10 @@ stages: before_script: - apt-get update - apt-get install -y openjfx - - wget https://repo.semoss.org/semoss/Semoss/-/jobs/artifacts/svn/dev/raw/target/semoss-0.0.1-SNAPSHOT.jar?job=build + - wget https://repo.semoss.org/semoss/Semoss/-/jobs/artifacts/svn/dev/raw/target/semoss-0.0.1-SNAPSHOT.jar?job=build -P temp + - cd temp - mvn install:install-file -Dfile=semoss-0.0.1-SNAPSHOT.jar -DgroupId=org.semoss -DartifactId=semoss -Dversion=0.0.1-SNAPSHOT -Dpackaging=jar + - cd .. variables: MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=WARN -Dorg.slf4j.simpleLogger.showDateTime=true -Djava.awt.headless=true" From 244558e3fecf7b63be6800c486384d45c9539e69 Mon Sep 17 00:00:00 2001 From: tbanach Date: Fri, 22 Jun 2018 16:04:42 +0000 Subject: [PATCH 0100/1906] UPDATE ::: CI - list files in temp for ref git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28850 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 1057f2a20a02fa187ebfa4c2c58f4b909dfd2a57 --- .gitlab-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ce6b972e8..00400020c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -8,6 +8,7 @@ before_script: - apt-get install -y openjfx - wget https://repo.semoss.org/semoss/Semoss/-/jobs/artifacts/svn/dev/raw/target/semoss-0.0.1-SNAPSHOT.jar?job=build -P temp - cd temp + - ls -la - mvn install:install-file -Dfile=semoss-0.0.1-SNAPSHOT.jar -DgroupId=org.semoss -DartifactId=semoss -Dversion=0.0.1-SNAPSHOT -Dpackaging=jar - cd .. From 12b871f05fbc1d058789dca104699a7c5d484a89 Mon Sep 17 00:00:00 2001 From: tbanach Date: Fri, 22 Jun 2018 16:10:59 +0000 Subject: [PATCH 0101/1906] BUGFIX ::: CI - correcting name of jar from wget command git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28851 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 4cb704dc0d41cdfff0e4cd437b190b8ba2feb5f8 --- .gitlab-ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 00400020c..200080642 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -6,10 +6,10 @@ stages: before_script: - apt-get update - apt-get install -y openjfx - - wget https://repo.semoss.org/semoss/Semoss/-/jobs/artifacts/svn/dev/raw/target/semoss-0.0.1-SNAPSHOT.jar?job=build -P temp + - wget https://repo.semoss.org/semoss/Semoss/-/jobs/artifacts/svn/dev/raw/target/semoss-0.0.1-SNAPSHOT.jar?job=build -O temp/semoss.jar - cd temp - - ls -la - - mvn install:install-file -Dfile=semoss-0.0.1-SNAPSHOT.jar -DgroupId=org.semoss -DartifactId=semoss -Dversion=0.0.1-SNAPSHOT -Dpackaging=jar + - ls -l + - mvn install:install-file -Dfile=semoss.jar -DgroupId=org.semoss -DartifactId=semoss -Dversion=0.0.1-SNAPSHOT -Dpackaging=jar - cd .. variables: From 5dcec2122be63fbc69f78c5daeef5b1d20c40550 Mon Sep 17 00:00:00 2001 From: tbanach Date: Fri, 22 Jun 2018 16:15:19 +0000 Subject: [PATCH 0102/1906] BUGFIX ::: wget syntax error git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28852 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 01fc61622a1b576df73752e72283a0f174fd2574 --- .gitlab-ci.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 200080642..5712550a4 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -6,11 +6,9 @@ stages: before_script: - apt-get update - apt-get install -y openjfx - - wget https://repo.semoss.org/semoss/Semoss/-/jobs/artifacts/svn/dev/raw/target/semoss-0.0.1-SNAPSHOT.jar?job=build -O temp/semoss.jar - - cd temp + - wget https://repo.semoss.org/semoss/Semoss/-/jobs/artifacts/svn/dev/raw/target/semoss-0.0.1-SNAPSHOT.jar?job=build -O semoss.jar - ls -l - mvn install:install-file -Dfile=semoss.jar -DgroupId=org.semoss -DartifactId=semoss -Dversion=0.0.1-SNAPSHOT -Dpackaging=jar - - cd .. variables: MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=WARN -Dorg.slf4j.simpleLogger.showDateTime=true -Djava.awt.headless=true" From 97e76daf1191a5a358bf7d6d5ebe8ab01cd20dbe Mon Sep 17 00:00:00 2001 From: tbanach Date: Fri, 22 Jun 2018 16:21:47 +0000 Subject: [PATCH 0103/1906] BUGFIX ::: CI - investigating why semoss jar is corrupt git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28853 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: f10a5db164275ea31696e9f1a60179b5f3bea9bd --- .gitlab-ci.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5712550a4..a53f3e3fa 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -6,9 +6,13 @@ stages: before_script: - apt-get update - apt-get install -y openjfx + - mkdir temp + - cd temp + - echo $MAVEN_OPTS - wget https://repo.semoss.org/semoss/Semoss/-/jobs/artifacts/svn/dev/raw/target/semoss-0.0.1-SNAPSHOT.jar?job=build -O semoss.jar - ls -l - mvn install:install-file -Dfile=semoss.jar -DgroupId=org.semoss -DartifactId=semoss -Dversion=0.0.1-SNAPSHOT -Dpackaging=jar + - cd .. variables: MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=WARN -Dorg.slf4j.simpleLogger.showDateTime=true -Djava.awt.headless=true" From 94971694feb5d7155f94f276bb8b7ec0d88bff14 Mon Sep 17 00:00:00 2001 From: tbanach Date: Fri, 22 Jun 2018 16:26:11 +0000 Subject: [PATCH 0104/1906] BUGFIX ::: CI - quotes to escape ? character in wget git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28854 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 85b5a721d6d3907ad8ec0314bb8e9444ed6fe43e --- .gitlab-ci.yml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a53f3e3fa..4cba79523 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -6,13 +6,9 @@ stages: before_script: - apt-get update - apt-get install -y openjfx - - mkdir temp - - cd temp - - echo $MAVEN_OPTS - - wget https://repo.semoss.org/semoss/Semoss/-/jobs/artifacts/svn/dev/raw/target/semoss-0.0.1-SNAPSHOT.jar?job=build -O semoss.jar + - wget "https://repo.semoss.org/semoss/Semoss/-/jobs/artifacts/svn/dev/raw/target/semoss-0.0.1-SNAPSHOT.jar?job=build" - ls -l - - mvn install:install-file -Dfile=semoss.jar -DgroupId=org.semoss -DartifactId=semoss -Dversion=0.0.1-SNAPSHOT -Dpackaging=jar - - cd .. + - mvn install:install-file -Dfile=semoss-0.0.1-SNAPSHOT.jar -DgroupId=org.semoss -DartifactId=semoss -Dversion=0.0.1-SNAPSHOT -Dpackaging=jar variables: MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=WARN -Dorg.slf4j.simpleLogger.showDateTime=true -Djava.awt.headless=true" From d6dea91fc33db16573f9200827826f31b6e89013 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 22 Jun 2018 16:37:18 +0000 Subject: [PATCH 0105/1906] BUGFIX ::: Fixing errors with getting db name vs. id UPDATE ::: Changing cac filter to set id as dod id and set name as user name git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28856 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 80ad069bb19b403b31417c883142fb63a23f8335 --- src/prerna/semoss/web/form/FormResource.java | 190 +++--------------- .../semoss/web/services/EngineResource.java | 2 +- src/prerna/web/conf/CACFilter.java | 12 +- 3 files changed, 32 insertions(+), 172 deletions(-) diff --git a/src/prerna/semoss/web/form/FormResource.java b/src/prerna/semoss/web/form/FormResource.java index 343fddce4..dc7fdcd05 100644 --- a/src/prerna/semoss/web/form/FormResource.java +++ b/src/prerna/semoss/web/form/FormResource.java @@ -1,6 +1,5 @@ package prerna.semoss.web.form; -import java.security.cert.X509Certificate; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; @@ -9,9 +8,8 @@ import java.util.Map; import javax.naming.InvalidNameException; -import javax.naming.ldap.LdapName; -import javax.naming.ldap.Rdn; import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; @@ -19,11 +17,14 @@ import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; +import prerna.auth.AuthProvider; +import prerna.auth.User; import prerna.engine.api.IEngine; import prerna.engine.impl.rdbms.RDBMSNativeEngine; import prerna.forms.AbstractFormBuilder; import prerna.forms.FormBuilder; import prerna.forms.FormFactory; +import prerna.nameserver.utility.MasterDatabaseUtility; import prerna.util.Utility; import prerna.web.services.util.WebUtility; @@ -72,9 +73,9 @@ public Response renameInstance(MultivaluedMap form) { deleteInstanceBoolean = Boolean.parseBoolean(form.getFirst("deleteInstanceBoolean")); } - IEngine coreEngine = Utility.getEngine(dbName); - AbstractFormBuilder formbuilder = FormFactory.getFormBuilder(coreEngine); + IEngine coreEngine = Utility.getEngine(MasterDatabaseUtility.testEngineIdIfAlias(dbName)); + AbstractFormBuilder formbuilder = FormFactory.getFormBuilder(coreEngine); formbuilder.modifyInstanceValue(origUri, newUri, deleteInstanceBoolean); return WebUtility.getResponse("success", 200); } @@ -87,7 +88,8 @@ public Response certifyInstance(MultivaluedMap form) { String instanceType = form.getFirst("instanceType"); String instanceName = form.getFirst("instanceName"); String dbName = form.getFirst("dbName"); - IEngine coreEngine = Utility.getEngine(dbName); + + IEngine coreEngine = Utility.getEngine(MasterDatabaseUtility.testEngineIdIfAlias(dbName)); AbstractFormBuilder formbuilder = FormFactory.getFormBuilder(coreEngine); formbuilder.setUser(userid); @@ -99,50 +101,25 @@ public Response certifyInstance(MultivaluedMap form) { @Path("/getUserInstanceAuth") @Produces("applicaiton/json") public Response getUserInstanceAuth(@Context HttpServletRequest request) throws InvalidNameException { - X509Certificate[] certs = (X509Certificate[]) request.getAttribute("javax.servlet.request.X509Certificate"); - if(certs == null || certs.length == 0) { - return WebUtility.getResponse("you messed up", 400); + String x509Id = null; + try { + HttpSession session = ((HttpServletRequest)request).getSession(false); + User user = (User) session.getAttribute("semoss_user"); + x509Id = user.getAccessToken(AuthProvider.CAC).getName(); + } catch(Exception e) { + Map err = new HashMap(); + err.put("errorMessage", "Could not identify user"); + return WebUtility.getResponse(err, 400); + } + if(x509Id == null) { + Map err = new HashMap(); + err.put("errorMessage", "Could not identify user"); + return WebUtility.getResponse(err, 400); } - - IEngine formBuilderEng = Utility.getEngine(FormBuilder.FORM_BUILDER_ENGINE_NAME); - // the x509 for the user - // and the instances they have access to - String x509Id = null; Map userAccessableInstances = new HashMap(); - for(int i = 0; i < certs.length; i++) { - X509Certificate cert = certs[i]; - - String dn = cert.getSubjectX500Principal().getName(); - LdapName ldapDN = new LdapName(dn); - for(Rdn rdn: ldapDN.getRdns()) { - if(rdn.getType().equals("CN")) { - String fullNameAndId = rdn.getValue().toString(); - // TODO: figure out how to do this well - // we are getting a weird value coming through from one of the certs - // which is causing issues - // going to hack around this for now - // for CAC card, we know it must contain a 10 digit number at the end - // so make sure length is 10 and we can cast it to an integer - String[] split = null; - if((split = fullNameAndId.split("\\.")).length > 0) { - String possibleId = split[split.length-1]; - if(possibleId.length() == 10) { - try { - Integer.parseInt(possibleId); - } catch(NumberFormatException e) { - // we know this is not a valid cac id - // so move on - continue; - } - x509Id = possibleId; - break; - } - } - } - } - } + IEngine formBuilderEng = Utility.getEngine(FormBuilder.FORM_BUILDER_ENGINE_NAME); // map to store the valid instances for the given user String query = "SELECT INSTANCE_NAME, IS_SYS_ADMIN FROM FORMS_USER_ACCESS WHERE USER_ID = '" + x509Id + "';"; Map ret = (Map) formBuilderEng.execQuery(query); @@ -173,125 +150,4 @@ public Response getUserInstanceAuth(@Context HttpServletRequest request) throws return WebUtility.getResponse(returnData, 200); } - -// @POST -// @Path("/getAllAvailableForms") -// @Produces("application/json") -// public Response getAllAvailableForms() { -// String query = "SELECT FORM_NAME, FORM_LOCATION FROM FORM_METADATA"; -// List> formsList = new Vector>(); -// -// ISelectWrapper wrapper = WrapperManager.getInstance().getSWrapper(formBuilderEng, query); -// String[] names = wrapper.getVariables(); -// while(wrapper.hasNext()) { -// ISelectStatement ss = wrapper.next(); -// Map formMap = new Hashtable(); -// formMap.put("formName", ss.getVar(names[0]) + ""); -// formMap.put("formLocation", ss.getVar(names[1]) + ""); -// formsList.add(formMap); -// } -// -// return WebUtility.getResponse(formsList, 200); -// } - -// @POST -// @Path("/saveForm") -// @Produces("application/json") -// public Response saveForm(MultivaluedMap form) -// { -// String formName = form.getFirst("formName"); -// String formLocation = form.getFirst("formLocation"); -// -// try { -// FormBuilder.saveForm(formBuilderEng, formName, formLocation); -// } catch (IOException e) { -// return WebUtility.getResponse(e.getMessage(), 400); -// } -// -// return WebUtility.getResponse("saved successfully", 200); -// } - -// @POST -// @Path("/saveFormData") -// @Produces("application/json") -// public Response saveFormData(MultivaluedMap form, @Context HttpServletRequest request) -// { -// String userId = ((User)request.getSession().getAttribute(Constants.SESSION_USER)).getId(); -// String formName = form.getFirst("formName"); -// String formData = form.getFirst("formData"); -// String formTableName = getFormTableFromName(formName); -// try { -// FormBuilder.saveFormData(formBuilderEng, formTableName, userId, formData); -// } catch(Exception e) { -// e.printStackTrace(); -// return WebUtility.getResponse("error saving data", 400); -// } -// -// return WebUtility.getResponse("success", 200); -// } - -// @POST -// @Path("/getFormStagingData") -// @Produces("application/json") -// public Response getFormStagingData(MultivaluedMap form, @Context HttpServletRequest request) -// { -// String formName = form.getFirst("formName"); -// String formTableName = getFormTableFromName(formName); -// List> results = null; -// try { -// results = FormBuilder.getStagingData(formBuilderEng, formTableName); -// } catch(Exception e) { -// e.printStackTrace(); -// return WebUtility.getResponse("error retrieving data", 400); -// -// } -// -// return WebUtility.getResponse(results, 200); -// } - -// @POST -// @Path("/deleteFormDataFromStaging") -// @Produces("application/json") -// public Response deleteFormDataFromStaging(MultivaluedMap form, @Context HttpServletRequest request) -// { -// Gson gson = new Gson(); -// String formName = form.getFirst("formName"); -// String[] formIds = gson.fromJson(form.getFirst("ids"), String[].class); -// try { -// FormBuilder.deleteFromStaggingArea(formBuilderEng, formName, formIds); -// } catch(Exception e) { -// e.printStackTrace(); -// return WebUtility.getResponse("error deleting staging data", 400); -// } -// -// return WebUtility.getResponse("success", 200); -// } - -// @POST -// @Path("/deleteForm") -// @Produces("application/json") -// public Response deleteForm(MultivaluedMap form, @Context HttpServletRequest request) { -// String formName = form.getFirst("formName"); -// String formTableName = getFormTableFromName(formName); -// -// // delete form information -// String deleteQuery = "DELETE FROM FORM_METADATA WHERE FORM_TABLE ='" + formTableName + "'"; -// formBuilderEng.removeData(deleteQuery); -// // drop form table -// deleteQuery = "DROP TABLE " + formName; -// formBuilderEng.removeData(deleteQuery); -// -// return WebUtility.getResponse("success", 200); -// } - -// private String getFormTableFromName(String formName) { -// String query = "SELECT FORM_TABLE FROM FORM_METADATA WHERE FORM_NAME = '" + formName + "'"; -// -// ISelectWrapper wrapper = WrapperManager.getInstance().getSWrapper(formBuilderEng, query); -// String[] names = wrapper.getVariables(); -// wrapper.hasNext(); -// ISelectStatement ss = wrapper.next(); -// return ss.getVar(names[0]).toString(); -// } - } diff --git a/src/prerna/semoss/web/services/EngineResource.java b/src/prerna/semoss/web/services/EngineResource.java index 9cd604074..cf75c0690 100644 --- a/src/prerna/semoss/web/services/EngineResource.java +++ b/src/prerna/semoss/web/services/EngineResource.java @@ -238,7 +238,7 @@ public Response commitFormData(@Context HttpServletRequest request, MultivaluedM try { HttpSession session = ((HttpServletRequest)request).getSession(false); User user = (User) session.getAttribute("semoss_user"); - userId = user.getAccessToken(AuthProvider.CAC).getName(); + userId = user.getAccessToken(AuthProvider.CAC).getId(); } catch(Exception e) { Map err = new HashMap(); err.put("errorMessage", "Could not identify user"); diff --git a/src/prerna/web/conf/CACFilter.java b/src/prerna/web/conf/CACFilter.java index d0d3031da..f2aaa8ebd 100644 --- a/src/prerna/web/conf/CACFilter.java +++ b/src/prerna/web/conf/CACFilter.java @@ -2,6 +2,8 @@ import java.io.IOException; import java.security.cert.X509Certificate; +import java.util.stream.Collectors; +import java.util.stream.Stream; import javax.naming.InvalidNameException; import javax.naming.ldap.LdapName; @@ -56,7 +58,8 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 if(value.equals("topazbpm001.mhse2e.med.osd.mil")) { // THIS IS FOR TOPAZ HITTING MHS // GIVE IT ACCESS - token.setName(value); + token.setId(value); + token.setName("TOPAZ"); // now set the other properties token.setToken_type(cert.getIssuerDN().getName()); token.setExpires_in((int) cert.getNotAfter().getTime()); @@ -72,7 +75,8 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 String cacId = split[split.length-1]; if(cacId.length() >= 10) { // valid CAC!!! - token.setName(cacId); + token.setId(cacId); + token.setName(Stream.of(split).limit(split.length-2).collect(Collectors.joining(" "))); // now set the other properties token.setToken_type(cert.getIssuerDN().getName()); token.setExpires_in((int) cert.getNotAfter().getTime()); @@ -94,12 +98,12 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 if(token.getName() != null) { LOGGER.info("Valid request coming from user " + token.getName()); user.setAccessToken(token); - session.setAttribute("semoss_user", user); + session.setAttribute(Constants.SESSION_USER, user); } } } - if(session.getAttribute("semoss_user") == null) { + if(session.getAttribute(Constants.SESSION_USER) == null) { LOGGER.error("COULDN'T AUTHORIZE USER!"); return; } From 4a6cc3867b5e1b00ab9a951840bb4370a473e88e Mon Sep 17 00:00:00 2001 From: tbanach Date: Fri, 22 Jun 2018 17:27:58 +0000 Subject: [PATCH 0106/1906] BUGFIX ::: CI - reverting wget code to pull Semoss git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28858 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: e1dafc2ec4f2132b376fa132c86e4e1384ef6cb8 --- .gitlab-ci.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 4cba79523..d03c81374 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -6,9 +6,6 @@ stages: before_script: - apt-get update - apt-get install -y openjfx - - wget "https://repo.semoss.org/semoss/Semoss/-/jobs/artifacts/svn/dev/raw/target/semoss-0.0.1-SNAPSHOT.jar?job=build" - - ls -l - - mvn install:install-file -Dfile=semoss-0.0.1-SNAPSHOT.jar -DgroupId=org.semoss -DartifactId=semoss -Dversion=0.0.1-SNAPSHOT -Dpackaging=jar variables: MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=WARN -Dorg.slf4j.simpleLogger.showDateTime=true -Djava.awt.headless=true" From 7328209093eec5c5aa4b8f60b3604e3d17ac4fd7 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 22 Jun 2018 18:27:26 +0000 Subject: [PATCH 0107/1906] UPDATE ::: Adding first phase of full engine filters throughout reactors based on user git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28860 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 38a74e07ae2bfbf6771f8c9d345daf900ae0e263 --- src/prerna/web/conf/TestFilter.java | 56 +++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 src/prerna/web/conf/TestFilter.java diff --git a/src/prerna/web/conf/TestFilter.java b/src/prerna/web/conf/TestFilter.java new file mode 100644 index 000000000..d0e853dfb --- /dev/null +++ b/src/prerna/web/conf/TestFilter.java @@ -0,0 +1,56 @@ +package prerna.web.conf; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +import prerna.auth.AccessToken; +import prerna.auth.AuthProvider; +import prerna.auth.User; +import prerna.util.Constants; + +public class TestFilter implements Filter { + + /* + * THIS IS JUST A TEST CLASS + * DO NOT ACTUALLY USE THIS! + */ + + + @Override + public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { + HttpSession session = ((HttpServletRequest)arg0).getSession(true); + + User user = new User(); + AccessToken token = new AccessToken(); + token.setProvider(AuthProvider.NATIVE); + token.setEmail("mahkhalil@deloitte.com"); + token.setName("Maher"); + token.setId("111"); + + user.setAccessToken(token); + session.setAttribute(Constants.SESSION_USER, user); + + arg2.doFilter(arg0, arg1); + } + + @Override + public void destroy() { + // TODO Auto-generated method stub + + } + + @Override + public void init(FilterConfig arg0) throws ServletException { + // TODO Auto-generated method stub + + } + +} From 1d27b65be5ad5733fed97a04a7ddd00cb63a1df5 Mon Sep 17 00:00:00 2001 From: tbanach Date: Mon, 25 Jun 2018 17:34:22 +0000 Subject: [PATCH 0108/1906] UPDATE ::: CI - pom configuration for maven central, activated by mvn clean install -P deploy. Just running mvn clean install will build the project as before. git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28864 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 29453e52a851322883ac0267449c7463e7bef0b3 --- pom.xml | 183 ++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 159 insertions(+), 24 deletions(-) diff --git a/pom.xml b/pom.xml index 36a2d58af..8280e2e44 100644 --- a/pom.xml +++ b/pom.xml @@ -7,33 +7,168 @@ war Monolith SEMOSS Monolith + http://semoss.org/ + + + The Apache License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + + + The GNU General Public License, Version 3.0 + https://www.gnu.org/licenses/gpl-3.0.en.html + + + + + Group Mailbox + semoss@semoss.org + SEMOSS + http://semoss.org/ + + + + scm:git:git://repo.semoss.org/semoss/Monolith.git + scm:git:ssh://repo.semoss.org:semoss/Monolith.git + https://repo.semoss.org/semoss/Monolith + + + cp1252 + cp1252 + + + + ossrh + https://oss.sonatype.org/content/repositories/snapshots + + src - - - maven-compiler-plugin - 3.5.1 - - 1.8 - 1.8 - cp1252 - - - - org.apache.maven.plugins - maven-war-plugin - 2.6 - - WebContent/WEB-INF/web.xml - true - - - - maven-dependency-plugin - 2.10 - - + + + dev + + true + + + + + maven-compiler-plugin + 3.3 + + 1.8 + 1.8 + cp1252 + + + + org.apache.maven.plugins + maven-war-plugin + 2.6 + + WebContent/WEB-INF/web.xml + true + + + + maven-dependency-plugin + 2.10 + + + + + + deploy + + + + + + + + -Xdoclint:none + + + + + maven-compiler-plugin + 3.3 + + 1.8 + 1.8 + cp1252 + + + + org.sonatype.plugins + nexus-staging-maven-plugin + 1.6.7 + true + + ossrh + https://oss.sonatype.org/ + + false + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.5 + + + sign-artifacts + verify + + sign + + + + + + org.apache.maven.plugins + maven-war-plugin + 2.6 + + WebContent/WEB-INF/web.xml + true + + + + org.apache.maven.plugins + maven-source-plugin + + + attach-sources + + jar + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.9.1 + + + attach-javadocs + + jar + + + + ${javadoc.opts} + + + + + + + + central From 72910af4de4d4cbcbccdd65e0cd91629531ba559 Mon Sep 17 00:00:00 2001 From: tbanach Date: Mon, 25 Jun 2018 18:45:47 +0000 Subject: [PATCH 0109/1906] UPDATE ::: CI - GPG config in pom.xml git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28876 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 6de9c8580d5890a98067a14c966f544ed9c16069 --- pom.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pom.xml b/pom.xml index 8280e2e44..778bbd95a 100644 --- a/pom.xml +++ b/pom.xml @@ -124,6 +124,12 @@ sign + + + --pinentry-mode + loopback + + From 58526b648b79b24e68a1725199be1607d76e6f5b Mon Sep 17 00:00:00 2001 From: tbanach Date: Mon, 25 Jun 2018 19:57:31 +0000 Subject: [PATCH 0110/1906] BUGFIX ::: Adding in staging repo URL as well git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28882 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 149ecb5b528ce6310d6e18cbe7e21d52a95827c6 --- pom.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pom.xml b/pom.xml index 778bbd95a..f063e8a94 100644 --- a/pom.xml +++ b/pom.xml @@ -40,6 +40,10 @@ ossrh https://oss.sonatype.org/content/repositories/snapshots + + ossrh + https://oss.sonatype.org/service/local/staging/deploy/maven2/ + src From 829c6885af63f25a4be3b64ebadb414133a97100 Mon Sep 17 00:00:00 2001 From: tbanach Date: Mon, 25 Jun 2018 20:23:31 +0000 Subject: [PATCH 0111/1906] UPDATE ::: Nexus plugin instead of default maven one git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28883 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 59cc0390322be677a869d8c937837993c8991379 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f063e8a94..b394110f4 100644 --- a/pom.xml +++ b/pom.xml @@ -41,7 +41,7 @@ https://oss.sonatype.org/content/repositories/snapshots - ossrh + ossrh-stage https://oss.sonatype.org/service/local/staging/deploy/maven2/ From 77fd8733cf31ee5a2dbcbdd11cac5d446261581d Mon Sep 17 00:00:00 2001 From: tbanach Date: Mon, 25 Jun 2018 20:37:16 +0000 Subject: [PATCH 0112/1906] BUGFIX ::: CI - correcting ID in stage to group ID git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28884 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: e6bc234b607a6f9a2a117adf496800e1c9704150 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b394110f4..f063e8a94 100644 --- a/pom.xml +++ b/pom.xml @@ -41,7 +41,7 @@ https://oss.sonatype.org/content/repositories/snapshots - ossrh-stage + ossrh https://oss.sonatype.org/service/local/staging/deploy/maven2/ From 01c9bc58708c30718704b790b8f4948ae2b1e2e3 Mon Sep 17 00:00:00 2001 From: tbanach Date: Mon, 25 Jun 2018 22:02:38 +0000 Subject: [PATCH 0113/1906] UPDATE ::: Parameterizing SEMOSS version and adding SNAPSHOT repo, so that Monolith can be built using SEMOSS off of maven central git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28888 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 45bcd8867c9b9a1a83c45b93d6ffe3fda3c18b3d --- pom.xml | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index f063e8a94..5d728b1e8 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 org.semoss monolith - 0.0.1-SNAPSHOT + ${ci.version} war Monolith SEMOSS Monolith @@ -32,6 +32,7 @@ https://repo.semoss.org/semoss/Monolith + 0.0.1-SNAPSHOT cp1252 cp1252 @@ -200,6 +201,17 @@ false + + snapshot + Sonatype's Maven repository - SNAPSHOT + http://oss.sonatype.org/content/repositories/snapshots/ + + false + + + true + + LDS repository LDS Maven repository @@ -246,7 +258,7 @@ org.semoss semoss - 0.0.1-SNAPSHOT + ${ci.version} jdk.tools From 566fc394b33bb3b88629ee047c768603b259d8c0 Mon Sep 17 00:00:00 2001 From: tbanach Date: Tue, 26 Jun 2018 16:04:42 +0000 Subject: [PATCH 0114/1906] UPDATE ::: CI - can invoke separate packaging of libraries and war git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28899 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: b6857c93671927588458b4fdf1bf3db03b9a03b4 --- .gitlab-ci.yml | 23 ++++++++++++++++++++--- libraries.xml | 14 ++++++++++++++ pom.xml | 35 ++++++++++++++++++++++++++--------- settings.xml | 22 ++++++++++++++++++++++ 4 files changed, 82 insertions(+), 12 deletions(-) create mode 100644 libraries.xml create mode 100644 settings.xml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d03c81374..0b6cb7f85 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -6,20 +6,37 @@ stages: before_script: - apt-get update - apt-get install -y openjfx + - apt-get install -y gnupg2 + - gpg2 --batch --import <(echo "$GPG_PRIVATE_KEY") variables: MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=WARN -Dorg.slf4j.simpleLogger.showDateTime=true -Djava.awt.headless=true" - MAVEN_CLI_OPTS: "--batch-mode" + MAVEN_CLI_OPTS: "-s ./settings.xml --batch-mode" cache: paths: - .m2/repository/ key: ${CI_BUILD_REF_NAME} - -build: + +# Does not push to maven central +build_dev: stage: build + # See https://docs.gitlab.com/ee/ci/yaml/#only-and-except-simplified + only: + - pushes script: - mvn $MAVEN_CLI_OPTS clean install artifacts: paths: - target/ + +# Pushes to maven central +build_deploy: + stage: build + only: + - web + script: + - mvn $MAVEN_CLI_OPTS deploy -P deploy + artifacts: + paths: + - target/ diff --git a/libraries.xml b/libraries.xml new file mode 100644 index 000000000..1542cfb61 --- /dev/null +++ b/libraries.xml @@ -0,0 +1,14 @@ + + libraries + + tar.gz + + + + ${project.build.directory}/${project.build.finalName}/WEB-INF/lib + WEB-INF/lib + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 5d728b1e8..8f0b013ab 100644 --- a/pom.xml +++ b/pom.xml @@ -106,6 +106,32 @@ cp1252 + + org.apache.maven.plugins + maven-war-plugin + 2.6 + + WebContent/WEB-INF/web.xml + true + WEB-INF/lib/*.jar + + + + maven-assembly-plugin + 2.5.3 + + libraries.xml + + + + create-archive + package + + single + + + + org.sonatype.plugins nexus-staging-maven-plugin @@ -138,15 +164,6 @@ - - org.apache.maven.plugins - maven-war-plugin - 2.6 - - WebContent/WEB-INF/web.xml - true - - org.apache.maven.plugins maven-source-plugin diff --git a/settings.xml b/settings.xml new file mode 100644 index 000000000..a4ad9332a --- /dev/null +++ b/settings.xml @@ -0,0 +1,22 @@ + + + + ossrh + ${env.MAVEN_REPO_USER} + ${env.MAVEN_REPO_PASS} + + + + + ossrh + + true + + + gpg2 + ${env.GPG_PASS_PHRASE} + + + + \ No newline at end of file From a0ee111c24162a2b880a7d6b4a8bcb6f0517d0d0 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 26 Jun 2018 18:09:48 +0000 Subject: [PATCH 0115/1906] UPDATE ::: Updating security db UPDATE ::: Shifting all methods to go to security db instead of solr. Can technically remove solr completely from tomcat now. Still need to finish adding security for saving/editing insights / properly getting permissions git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28906 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 97c4ef185b3852dacd8e47e1ee2d4df671007f45 --- .../semoss/web/services/AppResource.java | 4 +- .../semoss/web/services/NameServer.java | 549 ++++++++---------- src/prerna/upload/DatabaseUploader.java | 174 +++--- src/prerna/web/conf/DBLoader.java | 18 +- 4 files changed, 329 insertions(+), 416 deletions(-) diff --git a/src/prerna/semoss/web/services/AppResource.java b/src/prerna/semoss/web/services/AppResource.java index 9461ef3ed..85a3726f3 100644 --- a/src/prerna/semoss/web/services/AppResource.java +++ b/src/prerna/semoss/web/services/AppResource.java @@ -24,10 +24,10 @@ import org.apache.commons.io.IOUtils; import org.apache.commons.io.filefilter.WildcardFileFilter; +import prerna.auth.AbstractSecurityUtils; import prerna.engine.impl.SmssUtilities; import prerna.nameserver.utility.MasterDatabaseUtility; import prerna.sablecc2.reactor.utils.ImageCaptureReactor; -import prerna.solr.SolrUtility; import prerna.util.Constants; import prerna.util.DIHelper; import prerna.util.Utility; @@ -134,7 +134,7 @@ private File getInsightImageFile(String app, String id, String feUrl, String par return f; } else { // return stock image - f = SolrUtility.getStockImage(appId, id); + f = AbstractSecurityUtils.getStockImage(appId, id); return f; } } diff --git a/src/prerna/semoss/web/services/NameServer.java b/src/prerna/semoss/web/services/NameServer.java index 7b5715169..4dbe8c368 100644 --- a/src/prerna/semoss/web/services/NameServer.java +++ b/src/prerna/semoss/web/services/NameServer.java @@ -41,7 +41,6 @@ import java.util.Date; import java.util.Enumeration; import java.util.HashMap; -import java.util.HashSet; import java.util.Hashtable; import java.util.List; import java.util.Map; @@ -74,8 +73,6 @@ import org.apache.http.util.EntityUtils; import org.apache.log4j.Logger; import org.apache.solr.client.solrj.SolrServerException; -import org.apache.solr.common.SolrDocument; -import org.apache.solr.common.SolrDocumentList; import org.jsoup.Jsoup; import com.google.gson.Gson; @@ -83,6 +80,7 @@ import com.google.gson.reflect.TypeToken; import prerna.auth.AuthProvider; +import prerna.auth.SecurityQueryUtils; import prerna.auth.User; import prerna.auth.UserPermissionsMasterDB; import prerna.engine.api.IEngine; @@ -95,9 +93,6 @@ import prerna.sablecc2.PixelRunner; import prerna.sablecc2.comm.JobManager; import prerna.sablecc2.comm.JobThread; -import prerna.solr.SolrIndexEngine; -import prerna.solr.SolrIndexEngine.SOLR_PATHS; -import prerna.solr.SolrIndexEngineQueryBuilder; import prerna.upload.DatabaseUploader; import prerna.upload.FileUploader; import prerna.upload.ImageUploader; @@ -106,7 +101,6 @@ import prerna.util.DIHelper; import prerna.util.PlaySheetRDFMapBasedEnum; import prerna.util.Utility; -import prerna.util.insight.InsightScreenshot; import prerna.web.services.util.PixelWebUtility; import prerna.web.services.util.ResponseHashSingleton; import prerna.web.services.util.SemossExecutorSingleton; @@ -215,22 +209,22 @@ public StreamingOutput getTags(@QueryParam("insight") String insight, @Context H return null; } - // gets a particular insight - @GET - @Path("central/context/getInsight") - @Produces("application/xml") - public StreamingOutput getInsight(@QueryParam("insight") String uniqueId) { - // returns the insight - // typically is a JSON of the insight - SolrDocument results = null; - try { - results = SolrIndexEngine.getInstance().getInsight(uniqueId); - } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException | SolrServerException | IOException e1) { - e1.printStackTrace(); - return WebUtility.getSO("Error executing solr query"); - } - return WebUtility.getSO(results); - } +// // gets a particular insight +// @GET +// @Path("central/context/getInsight") +// @Produces("application/xml") +// public StreamingOutput getInsight(@QueryParam("insight") String uniqueId) { +// // returns the insight +// // typically is a JSON of the insight +// SolrDocument results = null; +// try { +// results = SolrIndexEngine.getInstance().getInsight(uniqueId); +// } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException | SolrServerException | IOException e1) { +// e1.printStackTrace(); +// return WebUtility.getSO("Error executing solr query"); +// } +// return WebUtility.getSO(results); +// } /** * Get the basic information of all engines from solr. @@ -378,14 +372,20 @@ public Uploader uploadImage(@Context HttpServletRequest request) { @Path("central/context/getAutoCompleteResults") @Produces("application/json") public StreamingOutput getAutoCompleteResults(@QueryParam("completeTerm") String searchString, @Context HttpServletRequest request) { - List results = null; - try { - results = SolrIndexEngine.getInstance().executeAutoCompleteQuery(searchString); - } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException | SolrServerException - | IOException e) { - e.printStackTrace(); + List searchResults = null; + boolean securityEnabled = Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED)); + if(securityEnabled) { + HttpSession session = request.getSession(false); + User user = (User) session.getAttribute(Constants.SESSION_USER); + String userId = "-1"; + if(user != null) { + userId = user.getAccessToken(user.getLogins().get(0)).getId(); + } + searchResults = SecurityQueryUtils.predictUserInsightSearch(userId, searchString, "15", "0"); + } else { + searchResults = SecurityQueryUtils.predictInsightSearch(searchString, "15", "0"); } - return WebUtility.getSO(results); + return WebUtility.getSO(searchResults); } /** @@ -397,227 +397,56 @@ public StreamingOutput getAutoCompleteResults(@QueryParam("completeTerm") String @Path("central/context/getSearchInsightsResults") @Produces("application/json") public StreamingOutput getSearchInsightsResults(MultivaluedMap form, @Context HttpServletRequest request) { - //text searched in search bar - String searchString = form.getFirst("searchString"); - logger.info("Searching based on input: " + searchString); - - //sort field - String sortField = form.getFirst("sortField"); - logger.info("Sorting field: " + sortField); - - //sort (based on relevance, asc, desc) - String sortOrdering = form.getFirst("sortOrdering"); - logger.info("Sorting order: " + sortOrdering); - - //offset for call - String offset = form.getFirst("offset"); - logger.info("Offset is: " + offset); - - //offset for call - String limit = form.getFirst("limit"); - logger.info("Limit is: " + limit); - - Integer offsetInt = null; - Integer limitInt = null; - if(offset != null && !offset.isEmpty()) { - offsetInt = Integer.parseInt(offset); - } - if(limit != null && !limit.isEmpty()) { - limitInt = Integer.parseInt(limit); - } - - //filter based on the boxes checked in the facet filter (filtered with an exact filter) - String filterDataStr = form.getFirst("filterData"); - Gson gson = new Gson(); - Map> filterData = gson.fromJson(filterDataStr, new TypeToken>>() {}.getType()); - Map results = null; - - //If security is enabled, remove the engines in the filters that aren't accessible - if none in filters, add all accessible engines to filter list - boolean securityEnabled = Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED)); - ArrayList filterEngines = new ArrayList(); - String userId = ""; - - if(securityEnabled) { - HttpSession session = request.getSession(false); - User user = ((User) session.getAttribute(Constants.SESSION_USER)); - if(user!= null) { - userId = user.getAccessToken(AuthProvider.NATIVE).getId(); - } - - HashSet userEngines = permissions.getUserAccessibleEngines(userId); - if(filterData.get(SolrIndexEngine.APP_ID) != null) { - filterEngines.addAll(filterData.get("core_engine")); - } - if(filterEngines.size() > 0) { - for(String s : filterEngines) { - if(!userEngines.contains(s)) { - filterData.get(SolrIndexEngine.APP_ID).remove(s); - } - } - } else { - filterEngines.addAll(userEngines); - if(filterEngines.size() > 0) { - filterData.put(SolrIndexEngine.APP_ID, filterEngines); - } - } - } - - try { - results = SolrIndexEngine.getInstance().executeSearchQuery(searchString, sortField, sortOrdering, offsetInt, limitInt, filterData); - //serialize images from path - SolrDocumentList list = (SolrDocumentList) results.get("queryResponse"); - String basePath = DIHelper.getInstance().getProperty("BaseFolder"); - int imageCount = 0; - if (list != null) { - for (int i = 0; i < list.size(); i++) { - SolrDocument doc = list.get(i); - String imagePath = (String) doc.get("image"); - if (imagePath != null && imagePath.length() > 0 && !imagePath.contains("data:image/:base64")) { - imageCount++; - long startTime = System.currentTimeMillis(); - File file = new File(basePath + imagePath); - if (file.exists()) { - String image = InsightScreenshot.imageToString(basePath + imagePath); - long endTime = System.currentTimeMillis(); - long duration = endTime - startTime; - //logger.info("Time to serialize an image " + duration); - doc.put("image", "data:image/png;base64," + image); - } - } - } - } - // logger.info("total images " + imageCount ); - } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException | SolrServerException - | IOException e1) { - e1.printStackTrace(); - return WebUtility.getSO("Error executing solr query"); - } - - if(securityEnabled) { - if(filterEngines.size() == 0) { - results = new HashMap(); - } - - //Get the results based on just insight-level permissions - Map results2 = new HashMap(); - ArrayList insightIDs = new ArrayList(); - StringMap> userInsights = permissions.getInsightPermissionsForUser(userId); - for(String engineName : userInsights.keySet()) { - if(!filterEngines.contains(engineName)) { - insightIDs.addAll(userInsights.get(engineName)); - } - } - - if(!insightIDs.isEmpty()) { - filterData.clear(); - filterData.put("id", insightIDs); - - try { - results2 = SolrIndexEngine.getInstance().executeSearchQuery(searchString, sortField, sortOrdering, offsetInt, limitInt, filterData); - } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException | SolrServerException | IOException e1) { - e1.printStackTrace(); - return WebUtility.getSO("Error executing solr query"); - } - - SolrDocumentList resultsFromDBSearch = (SolrDocumentList) results.get("queryResponse"); - for(SolrDocument doc : ((SolrDocumentList)results2.get("queryResponse"))) { - if(resultsFromDBSearch.contains(doc)) { - continue; - } - resultsFromDBSearch.add(doc); - } - System.out.println(results2); - results.put("queryResponse", resultsFromDBSearch); - } - } - - return WebUtility.getSO(results); - } - - /** - * Facet count based on info from search. This faceted instance count based on specified field - * @param form - information passes in from the front end - * @return a string version of the results attained from the query/facet search - */ - // facet - @GET - @Path("central/context/getFacetInsightsResults") - @Produces("application/json") - public StreamingOutput getFacetInsightsResults(@QueryParam("searchTerm") String searchString, @Context HttpServletRequest request) { - logger.info("Searching based on input: " + searchString); - - List facetList = new ArrayList<>(); - facetList.add(SolrIndexEngine.APP_ID); - facetList.add(SolrIndexEngine.APP_NAME); - facetList.add(SolrIndexEngine.LAYOUT); - facetList.add(SolrIndexEngine.TAGS); - - Map> facetFieldMap = null; - try { - facetFieldMap = SolrIndexEngine.getInstance().executeQueryFacetResults(searchString, facetList, SOLR_PATHS.SOLR_INSIGHTS_PATH); - } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException | SolrServerException e) { - e.printStackTrace(); - } - return WebUtility.getSO(facetFieldMap); - - } - -// /** -// * GroupBy based based on info from search. This groups documents based on specified field -// * @param form - information passes in from the front end -// * @return a string version of the results attained from the query/group by search -// */ -// // group based on info from the search -// @POST -// @Path("central/context/getGroupInsightsResults") -// @Produces("application/json") -// public StreamingOutput getGroupInsightsResults(MultivaluedMap form, @Context HttpServletRequest request) { // //text searched in search bar // String searchString = form.getFirst("searchString"); // logger.info("Searching based on input: " + searchString); -// -// //specifies the starting number for the list of insights to return -// String groupOffset = form.getFirst("groupOffset"); -// logger.info("Group offset is: " + groupOffset); // -// //specifies the number of insights to return -// String groupLimit = form.getFirst("groupLimit"); -// logger.info("Group limit is: " + groupLimit); +// //sort field +// String sortField = form.getFirst("sortField"); +// logger.info("Sorting field: " + sortField); // -// String groupSort = form.getFirst("groupSort"); -// logger.info("Group sort is: " + groupSort); +// //sort (based on relevance, asc, desc) +// String sortOrdering = form.getFirst("sortOrdering"); +// logger.info("Sorting order: " + sortOrdering); +// +// //offset for call +// String offset = form.getFirst("offset"); +// logger.info("Offset is: " + offset); // -// //specifies the single field to group by -// String groupByField = form.getFirst("groupBy"); -// logger.info("Group field is: " + groupByField); +// //offset for call +// String limit = form.getFirst("limit"); +// logger.info("Limit is: " + limit); // -// Integer groupLimitInt = null; -// Integer groupOffsetInt = null; -// if(groupLimit != null && !groupLimit.isEmpty()) { -// groupLimitInt = Integer.parseInt(groupLimit); +// Integer offsetInt = null; +// Integer limitInt = null; +// if(offset != null && !offset.isEmpty()) { +// offsetInt = Integer.parseInt(offset); // } -// if(groupOffset != null && !groupOffset.isEmpty()) { -// groupOffsetInt = Integer.parseInt(groupOffset); +// if(limit != null && !limit.isEmpty()) { +// limitInt = Integer.parseInt(limit); // } // // //filter based on the boxes checked in the facet filter (filtered with an exact filter) // String filterDataStr = form.getFirst("filterData"); // Gson gson = new Gson(); // Map> filterData = gson.fromJson(filterDataStr, new TypeToken>>() {}.getType()); +// Map results = null; // // //If security is enabled, remove the engines in the filters that aren't accessible - if none in filters, add all accessible engines to filter list -// if(Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED))) { +// boolean securityEnabled = Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED)); +// ArrayList filterEngines = new ArrayList(); +// String userId = ""; +// +// if(securityEnabled) { // HttpSession session = request.getSession(false); // User user = ((User) session.getAttribute(Constants.SESSION_USER)); -// String userId = ""; // if(user!= null) { -// userId = user.getId(); +// userId = user.getAccessToken(AuthProvider.NATIVE).getId(); // } // // HashSet userEngines = permissions.getUserAccessibleEngines(userId); -// ArrayList filterEngines = new ArrayList(); // if(filterData.get(SolrIndexEngine.APP_ID) != null) { -// filterEngines.addAll(filterData.get(SolrIndexEngine.APP_ID)); +// filterEngines.addAll(filterData.get("core_engine")); // } // if(filterEngines.size() > 0) { // for(String s : filterEngines) { @@ -627,21 +456,111 @@ public StreamingOutput getFacetInsightsResults(@QueryParam("searchTerm") String // } // } else { // filterEngines.addAll(userEngines); -// if(filterEngines.size() > 0) { +// if(filterEngines.size() > 0) { // filterData.put(SolrIndexEngine.APP_ID, filterEngines); // } // } // } // -// Map groupFieldMap = null; // try { -// groupFieldMap = SolrIndexEngine.getInstance().executeQueryGroupBy(searchString, groupOffsetInt, groupLimitInt, groupByField, groupSort, filterData); -// } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException | SolrServerException | IOException e) { -// e.printStackTrace(); +// results = SolrIndexEngine.getInstance().executeSearchQuery(searchString, sortField, sortOrdering, offsetInt, limitInt, filterData); +// //serialize images from path +// SolrDocumentList list = (SolrDocumentList) results.get("queryResponse"); +// String basePath = DIHelper.getInstance().getProperty("BaseFolder"); +// int imageCount = 0; +// if (list != null) { +// for (int i = 0; i < list.size(); i++) { +// SolrDocument doc = list.get(i); +// String imagePath = (String) doc.get("image"); +// if (imagePath != null && imagePath.length() > 0 && !imagePath.contains("data:image/:base64")) { +// imageCount++; +// long startTime = System.currentTimeMillis(); +// File file = new File(basePath + imagePath); +// if (file.exists()) { +// String image = InsightScreenshot.imageToString(basePath + imagePath); +// long endTime = System.currentTimeMillis(); +// long duration = endTime - startTime; +// //logger.info("Time to serialize an image " + duration); +// doc.put("image", "data:image/png;base64," + image); +// } +// } +// } +// } +// // logger.info("total images " + imageCount ); +// } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException | SolrServerException +// | IOException e1) { +// e1.printStackTrace(); +// return WebUtility.getSO("Error executing solr query"); // } +// +// if(securityEnabled) { +// if(filterEngines.size() == 0) { +// results = new HashMap(); +// } +// +// //Get the results based on just insight-level permissions +// Map results2 = new HashMap(); +// ArrayList insightIDs = new ArrayList(); +// StringMap> userInsights = permissions.getInsightPermissionsForUser(userId); +// for(String engineName : userInsights.keySet()) { +// if(!filterEngines.contains(engineName)) { +// insightIDs.addAll(userInsights.get(engineName)); +// } +// } +// +// if(!insightIDs.isEmpty()) { +// filterData.clear(); +// filterData.put("id", insightIDs); +// +// try { +// results2 = SolrIndexEngine.getInstance().executeSearchQuery(searchString, sortField, sortOrdering, offsetInt, limitInt, filterData); +// } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException | SolrServerException | IOException e1) { +// e1.printStackTrace(); +// return WebUtility.getSO("Error executing solr query"); +// } +// +// SolrDocumentList resultsFromDBSearch = (SolrDocumentList) results.get("queryResponse"); +// for(SolrDocument doc : ((SolrDocumentList)results2.get("queryResponse"))) { +// if(resultsFromDBSearch.contains(doc)) { +// continue; +// } +// resultsFromDBSearch.add(doc); +// } +// System.out.println(results2); +// results.put("queryResponse", resultsFromDBSearch); +// } +// } +// return WebUtility.getSO(results); + return null; + } + + /** + * Facet count based on info from search. This faceted instance count based on specified field + * @param form - information passes in from the front end + * @return a string version of the results attained from the query/facet search + */ + // facet + @GET + @Path("central/context/getFacetInsightsResults") + @Produces("application/json") + public StreamingOutput getFacetInsightsResults(@QueryParam("searchTerm") String searchString, @Context HttpServletRequest request) { +// logger.info("Searching based on input: " + searchString); // -// return WebUtility.getSO(groupFieldMap); -// } +// List facetList = new ArrayList<>(); +// facetList.add(SolrIndexEngine.APP_ID); +// facetList.add(SolrIndexEngine.APP_NAME); +// facetList.add(SolrIndexEngine.LAYOUT); +// facetList.add(SolrIndexEngine.TAGS); +// +// Map> facetFieldMap = null; +// try { +// facetFieldMap = SolrIndexEngine.getInstance().executeQueryFacetResults(searchString, facetList, SOLR_PATHS.SOLR_INSIGHTS_PATH); +// } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException | SolrServerException e) { +// e.printStackTrace(); +// } +// return WebUtility.getSO(facetFieldMap); + return null; + } //////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////// @@ -748,87 +667,87 @@ public Response getMetamodel(@Context HttpServletRequest request, @QueryParam("e @POST @Path("central/context/insights") @Produces("application/json") - public Response getCentralContextInsights(MultivaluedMap form, @Context HttpServletRequest request) - throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException, SolrServerException, IOException { - Gson gson = new Gson(); - ArrayList selectedUris; - try { - selectedUris = gson.fromJson(form.getFirst("selectedURI"), ArrayList.class); - } catch (ClassCastException e) { - Map errorHash = new HashMap(); - errorHash.put("errorMessage", "Can only run related insights on concepts and properties!"); - return Response.status(400).entity(WebUtility.getSO(errorHash)).build(); - } - - // TODO: need to change the format for this call!!!!!!!!!! - String type = Utility.getClassName(selectedUris.get(0)); - if (type == null) { - // this occurs when a column is artificially created in a query - type = selectedUris.get(0); - } - - SolrIndexEngineQueryBuilder queryBuilder = new SolrIndexEngineQueryBuilder(); - queryBuilder.setSearchString(type); - //TODO: should the params be different for this than the default search? - //TODO: need to test this out more - queryBuilder.setDefaultDisMaxWeighting(); - // facet still requires a df - queryBuilder.setDefaultSearchField(SolrIndexEngine.INDEX_NAME); - - List facetList = new ArrayList<>(); - facetList.add(SolrIndexEngine.APP_ID); - facetList.add(SolrIndexEngine.LAYOUT); - facetList.add(SolrIndexEngine.TAGS); - queryBuilder.setFacetField(facetList); - - // offset for call - String offset = form.getFirst("offset"); - logger.info("Offset is: " + offset); - - // offset for call - String limit = form.getFirst("limit"); - logger.info("Limit is: " + limit); - - Integer offsetInt = null; - Integer limitInt = null; - if (offset != null && !offset.isEmpty()) { - offsetInt = Integer.parseInt(offset); - queryBuilder.setOffset(offsetInt); - } - if (limit != null && !limit.isEmpty()) { - limitInt = Integer.parseInt(limit); - queryBuilder.setLimit(limitInt); - } - - // filter based on the boxes checked in the facet filter (filtered with an exact filter) - String filterDataStr = form.getFirst("filterData"); - Gson gsonVar = new Gson(); - Map> filterData = gsonVar.fromJson(filterDataStr, new TypeToken>>() {}.getType()); - if (filterData != null && !filterData.isEmpty()) { - queryBuilder.setFilterOptions(filterData); - } - - // always sort by score and name desc - queryBuilder.setSort(SolrIndexEngine.SCORE, SolrIndexEngine.DESC); - queryBuilder.setSort(SolrIndexEngine.STORAGE_NAME, SolrIndexEngine.ASC); - - SolrDocumentList results = SolrIndexEngine.getInstance().queryDocument(queryBuilder); - // throw an error if there are no results - if (results == null) { - Map errorHash = new HashMap(); - errorHash.put("errorMessage", "No related insights found!"); + public Response getCentralContextInsights(MultivaluedMap form, @Context HttpServletRequest request) throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException, SolrServerException, IOException { +// Gson gson = new Gson(); +// ArrayList selectedUris; +// try { +// selectedUris = gson.fromJson(form.getFirst("selectedURI"), ArrayList.class); +// } catch (ClassCastException e) { +// Map errorHash = new HashMap(); +// errorHash.put("errorMessage", "Can only run related insights on concepts and properties!"); // return Response.status(400).entity(WebUtility.getSO(errorHash)).build(); - return WebUtility.getResponse(errorHash, 400); - } - // query for facet results - Map> facetCount = SolrIndexEngine.getInstance().executeQueryFacetResults(type, facetList, SOLR_PATHS.SOLR_INSIGHTS_PATH); - - Map retMap = new HashMap(); - retMap.put(SolrIndexEngine.NUM_FOUND, results.getNumFound()); - retMap.put("results", results); - retMap.put("facet", facetCount); -// return Response.status(200).entity(WebUtility.getSO(retMap)).build(); - return WebUtility.getResponse(retMap, 200); +// } +// +// // TODO: need to change the format for this call!!!!!!!!!! +// String type = Utility.getClassName(selectedUris.get(0)); +// if (type == null) { +// // this occurs when a column is artificially created in a query +// type = selectedUris.get(0); +// } +// +// SolrIndexEngineQueryBuilder queryBuilder = new SolrIndexEngineQueryBuilder(); +// queryBuilder.setSearchString(type); +// //TODO: should the params be different for this than the default search? +// //TODO: need to test this out more +// queryBuilder.setDefaultDisMaxWeighting(); +// // facet still requires a df +// queryBuilder.setDefaultSearchField(SolrIndexEngine.INDEX_NAME); +// +// List facetList = new ArrayList<>(); +// facetList.add(SolrIndexEngine.APP_ID); +// facetList.add(SolrIndexEngine.LAYOUT); +// facetList.add(SolrIndexEngine.TAGS); +// queryBuilder.setFacetField(facetList); +// +// // offset for call +// String offset = form.getFirst("offset"); +// logger.info("Offset is: " + offset); +// +// // offset for call +// String limit = form.getFirst("limit"); +// logger.info("Limit is: " + limit); +// +// Integer offsetInt = null; +// Integer limitInt = null; +// if (offset != null && !offset.isEmpty()) { +// offsetInt = Integer.parseInt(offset); +// queryBuilder.setOffset(offsetInt); +// } +// if (limit != null && !limit.isEmpty()) { +// limitInt = Integer.parseInt(limit); +// queryBuilder.setLimit(limitInt); +// } +// +// // filter based on the boxes checked in the facet filter (filtered with an exact filter) +// String filterDataStr = form.getFirst("filterData"); +// Gson gsonVar = new Gson(); +// Map> filterData = gsonVar.fromJson(filterDataStr, new TypeToken>>() {}.getType()); +// if (filterData != null && !filterData.isEmpty()) { +// queryBuilder.setFilterOptions(filterData); +// } +// +// // always sort by score and name desc +// queryBuilder.setSort(SolrIndexEngine.SCORE, SolrIndexEngine.DESC); +// queryBuilder.setSort(SolrIndexEngine.STORAGE_NAME, SolrIndexEngine.ASC); +// +// SolrDocumentList results = SolrIndexEngine.getInstance().queryDocument(queryBuilder); +// // throw an error if there are no results +// if (results == null) { +// Map errorHash = new HashMap(); +// errorHash.put("errorMessage", "No related insights found!"); +//// return Response.status(400).entity(WebUtility.getSO(errorHash)).build(); +// return WebUtility.getResponse(errorHash, 400); +// } +// // query for facet results +// Map> facetCount = SolrIndexEngine.getInstance().executeQueryFacetResults(type, facetList, SOLR_PATHS.SOLR_INSIGHTS_PATH); +// +// Map retMap = new HashMap(); +// retMap.put(SolrIndexEngine.NUM_FOUND, results.getNumFound()); +// retMap.put("results", results); +// retMap.put("facet", facetCount); +//// return Response.status(200).entity(WebUtility.getSO(retMap)).build(); +// return WebUtility.getResponse(retMap, 200); + return null; } private StreamingOutput getSOHTML() { diff --git a/src/prerna/upload/DatabaseUploader.java b/src/prerna/upload/DatabaseUploader.java index 24e39f045..c917744b4 100644 --- a/src/prerna/upload/DatabaseUploader.java +++ b/src/prerna/upload/DatabaseUploader.java @@ -18,11 +18,9 @@ import java.util.Vector; import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; import javax.ws.rs.core.Context; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; @@ -39,13 +37,11 @@ import prerna.auth.User; import prerna.auth.UserPermissionsMasterDB; import prerna.engine.impl.SmssUtilities; -import prerna.engine.impl.solr.SolrEngine; import prerna.nameserver.AddToMasterDB; import prerna.poi.main.CSVPropFileBuilder; import prerna.poi.main.ExcelPropFileBuilder; import prerna.poi.main.HeadersException; import prerna.poi.main.MetaModelCreator; -import prerna.poi.main.SolrEngineConnector; import prerna.poi.main.helper.CSVFileHelper; import prerna.poi.main.helper.FileHelperUtil; import prerna.poi.main.helper.ImportOptions; @@ -1268,91 +1264,91 @@ public Response uploadNLPFile(@Context HttpServletRequest request) { return Response.status(200).entity(gson.toJson(outputText)).build(); } - @GET - @Path("/solr/ping") - @Produces("applicaiton/json") - public Response validSolrEngine(@QueryParam("solrURL") String solrURL , @QueryParam("coreName") String coreName) { - boolean isValid = SolrEngine.ping(solrURL, coreName); - return WebUtility.getResponse(isValid, 200); - } - - @POST - @Path("/solr/getMetamodel") - @Produces("applicaiton/json") - public Response getSolrMetadata(@Context HttpServletRequest request, MultivaluedMap form) { - String solrURL = form.getFirst("solrURL"); - String coreName = form.getFirst("coreName"); - boolean isValid = SolrEngine.ping(solrURL, coreName); - if(isValid) { - Map schemaData = SolrEngine.getSchema(solrURL, coreName); - // we send a really weird object - // so going format this data into that format - List columnHeaders = (List) schemaData.get(SolrEngine.SCHEMA_HEADERS_KEY); - List columnTypes = (List) schemaData.get(SolrEngine.SCHEMA_DATA_TYPE_KEY); - String key = (String) schemaData.get(SolrEngine.SCHEMA_UNIQUE_HEADER_KEY); - String keyType = (String) schemaData.get(SolrEngine.SCHEMA_UNIQUE_HEADER_DATA_TYPE_KEY); - - Map retMap = new HashMap(); - Map>> tableMap = new HashMap>>(); - retMap.put("tables", tableMap); - // we only have one table in our solr metamodel - List> fieldList = new Vector>(); - // add the name of the "table" -> i.e. the unique field - // to all of the other fields - tableMap.put(key, fieldList); - int numFields = columnHeaders.size(); - for(int i = 0; i < numFields; i++) { - Map fieldMap = new HashMap(); - String field = columnHeaders.get(i); - fieldMap.put("name", field); - fieldMap.put("type", columnTypes.get(i)); - if(field.equals(key)) { - fieldMap.put("isPK", true); - } else { - fieldMap.put("isPK", false); - } - fieldList.add(fieldMap); - } - - return WebUtility.getResponse(retMap, 200); - } else { - Map errorMap = new HashMap(); - errorMap.put("errorMessage", "Unable to successfully connect to solr instance at " + solrURL); - return WebUtility.getResponse(errorMap, 400); - } - } - - @POST - @Path("/solr/loadSolrEngine") - @Produces("applicaiton/json") - public Response loadSolrEngine(@Context HttpServletRequest request, MultivaluedMap form) { - String solrURL = form.getFirst("solrURL"); - String coreName = form.getFirst("coreName"); - boolean isValid = SolrEngine.ping(solrURL, coreName); - String appName = form.getFirst("dbName"); - String appID = UUID.randomUUID().toString(); - - if(isValid) { - appName = Utility.makeAlphaNumeric(appName); - SolrEngineConnector connector = new SolrEngineConnector(); - try { - connector.processExistingSolrConnection(appName, appID, solrURL, coreName ); - } catch (IOException e) { - e.printStackTrace(); - Map errorMap = new HashMap(); - errorMap.put("errorMessage", e.getMessage()); - return WebUtility.getResponse(errorMap, 400); - } - boolean success = true; - Map ret = new HashMap(); - ret.put("success", success); - return WebUtility.getResponse(ret, 200); - } else { - Map errorMap = new HashMap(); - errorMap.put("errorMessage", "Unable to successfully connect to solr instance at " + solrURL); - return WebUtility.getResponse(errorMap, 400); - } - } +// @GET +// @Path("/solr/ping") +// @Produces("applicaiton/json") +// public Response validSolrEngine(@QueryParam("solrURL") String solrURL , @QueryParam("coreName") String coreName) { +// boolean isValid = SolrEngine.ping(solrURL, coreName); +// return WebUtility.getResponse(isValid, 200); +// } +// +// @POST +// @Path("/solr/getMetamodel") +// @Produces("applicaiton/json") +// public Response getSolrMetadata(@Context HttpServletRequest request, MultivaluedMap form) { +// String solrURL = form.getFirst("solrURL"); +// String coreName = form.getFirst("coreName"); +// boolean isValid = SolrEngine.ping(solrURL, coreName); +// if(isValid) { +// Map schemaData = SolrEngine.getSchema(solrURL, coreName); +// // we send a really weird object +// // so going format this data into that format +// List columnHeaders = (List) schemaData.get(SolrEngine.SCHEMA_HEADERS_KEY); +// List columnTypes = (List) schemaData.get(SolrEngine.SCHEMA_DATA_TYPE_KEY); +// String key = (String) schemaData.get(SolrEngine.SCHEMA_UNIQUE_HEADER_KEY); +// String keyType = (String) schemaData.get(SolrEngine.SCHEMA_UNIQUE_HEADER_DATA_TYPE_KEY); +// +// Map retMap = new HashMap(); +// Map>> tableMap = new HashMap>>(); +// retMap.put("tables", tableMap); +// // we only have one table in our solr metamodel +// List> fieldList = new Vector>(); +// // add the name of the "table" -> i.e. the unique field +// // to all of the other fields +// tableMap.put(key, fieldList); +// int numFields = columnHeaders.size(); +// for(int i = 0; i < numFields; i++) { +// Map fieldMap = new HashMap(); +// String field = columnHeaders.get(i); +// fieldMap.put("name", field); +// fieldMap.put("type", columnTypes.get(i)); +// if(field.equals(key)) { +// fieldMap.put("isPK", true); +// } else { +// fieldMap.put("isPK", false); +// } +// fieldList.add(fieldMap); +// } +// +// return WebUtility.getResponse(retMap, 200); +// } else { +// Map errorMap = new HashMap(); +// errorMap.put("errorMessage", "Unable to successfully connect to solr instance at " + solrURL); +// return WebUtility.getResponse(errorMap, 400); +// } +// } +// +// @POST +// @Path("/solr/loadSolrEngine") +// @Produces("applicaiton/json") +// public Response loadSolrEngine(@Context HttpServletRequest request, MultivaluedMap form) { +// String solrURL = form.getFirst("solrURL"); +// String coreName = form.getFirst("coreName"); +// boolean isValid = SolrEngine.ping(solrURL, coreName); +// String appName = form.getFirst("dbName"); +// String appID = UUID.randomUUID().toString(); +// +// if(isValid) { +// appName = Utility.makeAlphaNumeric(appName); +// SolrEngineConnector connector = new SolrEngineConnector(); +// try { +// connector.processExistingSolrConnection(appName, appID, solrURL, coreName ); +// } catch (IOException e) { +// e.printStackTrace(); +// Map errorMap = new HashMap(); +// errorMap.put("errorMessage", e.getMessage()); +// return WebUtility.getResponse(errorMap, 400); +// } +// boolean success = true; +// Map ret = new HashMap(); +// ret.put("success", success); +// return WebUtility.getResponse(ret, 200); +// } else { +// Map errorMap = new HashMap(); +// errorMap.put("errorMessage", "Unable to successfully connect to solr instance at " + solrURL); +// return WebUtility.getResponse(errorMap, 400); +// } +// } @POST @Path("/rdbms/getMetadata2") diff --git a/src/prerna/web/conf/DBLoader.java b/src/prerna/web/conf/DBLoader.java index 605d3f03d..922fee559 100644 --- a/src/prerna/web/conf/DBLoader.java +++ b/src/prerna/web/conf/DBLoader.java @@ -27,19 +27,17 @@ *******************************************************************************/ package prerna.web.conf; -import java.io.File; - import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import org.apache.log4j.PropertyConfigurator; +import com.ibm.icu.util.StringTokenizer; + import prerna.util.AbstractFileWatcher; import prerna.util.Constants; import prerna.util.DIHelper; -import com.ibm.icu.util.StringTokenizer; - public class DBLoader implements ServletContextListener { public static final String RDFMAP = "RDF-MAP"; @@ -62,12 +60,12 @@ public void contextInitialized(ServletContextEvent arg0) { System.out.println("Setting log4j property: " + log4jConfig); PropertyConfigurator.configure(log4jConfig); - //Set Solr home variable (~SEMOSS_PROJ_HOME/Solr) - String solrHome = DIHelper.getInstance().getProperty("BaseFolder") + "/" + Constants.SOLR_HOME_DIR; - if((new File(solrHome)).exists()) { - System.out.println("Setting Solr home: " + solrHome); - System.setProperty("solr.solr.home", solrHome); - } +// //Set Solr home variable (~SEMOSS_PROJ_HOME/Solr) +// String solrHome = DIHelper.getInstance().getProperty("BaseFolder") + "/" + Constants.SOLR_HOME_DIR; +// if((new File(solrHome)).exists()) { +// System.out.println("Setting Solr home: " + solrHome); +// System.setProperty("solr.solr.home", solrHome); +// } //Load empty engine list into DIHelper, then load engines from db folder System.out.println("Loading engines..."); From c760985d38e4a328f5dbf757c665945a87b8b362 Mon Sep 17 00:00:00 2001 From: tbanach Date: Tue, 26 Jun 2018 18:37:42 +0000 Subject: [PATCH 0116/1906] UPDATE ::: CI - Changing the folder structure of tar.gz for libs git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28910 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: ac5b167ff58ad223866489250e8a45c8f51b055f --- libraries.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries.xml b/libraries.xml index 1542cfb61..cda3e2144 100644 --- a/libraries.xml +++ b/libraries.xml @@ -7,7 +7,7 @@ - ${project.build.directory}/${project.build.finalName}/WEB-INF/lib + ${project.build.directory}/WEB-INF/lib WEB-INF/lib From 384aa10e946e446dcf911c2c986c61d7a3b80502 Mon Sep 17 00:00:00 2001 From: tbanach Date: Tue, 26 Jun 2018 19:00:45 +0000 Subject: [PATCH 0117/1906] BUGFIX ::: CI - use latest version of SEMOSS snapshot git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28917 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 0024f8ee1c62baf3333da71ec1338a07c138e3ab --- .gitlab-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0b6cb7f85..c6ae33873 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -36,6 +36,7 @@ build_deploy: only: - web script: + - mvn versions:use-latest-snapshots -Dincludes=org.semoss:semoss - mvn $MAVEN_CLI_OPTS deploy -P deploy artifacts: paths: From a3e3e69dbeb2e85da91412472237d5b7638b4c1f Mon Sep 17 00:00:00 2001 From: tbanach Date: Tue, 26 Jun 2018 19:01:43 +0000 Subject: [PATCH 0118/1906] BUFGIX ::: CI - forgot to add mvn config in both stages of build git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28918 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 93acef5449cdc449e39c9331367a858c4ad4991d --- .gitlab-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c6ae33873..94645ab52 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -25,6 +25,7 @@ build_dev: only: - pushes script: + - mvn versions:use-latest-snapshots -Dincludes=org.semoss:semoss - mvn $MAVEN_CLI_OPTS clean install artifacts: paths: From 1e63fb30374a9a6fe13fbc5d97c442d957242eb8 Mon Sep 17 00:00:00 2001 From: tbanach Date: Tue, 26 Jun 2018 19:18:37 +0000 Subject: [PATCH 0119/1906] BUGFIX ::: CI - manually deleting cache git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28920 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 7cf481966d383d79d0986c4795b43274318e02f6 --- .gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 94645ab52..4d028a61c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -25,7 +25,7 @@ build_dev: only: - pushes script: - - mvn versions:use-latest-snapshots -Dincludes=org.semoss:semoss + - rm -rf .m2/repository/org/semoss - mvn $MAVEN_CLI_OPTS clean install artifacts: paths: @@ -37,7 +37,7 @@ build_deploy: only: - web script: - - mvn versions:use-latest-snapshots -Dincludes=org.semoss:semoss + - rm -rf .m2/repository/org/semoss - mvn $MAVEN_CLI_OPTS deploy -P deploy artifacts: paths: From ffa9a9444af87be6085271eaff2fc2d229d45517 Mon Sep 17 00:00:00 2001 From: tbanach Date: Tue, 26 Jun 2018 19:35:09 +0000 Subject: [PATCH 0120/1906] BUGFIX ::: CI - reverting location of libs git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28922 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: e6071c53e9272050d3dbbad615ad82539aa730ac --- libraries.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries.xml b/libraries.xml index cda3e2144..1542cfb61 100644 --- a/libraries.xml +++ b/libraries.xml @@ -7,7 +7,7 @@ - ${project.build.directory}/WEB-INF/lib + ${project.build.directory}/${project.build.finalName}/WEB-INF/lib WEB-INF/lib From fdd2c73d5b8de1eab9130071923d398ca362eb1c Mon Sep 17 00:00:00 2001 From: tbanach Date: Tue, 26 Jun 2018 21:02:08 +0000 Subject: [PATCH 0121/1906] REQUIREMENT ::: Maven update Semoss and Monolith BUGFIX ::: Roxy's and Angelo's runtime dep errors should be fixed by these two jars git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28932 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 3690b0e5202a0e26aa9cbdad97fcfa751b7b65dc --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 8f0b013ab..b0f393773 100644 --- a/pom.xml +++ b/pom.xml @@ -1365,7 +1365,7 @@ - + org.apache.lucene lucene-core @@ -2602,11 +2602,11 @@ 1.11.106 - + org.json json From d752819b715d5dac82b49596cb4b371188f0e216 Mon Sep 17 00:00:00 2001 From: tbanach Date: Tue, 26 Jun 2018 21:51:05 +0000 Subject: [PATCH 0122/1906] UPDATE ::: Including only semoss jar in lib of deploy git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28935 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: b4a4ea526916ded3cb75551c3f4a168dc05296c3 --- pom.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index b0f393773..b1440cfd4 100644 --- a/pom.xml +++ b/pom.xml @@ -113,7 +113,9 @@ WebContent/WEB-INF/web.xml true - WEB-INF/lib/*.jar + + %regex[WEB-INF/lib/(?!semoss-${ci.version}).*.jar] + From 6526b356b6ab68d5010e6444fc3fa6a6dba1e5ba Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 27 Jun 2018 12:29:30 +0000 Subject: [PATCH 0123/1906] UPDATE ::: If security enabled, there must be a user object to upload data - need to build this out still UPDATE ::: Creating file paths that user specified in web.xml for upload git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28943 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 5efb77a241b34d37e9ea27c514e8b355a849ef63 --- src/prerna/upload/DatabaseUploader.java | 21 ++++++++++++++++++--- src/prerna/upload/Uploader.java | 8 ++++++++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/prerna/upload/DatabaseUploader.java b/src/prerna/upload/DatabaseUploader.java index c917744b4..713acd2fb 100644 --- a/src/prerna/upload/DatabaseUploader.java +++ b/src/prerna/upload/DatabaseUploader.java @@ -1025,7 +1025,12 @@ public Response uploadExcelPOIFormat(@Context HttpServletRequest request) // add engine owner for permissions if(this.securityEnabled) { - User user = (User) request.getSession().getAttribute("semoss_user"); + User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); + if(user == null) { + Map errorHash = new HashMap(); + errorHash.put("errorMessage", "User must be signed into an account in order to create a database"); + return Response.status(400).entity(gson.toJson(errorHash)).build(); + } String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); if(user != null && !userId.equals(Constants.ANONYMOUS_USER_ID)) { addEngineOwner(options.getEngineID(), options.getDbName(), userId); @@ -1226,7 +1231,12 @@ public Response uploadNLPFile(@Context HttpServletRequest request) { // add engine owner for permissions if(this.securityEnabled) { - User user = (User) request.getSession().getAttribute("semoss_user"); + User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); + if(user == null) { + Map errorHash = new HashMap(); + errorHash.put("errorMessage", "User must be signed into an account in order to create a database"); + return Response.status(400).entity(gson.toJson(errorHash)).build(); + } String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); if(user != null && !userId.equals(Constants.ANONYMOUS_USER_ID)) { addEngineOwner(options.getEngineID(), options.getDbName(), userId); @@ -1422,7 +1432,12 @@ public Response connectExistingRDBMS(@Context HttpServletRequest request, Multiv importOptions.setEngineID(appID); // add engine owner for permissions if(this.securityEnabled) { - User user = (User) request.getSession().getAttribute("semoss_user"); + User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); + if(user == null) { + Map errorHash = new HashMap(); + errorHash.put("errorMessage", "User must be signed into an account in order to create a database"); + return Response.status(400).entity(gson.toJson(errorHash)).build(); + } String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); if(user != null && !userId.equals(Constants.ANONYMOUS_USER_ID)) { addEngineOwner(appID, options.get("dbName"), userId); diff --git a/src/prerna/upload/Uploader.java b/src/prerna/upload/Uploader.java index dcef6d18c..ba00b3f44 100644 --- a/src/prerna/upload/Uploader.java +++ b/src/prerna/upload/Uploader.java @@ -80,10 +80,18 @@ public void setFilePath(String filePath) { } else { this.filePath = filePath + DIR_SEPARATOR; } + File f = new File(this.filePath); + if(!f.exists() && !f.isDirectory()) { + f.mkdirs(); + } } public void setTempFilePath(String tempFilePath){ this.tempFilePath = tempFilePath; + File tFile = new File(tempFilePath); + if(!tFile.exists() && !tFile.isDirectory()) { + tFile.mkdirs(); + } } public void setSecurityEnabled(boolean securityEnabled) { From 961a7301c9f4ceeb594381bdde8275be160ad668 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 27 Jun 2018 13:46:43 +0000 Subject: [PATCH 0124/1906] UPDATE ::: Improving logic on upload to set every access token into engine permission git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28946 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 60bde0d9bab1df52b7ff8762dce69a1c2ef82844 --- src/prerna/upload/DatabaseUploader.java | 66 +++++++++++-------------- 1 file changed, 29 insertions(+), 37 deletions(-) diff --git a/src/prerna/upload/DatabaseUploader.java b/src/prerna/upload/DatabaseUploader.java index 713acd2fb..654d1b576 100644 --- a/src/prerna/upload/DatabaseUploader.java +++ b/src/prerna/upload/DatabaseUploader.java @@ -34,8 +34,8 @@ import com.google.gson.reflect.TypeToken; import prerna.auth.AuthProvider; +import prerna.auth.SecurityUpdateUtils; import prerna.auth.User; -import prerna.auth.UserPermissionsMasterDB; import prerna.engine.impl.SmssUtilities; import prerna.nameserver.AddToMasterDB; import prerna.poi.main.CSVPropFileBuilder; @@ -598,15 +598,16 @@ public Response uploadCSVFile(MultivaluedMap form, @Context Http // add engine owner for permissions if(this.securityEnabled) { - User user = (User) request.getSession().getAttribute("semoss_user"); - String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); - if(user != null && !userId.equals(Constants.ANONYMOUS_USER_ID)) { - addEngineOwner(options.getEngineID(), options.getDbName(), userId); - } else { + User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); + if(user == null) { Map errorHash = new HashMap(); - errorHash.put("errorMessage", "Please log in to upload data."); + errorHash.put("errorMessage", "User must be signed into an account in order to create a database"); return Response.status(400).entity(gson.toJson(errorHash)).build(); } + List logins = user.getLogins(); + for(AuthProvider ap : logins) { + addEngineOwner(options.getEngineID(), options.getDbName(), user.getAccessToken(ap).getId()); + } } // run the import @@ -933,15 +934,16 @@ public Response processExcelFile(@Context HttpServletRequest request) // add engine owner for permissions if(this.securityEnabled) { - User user = (User) request.getSession().getAttribute("semoss_user"); - String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); - if(user != null && !userId.equals(Constants.ANONYMOUS_USER_ID)) { - addEngineOwner(options.getEngineID(), options.getDbName(), userId); - } else { + User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); + if(user == null) { Map errorHash = new HashMap(); - errorHash.put("errorMessage", "Please log in to upload data."); + errorHash.put("errorMessage", "User must be signed into an account in order to create a database"); return Response.status(400).entity(gson.toJson(errorHash)).build(); } + List logins = user.getLogins(); + for(AuthProvider ap : logins) { + addEngineOwner(options.getEngineID(), options.getDbName(), user.getAccessToken(ap).getId()); + } } // run the processor @@ -1031,13 +1033,9 @@ public Response uploadExcelPOIFormat(@Context HttpServletRequest request) errorHash.put("errorMessage", "User must be signed into an account in order to create a database"); return Response.status(400).entity(gson.toJson(errorHash)).build(); } - String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); - if(user != null && !userId.equals(Constants.ANONYMOUS_USER_ID)) { - addEngineOwner(options.getEngineID(), options.getDbName(), userId); - } else { - Map errorHash = new HashMap(); - errorHash.put("errorMessage", "Please log in to upload data."); - return Response.status(400).entity(gson.toJson(errorHash)).build(); + List logins = user.getLogins(); + for(AuthProvider ap : logins) { + addEngineOwner(options.getEngineID(), options.getDbName(), user.getAccessToken(ap).getId()); } } @@ -1237,13 +1235,9 @@ public Response uploadNLPFile(@Context HttpServletRequest request) { errorHash.put("errorMessage", "User must be signed into an account in order to create a database"); return Response.status(400).entity(gson.toJson(errorHash)).build(); } - String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); - if(user != null && !userId.equals(Constants.ANONYMOUS_USER_ID)) { - addEngineOwner(options.getEngineID(), options.getDbName(), userId); - } else { - Map errorHash = new HashMap(); - errorHash.put("errorMessage", "Please log in to upload data."); - return Response.status(400).entity(gson.toJson(errorHash)).build(); + List logins = user.getLogins(); + for(AuthProvider ap : logins) { + addEngineOwner(options.getEngineID(), options.getDbName(), user.getAccessToken(ap).getId()); } } @@ -1425,7 +1419,8 @@ public Response connectExistingRDBMS(@Context HttpServletRequest request, Multiv HashMap databaseOptions = gson.fromJson(gson.toJson(details.get("databaseOptions")), new TypeToken>() {}.getType()); HashMap options = gson.fromJson(gson.toJson(details.get("options")), new TypeToken>() {}.getType()); - options.put("dbName", Utility.makeAlphaNumeric(databaseOptions.get("databaseName"))); + String appName = Utility.makeAlphaNumeric(databaseOptions.get("databaseName")); + options.put("dbName", appName); ImportOptions importOptions = setupImportOptionsForExternalConnection(options, metamodel); String appID = UUID.randomUUID().toString(); @@ -1438,13 +1433,9 @@ public Response connectExistingRDBMS(@Context HttpServletRequest request, Multiv errorHash.put("errorMessage", "User must be signed into an account in order to create a database"); return Response.status(400).entity(gson.toJson(errorHash)).build(); } - String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); - if(user != null && !userId.equals(Constants.ANONYMOUS_USER_ID)) { - addEngineOwner(appID, options.get("dbName"), userId); - } else { - Map errorHash = new HashMap(); - errorHash.put("errorMessage", "Please log in to upload data."); - return Response.status(400).entity(gson.toJson(errorHash)).build(); + List logins = user.getLogins(); + for(AuthProvider ap : logins) { + addEngineOwner(appID, appName, user.getAccessToken(ap).getId()); } } @@ -1541,8 +1532,9 @@ private String processOpenRefine(String dbName, String cleanedValues) { } public void addEngineOwner(String engineId, String engine, String userId) { - UserPermissionsMasterDB masterDB = new UserPermissionsMasterDB(); - masterDB.addEngineAndOwner(engineId, engine, userId); + SecurityUpdateUtils.addEngineAndOwner(engineId, engine, userId); +// UserPermissionsMasterDB masterDB = new UserPermissionsMasterDB(); +// masterDB.addEngineAndOwner(engineId, engine, userId); } @POST From ed27f59843a6e923c6c1f2a098ea74b8b9305f87 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 27 Jun 2018 14:39:38 +0000 Subject: [PATCH 0125/1906] UPDATE ::: Not deleting security db on start up anymore UPDATE ::: Adding test filter for forms cac mocking git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28947 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 811e17830d454179de27ce828143a8639357f87d --- src/prerna/web/conf/TestFilter.java | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/prerna/web/conf/TestFilter.java b/src/prerna/web/conf/TestFilter.java index d0e853dfb..782a6d11f 100644 --- a/src/prerna/web/conf/TestFilter.java +++ b/src/prerna/web/conf/TestFilter.java @@ -30,15 +30,23 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 User user = new User(); AccessToken token = new AccessToken(); - token.setProvider(AuthProvider.NATIVE); - token.setEmail("mahkhalil@deloitte.com"); - token.setName("Maher"); - token.setId("111"); + token.setProvider(AuthProvider.CAC); + token.setEmail("admin@health.mil"); + token.setName("CAC_ADMIN_USER"); + token.setId("12345"); + +// User user = new User(); +// AccessToken token = new AccessToken(); +// token.setProvider(AuthProvider.CAC); +// token.setEmail("readonly@health.mil"); +// token.setName("CAC_READ_ONLY"); +// token.setId("54321"); user.setAccessToken(token); session.setAttribute(Constants.SESSION_USER, user); arg2.doFilter(arg0, arg1); + } @Override From 3a9b339058922f1e7456dac94c89cb3d69c8c772 Mon Sep 17 00:00:00 2001 From: rramirezjimenez Date: Wed, 27 Jun 2018 19:27:46 +0000 Subject: [PATCH 0126/1906] UPDATE ::: Connect to External calls new reactor for now git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28960 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 2748315d77a35cafcee20de626f26552acc906c9 --- src/prerna/upload/DatabaseUploader.java | 109 ++++++++++++++++++------ 1 file changed, 85 insertions(+), 24 deletions(-) diff --git a/src/prerna/upload/DatabaseUploader.java b/src/prerna/upload/DatabaseUploader.java index 654d1b576..855c252ef 100644 --- a/src/prerna/upload/DatabaseUploader.java +++ b/src/prerna/upload/DatabaseUploader.java @@ -38,6 +38,8 @@ import prerna.auth.User; import prerna.engine.impl.SmssUtilities; import prerna.nameserver.AddToMasterDB; +import prerna.om.Insight; +import prerna.om.InsightStore; import prerna.poi.main.CSVPropFileBuilder; import prerna.poi.main.ExcelPropFileBuilder; import prerna.poi.main.HeadersException; @@ -47,6 +49,12 @@ import prerna.poi.main.helper.ImportOptions; import prerna.poi.main.helper.XLFileHelper; import prerna.rdf.main.ImportRDBMSProcessor; +import prerna.sablecc2.om.GenRowStruct; +import prerna.sablecc2.om.PixelDataType; +import prerna.sablecc2.om.ReactorKeysEnum; +import prerna.sablecc2.om.nounmeta.NounMetadata; +import prerna.sablecc2.reactor.PixelPlanner; +import prerna.sablecc2.reactor.app.upload.rdbms.csv.RdbmsExternalUploadReactor; import prerna.ui.components.ImportDataProcessor; import prerna.util.Constants; import prerna.util.DIHelper; @@ -943,7 +951,7 @@ public Response processExcelFile(@Context HttpServletRequest request) List logins = user.getLogins(); for(AuthProvider ap : logins) { addEngineOwner(options.getEngineID(), options.getDbName(), user.getAccessToken(ap).getId()); - } + } } // run the processor @@ -1391,15 +1399,14 @@ public Response getExistingRDBMSMetadata2(@Context HttpServletRequest request, M public Response connectExistingRDBMS(@Context HttpServletRequest request, MultivaluedMap form) { Gson gson = new Gson(); HashMap ret = new HashMap(1); - ImportDataProcessor importer = new ImportDataProcessor(); - HashMap metamodel = new HashMap(2); + Map metamodel = new HashMap(); HashMap details = gson.fromJson(form.getFirst("details"), new TypeToken>() {}.getType()); HashMap metamodelData = gson.fromJson(gson.toJson(details.get("metamodelData")), new TypeToken>() {}.getType()); ArrayList nodes = gson.fromJson(gson.toJson(metamodelData.get("nodes")), new TypeToken>() {}.getType()); ArrayList relationships = gson.fromJson(gson.toJson(metamodelData.get("relationships")), new TypeToken>() {}.getType()); + // reformat metamodel for new reactor HashMap> nodesAndProps = new HashMap>(nodes.size()); - ArrayList nodeRelationships = new ArrayList(relationships.size()); - + ArrayList> nodeRelationships = new ArrayList<>(relationships.size()); for(Object o: nodes) { ArrayList props = new ArrayList(); HashMap nodeHash = gson.fromJson(gson.toJson(o), new TypeToken>() {}.getType()); @@ -1409,23 +1416,86 @@ public Response connectExistingRDBMS(@Context HttpServletRequest request, Multiv } nodesAndProps.put(nodeHash.get("node") + "." + nodeHash.get("primaryKey"), props); // Table1.idTable1 -> [prop1, prop2, ...] } - metamodel.put("nodes", nodesAndProps); - + metamodel.put(Constants.NODE_PROP, nodesAndProps); for(Object o: relationships) { HashMap relationship = gson.fromJson(gson.toJson(o), new TypeToken>() {}.getType()); - nodeRelationships.add(new String[] { relationship.get("sub"), relationship.get("pred"), relationship.get("obj") }); + String fromTable = relationship.get("sub"); + String relName = relationship.get("pred"); + String toTable = relationship.get("obj"); + Map relMap = new HashMap<>(); + relMap.put(Constants.FROM_TABLE, fromTable); + relMap.put(Constants.REL_NAME, relName); + relMap.put(Constants.TO_TABLE, toTable); + nodeRelationships.add(relMap); } - metamodel.put("relationships", nodeRelationships); + metamodel.put(Constants.RELATION, nodeRelationships); HashMap databaseOptions = gson.fromJson(gson.toJson(details.get("databaseOptions")), new TypeToken>() {}.getType()); HashMap options = gson.fromJson(gson.toJson(details.get("options")), new TypeToken>() {}.getType()); - String appName = Utility.makeAlphaNumeric(databaseOptions.get("databaseName")); - options.put("dbName", appName); - ImportOptions importOptions = setupImportOptionsForExternalConnection(options, metamodel); + options.put("dbName", Utility.makeAlphaNumeric(databaseOptions.get("databaseName"))); - String appID = UUID.randomUUID().toString(); - importOptions.setEngineID(appID); - // add engine owner for permissions + boolean success = true; + + // mocking inputs until FE makes full pixel call + RdbmsExternalUploadReactor reactor = new RdbmsExternalUploadReactor(); + reactor.In(); + // make an insight to set + // so we can pass the user + Insight dummyIn = new Insight(); + InsightStore.getInstance().put(dummyIn); + //TODO do we need this? + // InsightStore.getInstance().addToSessionHash(session.getId(), + // dummyIn.getInsightId()); + // dummyIn.getVarStore().put(JobReactor.SESSION_KEY, new + // NounMetadata(session.getId(), PixelDataType.CONST_STRING)); + // dummyIn.setUser(user); + reactor.setInsight(dummyIn); + PixelPlanner planner = new PixelPlanner(); + planner.setVarStore(dummyIn.getVarStore()); + reactor.setPixelPlanner(planner); + // add app name + GenRowStruct grs1 = new GenRowStruct(); + grs1.add(new NounMetadata(Utility.makeAlphaNumeric(databaseOptions.get("databaseName")), + PixelDataType.CONST_STRING)); + reactor.getNounStore().addNoun(ReactorKeysEnum.APP.getKey(), grs1); + // add db driver + GenRowStruct grs2 = new GenRowStruct(); + grs2.add(new NounMetadata(options.get("driver"), PixelDataType.CONST_STRING)); + reactor.getNounStore().addNoun(ReactorKeysEnum.DB_DRIVER_KEY.getKey(), grs2); + // add host + GenRowStruct grs3 = new GenRowStruct(); + grs3.add(new NounMetadata(options.get("hostname"), PixelDataType.CONST_STRING)); + reactor.getNounStore().addNoun(ReactorKeysEnum.HOST.getKey(), grs3); + // add port + GenRowStruct grs4 = new GenRowStruct(); + grs4.add(new NounMetadata(options.get("port"), PixelDataType.CONST_STRING)); + reactor.getNounStore().addNoun(ReactorKeysEnum.PORT.getKey(), grs4); + // add schema + GenRowStruct grs5 = new GenRowStruct(); + grs5.add(new NounMetadata(options.get("schema"), PixelDataType.CONST_STRING)); + reactor.getNounStore().addNoun(ReactorKeysEnum.SCHEMA.getKey(), grs5); + // add username + GenRowStruct grs6 = new GenRowStruct(); + grs6.add(new NounMetadata(options.get("username"), PixelDataType.CONST_STRING)); + reactor.getNounStore().addNoun(ReactorKeysEnum.USERNAME.getKey(), grs6); + // add password + GenRowStruct grs7 = new GenRowStruct(); + grs7.add(new NounMetadata(options.get("password"), PixelDataType.CONST_STRING)); + reactor.getNounStore().addNoun(ReactorKeysEnum.PASSWORD.getKey(), grs7); + // add additional paras + GenRowStruct grs8 = new GenRowStruct(); + grs8.add(new NounMetadata(options.get("additionalParams"), PixelDataType.CONST_STRING)); + reactor.getNounStore().addNoun(ReactorKeysEnum.ADDITIONAL_CONNECTION_PARAMS_KEY.getKey(), grs8); + // add metamodel + // additional paras + GenRowStruct grs9 = new GenRowStruct(); + grs9.add(new NounMetadata(metamodel, PixelDataType.MAP)); + reactor.getNounStore().addNoun(ReactorKeysEnum.METAMODEL.getKey(), grs9); + + NounMetadata retNoun = reactor.execute(); + + String appID = retNoun.getValue().toString(); + String appName =Utility.makeAlphaNumeric(databaseOptions.get("databaseName")); if(this.securityEnabled) { User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); if(user == null) { @@ -1438,15 +1508,6 @@ public Response connectExistingRDBMS(@Context HttpServletRequest request, Multiv addEngineOwner(appID, appName, user.getAccessToken(ap).getId()); } } - - boolean success = true; - try { - importer.runProcessor(importOptions); - } catch (Exception e) { - success = false; - e.printStackTrace(); - } - ret.put("success", success); if(success) { return Response.status(200).entity(gson.toJson(ret)).build(); From 0514248c55d378f03d094d7ef24a4a608c1c1b1f Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 27 Jun 2018 19:39:52 +0000 Subject: [PATCH 0127/1906] UPDATE ::: Adding new payload structure for search git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28961 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 08bd2ca42a633c13d249988129f4d9fef71091b5 --- .../semoss/web/services/NameServer.java | 248 +++++++----------- 1 file changed, 96 insertions(+), 152 deletions(-) diff --git a/src/prerna/semoss/web/services/NameServer.java b/src/prerna/semoss/web/services/NameServer.java index 4dbe8c368..851055c96 100644 --- a/src/prerna/semoss/web/services/NameServer.java +++ b/src/prerna/semoss/web/services/NameServer.java @@ -388,6 +388,11 @@ public StreamingOutput getAutoCompleteResults(@QueryParam("completeTerm") String return WebUtility.getSO(searchResults); } + /** + * Search based on a string input + * @param form - information passes in from the front end + * @return a string version of the results attained from the query search + */ /** * Search based on a string input * @param form - information passes in from the front end @@ -397,141 +402,41 @@ public StreamingOutput getAutoCompleteResults(@QueryParam("completeTerm") String @Path("central/context/getSearchInsightsResults") @Produces("application/json") public StreamingOutput getSearchInsightsResults(MultivaluedMap form, @Context HttpServletRequest request) { -// //text searched in search bar -// String searchString = form.getFirst("searchString"); -// logger.info("Searching based on input: " + searchString); -// -// //sort field -// String sortField = form.getFirst("sortField"); -// logger.info("Sorting field: " + sortField); -// -// //sort (based on relevance, asc, desc) -// String sortOrdering = form.getFirst("sortOrdering"); -// logger.info("Sorting order: " + sortOrdering); -// -// //offset for call -// String offset = form.getFirst("offset"); -// logger.info("Offset is: " + offset); -// -// //offset for call -// String limit = form.getFirst("limit"); -// logger.info("Limit is: " + limit); -// -// Integer offsetInt = null; -// Integer limitInt = null; -// if(offset != null && !offset.isEmpty()) { -// offsetInt = Integer.parseInt(offset); -// } -// if(limit != null && !limit.isEmpty()) { -// limitInt = Integer.parseInt(limit); -// } -// -// //filter based on the boxes checked in the facet filter (filtered with an exact filter) -// String filterDataStr = form.getFirst("filterData"); -// Gson gson = new Gson(); -// Map> filterData = gson.fromJson(filterDataStr, new TypeToken>>() {}.getType()); -// Map results = null; -// -// //If security is enabled, remove the engines in the filters that aren't accessible - if none in filters, add all accessible engines to filter list -// boolean securityEnabled = Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED)); -// ArrayList filterEngines = new ArrayList(); -// String userId = ""; -// -// if(securityEnabled) { -// HttpSession session = request.getSession(false); -// User user = ((User) session.getAttribute(Constants.SESSION_USER)); -// if(user!= null) { -// userId = user.getAccessToken(AuthProvider.NATIVE).getId(); -// } -// -// HashSet userEngines = permissions.getUserAccessibleEngines(userId); -// if(filterData.get(SolrIndexEngine.APP_ID) != null) { -// filterEngines.addAll(filterData.get("core_engine")); -// } -// if(filterEngines.size() > 0) { -// for(String s : filterEngines) { -// if(!userEngines.contains(s)) { -// filterData.get(SolrIndexEngine.APP_ID).remove(s); -// } -// } -// } else { -// filterEngines.addAll(userEngines); -// if(filterEngines.size() > 0) { -// filterData.put(SolrIndexEngine.APP_ID, filterEngines); -// } -// } -// } -// -// try { -// results = SolrIndexEngine.getInstance().executeSearchQuery(searchString, sortField, sortOrdering, offsetInt, limitInt, filterData); -// //serialize images from path -// SolrDocumentList list = (SolrDocumentList) results.get("queryResponse"); -// String basePath = DIHelper.getInstance().getProperty("BaseFolder"); -// int imageCount = 0; -// if (list != null) { -// for (int i = 0; i < list.size(); i++) { -// SolrDocument doc = list.get(i); -// String imagePath = (String) doc.get("image"); -// if (imagePath != null && imagePath.length() > 0 && !imagePath.contains("data:image/:base64")) { -// imageCount++; -// long startTime = System.currentTimeMillis(); -// File file = new File(basePath + imagePath); -// if (file.exists()) { -// String image = InsightScreenshot.imageToString(basePath + imagePath); -// long endTime = System.currentTimeMillis(); -// long duration = endTime - startTime; -// //logger.info("Time to serialize an image " + duration); -// doc.put("image", "data:image/png;base64," + image); -// } -// } -// } -// } -// // logger.info("total images " + imageCount ); -// } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException | SolrServerException -// | IOException e1) { -// e1.printStackTrace(); -// return WebUtility.getSO("Error executing solr query"); -// } -// -// if(securityEnabled) { -// if(filterEngines.size() == 0) { -// results = new HashMap(); -// } -// -// //Get the results based on just insight-level permissions -// Map results2 = new HashMap(); -// ArrayList insightIDs = new ArrayList(); -// StringMap> userInsights = permissions.getInsightPermissionsForUser(userId); -// for(String engineName : userInsights.keySet()) { -// if(!filterEngines.contains(engineName)) { -// insightIDs.addAll(userInsights.get(engineName)); -// } -// } -// -// if(!insightIDs.isEmpty()) { -// filterData.clear(); -// filterData.put("id", insightIDs); -// -// try { -// results2 = SolrIndexEngine.getInstance().executeSearchQuery(searchString, sortField, sortOrdering, offsetInt, limitInt, filterData); -// } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException | SolrServerException | IOException e1) { -// e1.printStackTrace(); -// return WebUtility.getSO("Error executing solr query"); -// } -// -// SolrDocumentList resultsFromDBSearch = (SolrDocumentList) results.get("queryResponse"); -// for(SolrDocument doc : ((SolrDocumentList)results2.get("queryResponse"))) { -// if(resultsFromDBSearch.contains(doc)) { -// continue; -// } -// resultsFromDBSearch.add(doc); -// } -// System.out.println(results2); -// results.put("queryResponse", resultsFromDBSearch); -// } -// } -// return WebUtility.getSO(results); - return null; + // text searched in search bar + String searchString = form.getFirst("searchString"); + logger.info("Searching based on input: " + searchString); + + // offset for call + String offset = form.getFirst("offset"); + logger.info("Offset is: " + offset); + + // offset for call + String limit = form.getFirst("limit"); + logger.info("Limit is: " + limit); + + // If security is enabled, remove the engines in the filters that aren't + // accessible - if none in filters, add all accessible engines to filter + // list + boolean securityEnabled = Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED)); + String userId = ""; + List> queryResults = null; + if (securityEnabled) { + // filter insights based on what the user has access to + HttpSession session = request.getSession(false); + User user = ((User) session.getAttribute(Constants.SESSION_USER)); + if(user == null) { + WebUtility.getSO(new HashMap()); + } + userId = user.getAccessToken(user.getLogins().get(0)).getId(); + List userEngines = SecurityQueryUtils.getUserEngines(userId); + // search for insights by that name with engine filter based on what + // the user has access to + queryResults = SecurityQueryUtils.getInsightDataByName(searchString, limit, offset, userEngines.toArray(new String[]{})); + } else { + queryResults = SecurityQueryUtils.getInsightDataByName(searchString, limit, offset, MasterDatabaseUtility.getAllEngineIds().toArray(new String[]{})); + } + + return WebUtility.getSO(queryResults); } /** @@ -543,23 +448,62 @@ public StreamingOutput getSearchInsightsResults(MultivaluedMap f @GET @Path("central/context/getFacetInsightsResults") @Produces("application/json") - public StreamingOutput getFacetInsightsResults(@QueryParam("searchTerm") String searchString, @Context HttpServletRequest request) { -// logger.info("Searching based on input: " + searchString); -// -// List facetList = new ArrayList<>(); -// facetList.add(SolrIndexEngine.APP_ID); -// facetList.add(SolrIndexEngine.APP_NAME); -// facetList.add(SolrIndexEngine.LAYOUT); -// facetList.add(SolrIndexEngine.TAGS); -// -// Map> facetFieldMap = null; -// try { -// facetFieldMap = SolrIndexEngine.getInstance().executeQueryFacetResults(searchString, facetList, SOLR_PATHS.SOLR_INSIGHTS_PATH); -// } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException | SolrServerException e) { -// e.printStackTrace(); -// } -// return WebUtility.getSO(facetFieldMap); - return null; + public StreamingOutput getFacetInsightsResults(@QueryParam("searchTerm") String searchString, + @Context HttpServletRequest request) { + logger.info("Searching based on input: " + searchString); + + String userId = ""; + boolean securityEnabled = Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED)); + List> facetResults = null; + if (securityEnabled) { + // filter insights based on what the user has access to + HttpSession session = request.getSession(false); + User user = ((User) session.getAttribute(Constants.SESSION_USER)); + if(user == null) { + WebUtility.getSO(new HashMap()); + } + userId = user.getAccessToken(user.getLogins().get(0)).getId(); + List userEngines = SecurityQueryUtils.getUserEngines(userId); + facetResults = SecurityQueryUtils.getInsightFacetDataByName(searchString, userEngines.toArray(new String[userEngines.size()])); + } else { + facetResults = SecurityQueryUtils.getInsightFacetDataByName(searchString, MasterDatabaseUtility.getAllEngineIds().toArray(new String[]{})); + } + + // prepare output in specific format for FE + Map results = new HashMap(); + if (facetResults != null && !facetResults.isEmpty()) { + Map dbCount = new HashMap(); + Map layMap = new HashMap(); + for (Map data : facetResults) { + String engineName = data.get("ENGINEID") + ""; + Integer layCount = new Integer(0); + if (!(data.get("COUNT(ENGINEID)") + "").trim().isEmpty()) { + layCount = new Integer((int) Float.parseFloat(data.get("COUNT(ENGINEID)").toString())); + } + String layout = data.get("LAYOUT") + ""; + + // update layout map - either add or update count + if (layMap.get(layout) == null) { + layMap.put(layout, layCount); + } else { + layMap.put(layout, layMap.get(layout) + layCount); + } + + // same update for dbMap + if (dbCount.get(engineName) == null) { + dbCount.put(engineName, layCount); + } else { + dbCount.put(engineName, dbCount.get(engineName) + layCount); + } + + } + results.put("core_engine", dbCount); + results.put("layout", layMap); + // TODO: add logic for getting tags + results.put("tags", new HashMap()); + } + + return WebUtility.getSO(results); } //////////////////////////////////////////////////////////////////////////////////// From 7fd7773932132f907022246d8071e3dac7f9556d Mon Sep 17 00:00:00 2001 From: tbanach Date: Thu, 28 Jun 2018 13:57:23 +0000 Subject: [PATCH 0128/1906] REQUIREMENT ::: Maven update Semoss and Monolith BUGFIX ::: RDF Runtime deps for upload git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28983 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 6b7205f743ba4bede6fec7f32af7c83aee36d08a --- pom.xml | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/pom.xml b/pom.xml index b1440cfd4..08b7a30a7 100644 --- a/pom.xml +++ b/pom.xml @@ -942,7 +942,7 @@ - + com.itextpdf itextpdf @@ -1092,7 +1092,7 @@ - + org.apache.jena jena-larq @@ -1115,7 +1115,7 @@ - + + + org.apache.lucene + lucene-analyzers-common + 7.4.0 + + + * + * + + + org.mapdb mapdb @@ -2747,5 +2759,17 @@ jodd-core 3.6.2 + + + org.semarglproject + semargl-rdf + 0.6.1 + + + + org.semarglproject + semargl-sesame + 0.6 + \ No newline at end of file From 8d542f0cd65f679684a3097c965ee0165935123a Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 28 Jun 2018 14:44:52 +0000 Subject: [PATCH 0129/1906] UPDATE ::: Removing all solr dependencies from code + pom git-svn-id: svn://107.170.10.188:8080/Monolith/dev@28986 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 436bd2b98e41f298d2c5e7048a0de5b4067bfec3 --- pom.xml | 18 +- .../web/services/CentralNameServer.java | 52 +++-- .../semoss/web/services/NameServer.java | 178 +++++++++--------- 3 files changed, 120 insertions(+), 128 deletions(-) diff --git a/pom.xml b/pom.xml index 08b7a30a7..6acb51c3b 100644 --- a/pom.xml +++ b/pom.xml @@ -1714,17 +1714,18 @@ - + + - + + - + + - + + - + - + - + org.json json @@ -2701,11 +2701,6 @@ json-path 2.3.0 - - net.minidev - json-smart - 1.0.9 - io.burt jmespath-jackson From 14f10b3f31969bcffe795003d834c7f3b6163c61 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 28 Jun 2018 22:00:13 +0000 Subject: [PATCH 0134/1906] UPDATE ::: Fixing error with having test filter on and using social data git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29017 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 4670510df924f8d8ea6d442c1afe85f6947706d7 --- src/prerna/web/conf/TestFilter.java | 36 +++++++++++++++-------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/src/prerna/web/conf/TestFilter.java b/src/prerna/web/conf/TestFilter.java index 782a6d11f..dd04ce1aa 100644 --- a/src/prerna/web/conf/TestFilter.java +++ b/src/prerna/web/conf/TestFilter.java @@ -28,25 +28,27 @@ public class TestFilter implements Filter { public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { HttpSession session = ((HttpServletRequest)arg0).getSession(true); - User user = new User(); - AccessToken token = new AccessToken(); - token.setProvider(AuthProvider.CAC); - token.setEmail("admin@health.mil"); - token.setName("CAC_ADMIN_USER"); - token.setId("12345"); - -// User user = new User(); -// AccessToken token = new AccessToken(); -// token.setProvider(AuthProvider.CAC); -// token.setEmail("readonly@health.mil"); -// token.setName("CAC_READ_ONLY"); -// token.setId("54321"); - - user.setAccessToken(token); - session.setAttribute(Constants.SESSION_USER, user); + User semossUser = new User(); + Object user = session.getAttribute(Constants.SESSION_USER); + if(user != null) { + semossUser = (User) user; + AccessToken token = new AccessToken(); + token.setProvider(AuthProvider.CAC); + token.setEmail("admin@health.mil"); + token.setName("CAC_ADMIN_USER"); + token.setId("12345"); + +// AccessToken token = new AccessToken(); +// token.setProvider(AuthProvider.CAC); +// token.setEmail("readonly@health.mil"); +// token.setName("CAC_READ_ONLY"); +// token.setId("54321"); + + semossUser.setAccessToken(token); + session.setAttribute(Constants.SESSION_USER, semossUser); + } arg2.doFilter(arg0, arg1); - } @Override From a38da81ca4865ddfa344f92ef3399030b5680f70 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 29 Jun 2018 18:25:32 +0000 Subject: [PATCH 0135/1906] UPDATE ::: Returning default app image git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29037 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 688045ce06a17471b79f2812bdaef20ebad4c0b7 --- src/prerna/semoss/web/services/AppResource.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/prerna/semoss/web/services/AppResource.java b/src/prerna/semoss/web/services/AppResource.java index 85a3726f3..9eceffab9 100644 --- a/src/prerna/semoss/web/services/AppResource.java +++ b/src/prerna/semoss/web/services/AppResource.java @@ -63,7 +63,9 @@ private File getAppImageFile(String app) { String appId = MasterDatabaseUtility.testEngineIdIfAlias(app); String propFileLoc = DIHelper.getInstance().getProperty(appId + "_" + Constants.STORE); if(propFileLoc == null && !app.equals("NEWSEMOSSAPP")) { - return null; + String imageDir = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER) + "/images/stock/"; + return new File(imageDir + "color-logo.png"); +// return null; } Properties prop = Utility.loadProperties(propFileLoc); app = prop.getProperty(Constants.ENGINE_ALIAS); From e1ba62c1b6ff74115bd4815b8de41ccb4b461d12 Mon Sep 17 00:00:00 2001 From: tbanach Date: Fri, 29 Jun 2018 19:34:57 +0000 Subject: [PATCH 0136/1906] UPDATE ::: Invoking SEMOSS builder before monolith is built, to make sure the code is always in sync git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29044 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: a7bcd34e3cb95d91887705fdfa126b9c2f185889 --- .gitlab-ci.yml | 43 ++++++++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e3f851411..59fb6dfcd 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,26 +1,42 @@ image: maven:3.5-jdk-8 stages: - - build - -before_script: - - apt-get update - - apt-get install -y openjfx - - apt-get install -y gnupg2 - - gpg2 --batch --import <(echo "$GPG_PRIVATE_KEY") + - setup + - build_semoss + - build_monolith variables: MAVEN_OPTS: "-Dmaven.repo.local=.m2/repository -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=WARN -Dorg.slf4j.simpleLogger.showDateTime=true -Djava.awt.headless=true" MAVEN_CLI_OPTS: "-s ./settings.xml --batch-mode" - + # Used for triggering SEMOSS pipeline + IMAGE: "registry.gitlab.com/finestructure/pipeline-trigger" + URL: "repo.semoss.org" + cache: paths: - .m2/repository/ key: ${CI_BUILD_REF_NAME} +setup: + stage: setup + script: + - apt-get update + - apt-get install -y openjfx + - apt-get install -y gnupg2 + - gpg2 --batch --import <(echo "$GPG_PRIVATE_KEY") + +build_semoss: + stage: build_semoss + image: $IMAGE + script: + - date +%s + # Set via secret variables in SEMOSS group + - trigger -h $URL -a $API_TOKEN -p $SEMOSS_PIPELINE_TOKEN -t $SEMOSS_TARGET_BRANCH $SEMOSS_PROJECT_ID + - date +%s + # Does not push to maven central -build_dev: - stage: build +build_monolith_dev: + stage: build_monolith # See https://docs.gitlab.com/ee/ci/yaml/#only-and-except-simplified only: - pushes @@ -32,10 +48,11 @@ build_dev: - target/monolith-0.0.1-SNAPSHOT.war # Pushes to maven central -build_deploy: - stage: build +build_monolith_deploy: + stage: build_monolith only: - - web + - triggers + - web script: - rm -rf .m2/repository/org/semoss - mvn $MAVEN_CLI_OPTS deploy -P deploy From 891a57553804dd60bcbf78369b35b3147030084c Mon Sep 17 00:00:00 2001 From: tbanach Date: Fri, 29 Jun 2018 19:48:28 +0000 Subject: [PATCH 0137/1906] BUGFIX ::: Breaking out setup into each phase, because it would be too difficult to cache deps for semoss and monolith git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29046 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 58c4c39f21c0554c2ab73162506a02fc1317680a --- .gitlab-ci.yml | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 59fb6dfcd..d1e36c60f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,7 +1,6 @@ image: maven:3.5-jdk-8 stages: - - setup - build_semoss - build_monolith @@ -16,14 +15,6 @@ cache: paths: - .m2/repository/ key: ${CI_BUILD_REF_NAME} - -setup: - stage: setup - script: - - apt-get update - - apt-get install -y openjfx - - apt-get install -y gnupg2 - - gpg2 --batch --import <(echo "$GPG_PRIVATE_KEY") build_semoss: stage: build_semoss @@ -41,6 +32,8 @@ build_monolith_dev: only: - pushes script: + - apt-get update + - apt-get install -y openjfx - rm -rf .m2/repository/org/semoss - mvn $MAVEN_CLI_OPTS clean install artifacts: @@ -54,6 +47,10 @@ build_monolith_deploy: - triggers - web script: + - apt-get update + - apt-get install -y openjfx + - apt-get install -y gnupg2 + - gpg2 --batch --import <(echo "$GPG_PRIVATE_KEY") - rm -rf .m2/repository/org/semoss - mvn $MAVEN_CLI_OPTS deploy -P deploy artifacts: From b62f2e0113c0d15e165df8109df4a20d0f0c5cf9 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 29 Jun 2018 21:02:26 +0000 Subject: [PATCH 0138/1906] UPDATE ::: Fixing test filter for testing... git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29048 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 06b5415cf4de784737fff148c68e1df7fb0bccee --- src/prerna/web/conf/TestFilter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prerna/web/conf/TestFilter.java b/src/prerna/web/conf/TestFilter.java index dd04ce1aa..554156e17 100644 --- a/src/prerna/web/conf/TestFilter.java +++ b/src/prerna/web/conf/TestFilter.java @@ -30,7 +30,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 User semossUser = new User(); Object user = session.getAttribute(Constants.SESSION_USER); - if(user != null) { + if(user == null) { semossUser = (User) user; AccessToken token = new AccessToken(); token.setProvider(AuthProvider.CAC); From 307398bfade476e4a8c00d1d1c37b82327a59f39 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 29 Jun 2018 21:03:30 +0000 Subject: [PATCH 0139/1906] UPDATE ::: Fixing test filter for testing... git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29049 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 552746bc2de87cb9524475ab5360bfd7c617b552 --- src/prerna/web/conf/TestFilter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prerna/web/conf/TestFilter.java b/src/prerna/web/conf/TestFilter.java index 554156e17..2e90ac3b0 100644 --- a/src/prerna/web/conf/TestFilter.java +++ b/src/prerna/web/conf/TestFilter.java @@ -31,7 +31,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 User semossUser = new User(); Object user = session.getAttribute(Constants.SESSION_USER); if(user == null) { - semossUser = (User) user; + semossUser = new User(); AccessToken token = new AccessToken(); token.setProvider(AuthProvider.CAC); token.setEmail("admin@health.mil"); From b2489303a0f1b8bb896e30026f8a5265f494d548 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 2 Jul 2018 02:10:39 +0000 Subject: [PATCH 0140/1906] UPDATE ::: Adding restriction on app to only allow access to users who are registered git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29057 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 338c3e95724ccdea9e306aef6dc26e22b087d388 --- WebContent/WEB-INF/web.xml | 18 +++++- .../web/conf/UserRestrictionFilter.java | 64 +++++++++++++++++++ 2 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 src/prerna/web/conf/UserRestrictionFilter.java diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index 75f80c101..fb5e1d866 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -5,6 +5,22 @@ index.html + + + + Resteasy org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher @@ -119,7 +117,7 @@ security-enabled - true + false Location to store uploaded file From 61b309410112e41ce5d114d6ec9db5a26e5d147b Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 10 Jul 2018 19:52:21 +0000 Subject: [PATCH 0156/1906] UPDATE ::: Shifting the BE to assume/use range for excel loading via drag n drop. REQUIREMENT ::: If you are using excel loading, need to wait to update since this requires synchronization with a FE that will happen soon git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29162 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 7b1907a6c7b6b108e1813b530d7f02b44b182608 --- src/prerna/upload/DatabaseUploader.java | 81 +++++++++++++++++++------ src/prerna/upload/FileUploader.java | 80 +++++++++++++++++++----- 2 files changed, 127 insertions(+), 34 deletions(-) diff --git a/src/prerna/upload/DatabaseUploader.java b/src/prerna/upload/DatabaseUploader.java index 855c252ef..c393a1ff0 100644 --- a/src/prerna/upload/DatabaseUploader.java +++ b/src/prerna/upload/DatabaseUploader.java @@ -47,7 +47,10 @@ import prerna.poi.main.helper.CSVFileHelper; import prerna.poi.main.helper.FileHelperUtil; import prerna.poi.main.helper.ImportOptions; -import prerna.poi.main.helper.XLFileHelper; +import prerna.poi.main.helper.excel.ExcelBlock; +import prerna.poi.main.helper.excel.ExcelWorkbookFilePreProcessor; +import prerna.poi.main.helper.excel.ExcelRange; +import prerna.poi.main.helper.excel.ExcelSheetPreProcessor; import prerna.rdf.main.ImportRDBMSProcessor; import prerna.sablecc2.om.GenRowStruct; import prerna.sablecc2.om.PixelDataType; @@ -799,28 +802,66 @@ public Response uploadExcelFile(@Context HttpServletRequest request) { } fileMetaModelData.put("fileName", file); - XLFileHelper helper = new XLFileHelper(); - helper.parse(files[i]); + // processing excel file data + // trying to determine data blocks within a sheet - // store the suggested data types - String[] sheetNames = helper.getTables(); - Map> dataTypes = new Hashtable>(); - Map> additionalDataTypes = new Hashtable>(); - - for(String sheetName : sheetNames) { - Map[] predictionMaps = FileHelperUtil.generateDataTypeMapsFromPrediction(helper.getHeaders(sheetName), helper.predictTypes(sheetName)); - Map sheetDataMap = predictionMaps[0]; - Map additionalTypesMap = predictionMaps[1]; + ExcelWorkbookFilePreProcessor preProcessor = new ExcelWorkbookFilePreProcessor(); + preProcessor.parse(files[i]); + preProcessor.determineTableRanges(); + Map sProcessors = preProcessor.getSheetProcessors(); + for(String sheet : sProcessors.keySet()) { + ExcelSheetPreProcessor processor = sProcessors.get(sheet); + List blocks = processor.getAllBlocks(); - dataTypes.put(sheetName, sheetDataMap); - additionalDataTypes.put(sheetName, additionalTypesMap); + Map rangeInfo = new HashMap(); + + for(ExcelBlock block : blocks) { + List ranges = block.getRanges(); + for(ExcelRange r : ranges) { + String rSyntax = r.getRangeSyntax(); + String[] origHeaders = processor.getRangeHeaders(r); + String[] cleanedHeaders = processor.getCleanedRangeHeaders(r); + + Object[][] rangeTypes = block.getRangeTypes(r); + Map[] retMaps = FileHelperUtil.generateDataTypeMapsFromPrediction(cleanedHeaders, rangeTypes); + + Map rangeMap = new HashMap(); + rangeMap.put("headers", origHeaders); + rangeMap.put("cleanHeaders", cleanedHeaders); + rangeMap.put("dataTypes", retMaps[0]); + rangeMap.put("additionalDataTypes", retMaps[1]); + + rangeInfo.put(rSyntax, rangeMap); + } + } + + // add all ranges in the sheet + fileMetaModelData.put(sheet, rangeInfo); } - fileMetaModelData.put("dataTypes", dataTypes); - fileMetaModelData.put("additionalDataTypes", additionalDataTypes); - - // store auto modified header names - Map> fileHeaderMods = helper.getChangedHeaders(); - fileMetaModelData.put("headerModifications", fileHeaderMods); + preProcessor.clear(); + +// XLFileHelper helper = new XLFileHelper(); +// helper.parse(files[i]); +// +// // store the suggested data types +// String[] sheetNames = helper.getTables(); +// Map> dataTypes = new Hashtable>(); +// Map> additionalDataTypes = new Hashtable>(); +// +// for(String sheetName : sheetNames) { +// Map[] predictionMaps = FileHelperUtil.generateDataTypeMapsFromPrediction(helper.getHeaders(sheetName), helper.predictTypes(sheetName)); +// Map sheetDataMap = predictionMaps[0]; +// Map additionalTypesMap = predictionMaps[1]; +// +// dataTypes.put(sheetName, sheetDataMap); +// additionalDataTypes.put(sheetName, additionalTypesMap); +// } +// fileMetaModelData.put("dataTypes", dataTypes); +// fileMetaModelData.put("additionalDataTypes", additionalDataTypes); +// +// // store auto modified header names +// Map> fileHeaderMods = helper.getChangedHeaders(); +// fileMetaModelData.put("headerModifications", fileHeaderMods); // add the info to the metamodel data to send metaModelData.add(fileMetaModelData); diff --git a/src/prerna/upload/FileUploader.java b/src/prerna/upload/FileUploader.java index 529308cb5..9906f38e3 100644 --- a/src/prerna/upload/FileUploader.java +++ b/src/prerna/upload/FileUploader.java @@ -24,6 +24,10 @@ import prerna.poi.main.helper.CSVFileHelper; import prerna.poi.main.helper.FileHelperUtil; import prerna.poi.main.helper.XLFileHelper; +import prerna.poi.main.helper.excel.ExcelBlock; +import prerna.poi.main.helper.excel.ExcelWorkbookFilePreProcessor; +import prerna.poi.main.helper.excel.ExcelRange; +import prerna.poi.main.helper.excel.ExcelSheetPreProcessor; import prerna.web.services.util.WebUtility; public class FileUploader extends Uploader { @@ -67,22 +71,70 @@ protected static Map generateDataTypes(Map input String uniqueStorageId = FileStore.getInstance().put(fileLoc); retObj.put("uniqueFileKey", uniqueStorageId); if(fileLoc.endsWith(".xlsx") || fileLoc.endsWith(".xlsm")) { - XLFileHelper helper = new XLFileHelper(); - helper.parse(fileLoc); - - String[] sheets = helper.getTables(); - for(int i = 0; i < sheets.length; i++) { - String sheetName = sheets[i]; - String[] headers = helper.getHeaders(sheetName); - Map[] retMaps = FileHelperUtil.generateDataTypeMapsFromPrediction(headers, helper.predictTypes(sheetName)); - - Map innerObj = new HashMap(); - innerObj.put("dataTypes", retMaps[0]); - innerObj.put("additionalDataTypes", retMaps[1]); - retObj.put(sheetName, innerObj); + + // new approach + { + Map> newPayload = new HashMap>(); + + ExcelWorkbookFilePreProcessor preProcessor = new ExcelWorkbookFilePreProcessor(); + preProcessor.parse(fileLoc); + Map sProcessors = preProcessor.getSheetProcessors(); + for(String sheet : sProcessors.keySet()) { + ExcelSheetPreProcessor processor = sProcessors.get(sheet); + List blocks = processor.getAllBlocks(); + + Map rangeInfo = new HashMap(); + + for(ExcelBlock block : blocks) { + List ranges = block.getRanges(); + for(ExcelRange r : ranges) { + String rSyntax = r.getRangeSyntax(); + String[] origHeaders = processor.getRangeHeaders(r); + String[] cleanedHeaders = processor.getCleanedRangeHeaders(r); + + Object[][] rangeTypes = block.getRangeTypes(r); + Map[] retMaps = FileHelperUtil.generateDataTypeMapsFromPrediction(cleanedHeaders, rangeTypes); + Map typeMap = new HashMap(); + typeMap.put("dataTypes", retMaps[0]); + typeMap.put("additionalDataTypes", retMaps[1]); + + Map rangeMap = new HashMap(); + rangeMap.put("headers", origHeaders); + rangeMap.put("cleanHeaders", cleanedHeaders); + rangeMap.put("types", typeMap); + + rangeInfo.put(rSyntax, rangeMap); + } + } + + // add all ranges in the sheet + newPayload.put(sheet, rangeInfo); + } + + // put in return object + retObj.put("newPayload", newPayload); + preProcessor.clear(); } - helper.clear(); + // old + { + XLFileHelper helper = new XLFileHelper(); + helper.parse(fileLoc); + + String[] sheets = helper.getTables(); + for(int i = 0; i < sheets.length; i++) { + String sheetName = sheets[i]; + String[] headers = helper.getHeaders(sheetName); + Map[] retMaps = FileHelperUtil.generateDataTypeMapsFromPrediction(headers, helper.predictTypes(sheetName)); + + Map innerObj = new HashMap(); + innerObj.put("dataTypes", retMaps[0]); + innerObj.put("additionalDataTypes", retMaps[1]); + retObj.put(sheetName, innerObj); + } + + helper.clear(); + } } else { String delimiter = inputData.get("delimiter"); // generate tinker frame from From fb2f624df2f5c2279e883d37f76b2d94cba3e592 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 11 Jul 2018 18:51:48 +0000 Subject: [PATCH 0157/1906] UPDATE ::: Adding back dependency required to start rdbms in main method - used a lot for testing UPDATE ::: Modifying order of RDF_MAP for easier understanding of what to modify/edit when new users are deploying git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29192 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 9ad49546e82cc37b8f2dead7111657307c831398 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index aacb05eaf..b643f998d 100644 --- a/pom.xml +++ b/pom.xml @@ -2575,7 +2575,7 @@ - + @@ -2768,5 +2774,17 @@ semargl-sesame 0.6 + + + com.sun.jersey + jersey-core + 1.19 + + + + org.codehaus.plexus + plexus-utils + 3.1.0 + \ No newline at end of file From a2630182807e4b9cf51ebde9a0c4e2c0ae8f3705 Mon Sep 17 00:00:00 2001 From: tbanach Date: Thu, 12 Jul 2018 14:01:13 +0000 Subject: [PATCH 0160/1906] BUGFIX ::: Roxy's jsoup update git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29211 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: abdb8a038d4aae52f7eecce84d12bde3eca07d90 --- pom.xml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/pom.xml b/pom.xml index 6ce757f2a..a0f61daf5 100644 --- a/pom.xml +++ b/pom.xml @@ -1257,7 +1257,7 @@ org.jsoup jsoup - 1.7.3 + 1.8.3 * @@ -2744,12 +2744,12 @@ oauth2-oidc-sdk 4.5 - - - org.jsoup - jsoup - 1.11.3 - + + au.com.bytecode From 9d180902bc0be84c2f81a178dcce56a99c23cdf8 Mon Sep 17 00:00:00 2001 From: tbanach Date: Thu, 12 Jul 2018 18:58:54 +0000 Subject: [PATCH 0161/1906] BUGFIX ::: Impala runtime git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29234 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: c4230eec800c8f87bbaebdc2223aa2817975a039 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index a0f61daf5..641eff18c 100644 --- a/pom.xml +++ b/pom.xml @@ -2605,7 +2605,7 @@ - + From 9ec439cf2d2f89c157883d366c9f29d6c1ba8211 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 24 Jul 2018 19:30:39 +0000 Subject: [PATCH 0166/1906] UPDATE ::: Adding logic to write the last task on each panel to a json during caching git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29340 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: fd130d4975c8e336f09158659834fca0e90e36bf --- .../semoss/web/services/NameServer.java | 4 +- .../web/services/util/PixelWebUtility.java | 445 ------------------ src/prerna/web/services/util/WebUtility.java | 2 +- 3 files changed, 3 insertions(+), 448 deletions(-) delete mode 100644 src/prerna/web/services/util/PixelWebUtility.java diff --git a/src/prerna/semoss/web/services/NameServer.java b/src/prerna/semoss/web/services/NameServer.java index a57fc327c..a35f8f72e 100644 --- a/src/prerna/semoss/web/services/NameServer.java +++ b/src/prerna/semoss/web/services/NameServer.java @@ -87,6 +87,7 @@ import prerna.om.InsightStore; import prerna.sablecc.PKQLRunner; import prerna.sablecc2.PixelRunner; +import prerna.sablecc2.PixelStreamUtility; import prerna.sablecc2.comm.JobManager; import prerna.sablecc2.comm.JobThread; import prerna.upload.DatabaseUploader; @@ -97,7 +98,6 @@ import prerna.util.DIHelper; import prerna.util.PlaySheetRDFMapBasedEnum; import prerna.util.Utility; -import prerna.web.services.util.PixelWebUtility; import prerna.web.services.util.ResponseHashSingleton; import prerna.web.services.util.SemossExecutorSingleton; import prerna.web.services.util.SemossThread; @@ -963,7 +963,7 @@ public Response runPixelSync(MultivaluedMap form, @Context HttpS PixelRunner pixelRunner = jt.getRunner(); manager.flushJob(jobId); - return Response.status(200).entity(PixelWebUtility.collectPixelData(pixelRunner)).build(); + return Response.status(200).entity(PixelStreamUtility.collectPixelData(pixelRunner)).build(); } } diff --git a/src/prerna/web/services/util/PixelWebUtility.java b/src/prerna/web/services/util/PixelWebUtility.java deleted file mode 100644 index a6d58dd60..000000000 --- a/src/prerna/web/services/util/PixelWebUtility.java +++ /dev/null @@ -1,445 +0,0 @@ -package prerna.web.services.util; - -import java.io.IOException; -import java.io.OutputStream; -import java.io.PrintStream; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.ws.rs.WebApplicationException; -import javax.ws.rs.core.StreamingOutput; - -import org.apache.log4j.Logger; - -import com.google.gson.Gson; - -import prerna.algorithm.api.ITableDataFrame; -import prerna.engine.api.IHeadersDataRow; -import prerna.om.Insight; -import prerna.sablecc2.PixelRunner; -import prerna.sablecc2.PixelUtility; -import prerna.sablecc2.om.PixelDataType; -import prerna.sablecc2.om.PixelOperationType; -import prerna.sablecc2.om.nounmeta.NounMetadata; -import prerna.sablecc2.om.task.AbstractTask; -import prerna.sablecc2.om.task.ConstantDataTask; -import prerna.sablecc2.om.task.ITask; -import prerna.sablecc2.reactor.export.GraphFormatter; -import prerna.sablecc2.reactor.frame.FrameFactory; -import prerna.util.insight.InsightUtility; - -public class PixelWebUtility extends WebUtility{ - - private static final String CLASS_NAME = PixelWebUtility.class.getName(); - private static final Logger LOGGER = Logger.getLogger(CLASS_NAME); - - /** - * Collect pixel data from the runner - * @param runner - * @return - */ - public static StreamingOutput collectPixelData(PixelRunner runner) { - // get the default gson object - Gson gson = getDefaultGson(); - - // now process everything - try { - return new StreamingOutput() { - public void write(OutputStream outputStream) throws IOException, WebApplicationException { - try(PrintStream ps = new PrintStream(outputStream)) { - // we want to ignore the first index since it will be a job - processPixelRunner(ps, gson, runner, true); - ps.close(); - } - }}; - } catch (Exception e) { - LOGGER.error("Failed to write object to stream"); - } - return null; - } - - private static void processPixelRunner(PrintStream ps, Gson gson, PixelRunner runner, boolean ignoreFirst) { - // get the values we need from the runner - Insight in = runner.getInsight(); - List resultList = runner.getResults(); - // get the expression which created the return - // this matches with the above by index - List pixelStrings = runner.getPixelExpressions(); - List isMeta = runner.isMeta(); - Map encodedTextToOriginal = runner.getEncodedTextToOriginal(); - boolean invalidSyntax = runner.isInvalidSyntax(); - - // start of the map - // and the insight id - ps.print("{\"insightID\":\"" + in.getInsightId() + "\","); - ps.flush(); - - // now flush array of pixel returns - ps.print("\"pixelReturn\":["); - int size = pixelStrings.size(); - - // THIS IS BECAUSE WE APPEND THE JOB PIXEL - // BUT FE DOENS'T RESPOND TO IT AND NEED TO REMOVE IT - // HOWEVER, IF THE SIZE IS JUST 1, IT MEANS THAT THERE WAS - // AN ERROR THAT OCCURED - // but when we run a saved insight within a pixel - // we do not want to shift the index - int startIndex = 0; - if(ignoreFirst) { - startIndex = 1; - } - if(size == 1) { - startIndex = 0; - } - for (int i = startIndex; i < size; i++) { - NounMetadata noun = resultList.get(i); - String expression = pixelStrings.get(i); - expression = PixelUtility.recreateOriginalPixelExpression(expression, encodedTextToOriginal); - boolean meta = isMeta.get(i); - processNounMetadata(in, ps, gson, noun, expression, meta); - - // update the pixel list to say this is routine is valid - // TODO: need to set this inside the translation directly!!! - if (!meta && !invalidSyntax) { - // update the insight recipe - in.getPixelRecipe().add(expression); - } - - // add a comma for the next item in the list - if( (i+1) != size) { - ps.print(","); - ps.flush(); - } - } - - // now close of the array and the map - ps.print("]}"); - ps.flush(); - } - - - /** - * Process the noun metadata for consumption on the FE - * @param noun - * @return - */ - private static void processNounMetadata(Insight in, PrintStream ps, Gson gson, NounMetadata noun, String expression, Boolean isMeta) { - ps.print("{"); - - // add expression if there - if(expression != null) { - ps.print("\"pixelExpression\":" + gson.toJson(expression) + ","); - } - // add is meta if there - if(isMeta != null) { - ps.print("\"isMeta\":" + isMeta + ","); - } - - PixelDataType nounT = noun.getNounType(); - if(nounT == PixelDataType.FRAME) { - // if we have a frame - // return the table name of the frame - // FE needs this to create proper QS - // this has no meaning for graphs - Map frameData = new HashMap(); - ITableDataFrame frame = (ITableDataFrame) noun.getValue(); - frameData.put("type", FrameFactory.getFrameType(frame)); - String name = frame.getTableName(); - if(name != null) { - frameData.put("name", name); - } - - ps.print("\"output\":"); - ps.print(gson.toJson(frameData)); - ps.print(",\"operationType\":"); - ps.print(gson.toJson(noun.getOpType())); - - // add additional outputs - List addReturns = noun.getAdditionalReturn(); - int numOutputs = addReturns.size(); - if(numOutputs > 0) { - ps.print(",\"additionalOutput\":["); - for(int i = 0; i < numOutputs; i++) { - processNounMetadata(in, ps, gson, addReturns.get(i), null, null); - } - ps.print("]"); - } - - } else if(nounT == PixelDataType.CODE || nounT == PixelDataType.TASK_LIST) { - // code is a tough one to process - // since many operations could have been performed - // we need to loop through a set of noun meta datas to output - List codeOutputs = (List) noun.getValue(); - int numOutputs = codeOutputs.size(); - if(numOutputs > 0) { - ps.print("\"output\":["); - for(int i = 0; i < numOutputs; i++) { - processNounMetadata(in, ps, gson, codeOutputs.get(i), null, null); - } - ps.print("]"); - } - ps.print(",\"operationType\":"); - ps.print(gson.toJson(noun.getOpType())); - - } else if(nounT == PixelDataType.TASK) { - // if we have a task - // we gotta iterate through it to return the data - ITask task = (ITask) noun.getValue(); - ps.print("\"output\":{"); - ps.print("\"taskId\":\"" + task.getId() + "\""); - ps.print("}"); - ps.print(",\"operationType\":"); - ps.print(gson.toJson(noun.getOpType())); - - } else if(nounT == PixelDataType.FORMATTED_DATA_SET) { - Object value = noun.getValue(); - if(value instanceof ITask) { - // if we have a task - // we gotta iterate through it to return the data - ITask task = (ITask) noun.getValue(); - int numCollect = task.getNumCollect(); - boolean collectAll = numCollect == -1; - String formatType = task.getFormatter().getFormatType(); - Map taskMeta = task.getMeta(); - - if(task instanceof ConstantDataTask) { - ps.print("\"output\":{"); - ps.print("\"data\":" + gson.toJson( ((ConstantDataTask) task).getOutputData())); - ps.flush(); - } else if(formatType.equals("TABLE")) { - // right now, only grid will work - boolean first = true; - String[] headers = null; - String[] rawHeaders = null; - int count = 0; - - // we need to use a try catch - // in case there is an issue - // since we can get to this point - // without trying to execute or anything - try { - // recall, a task is also an iterator! - while(task.hasNext() && (collectAll || count < numCollect)) { - IHeadersDataRow row = task.next(); - // need to set the headers - if(headers == null) { - headers = row.getHeaders(); - rawHeaders = row.getRawHeaders(); - ps.print("\"output\":{"); - ps.print("\"data\":{" ); - ps.print("\"values\":["); - } - - if(!first) { - ps.print(","); - } - ps.print(gson.toJson(row.getValues())); - ps.flush(); - - first = false; - count++; - } - } catch(Exception e) { - // on no, this is not good - e.printStackTrace(); - - // let us send back an error - ps.print("\"output\":"); - ps.print(gson.toJson(e.getMessage())); - ps.print(",\"operationType\":"); - ps.print(gson.toJson(new PixelOperationType[]{PixelOperationType.ERROR})); - // close the map - ps.print("}"); - ps.flush(); - return; - } - - // this happens if there is no data to return - if(first == true) { - ps.print("\"output\":{"); - ps.print("\"data\":{" ); - ps.print("\"values\":["); - // try to at least provide the headers - List> headerInfo = task.getHeaderInfo(); - headers = new String[headerInfo.size()]; - for(int i = 0; i < headers.length; i++) { - headers[i] = headerInfo.get(i).get("alias") + ""; - } - } - // end the values and add the headers - ps.print("],\"headers\":" + gson.toJson(headers)); - ps.print(",\"rawHeaders\":" + gson.toJson(rawHeaders)); - ps.print("}" ); - - } else if(formatType.equals("GRAPH")){ -// // format type is probably graph -// ps.print("\"output\":{"); -// ps.print("\"data\":" ); -// // this is a map return -// ps.print(gson.toJson( ((AbstractTask) task).getData())); - - // format type is graph - ps.print("\"output\":{"); - printMapData(ps, (Map) ((AbstractTask) task).getData(), gson); - } - - for(String taskMetaKey : taskMeta.keySet()) { - ps.print(",\"" + taskMetaKey + "\":" + gson.toJson(taskMeta.get(taskMetaKey))); - ps.flush(); - } - - ps.print(",\"taskId\":\"" + task.getId() + "\""); - ps.print("}"); - ps.print(",\"operationType\":"); - ps.print(gson.toJson(noun.getOpType())); - - } - // if we do not have a task - // we just have data to send - else { - // sometimes there is just data to send - // dont need to do anything special - ps.print("\"output\":"); - Object obj = noun.getValue(); - if(obj instanceof Map && ((Map) obj).containsKey("type") && ((Map) obj).get("type").equals("GRAPH")) { - ps.print("{"); - Map mapObj = (Map) obj; - Map retData = (Map) mapObj.remove("data"); - printMapData(ps, retData, gson); - // print the rest of the stuff - for(Object key : mapObj.keySet()) { - ps.println(",\"" + key + ":" + gson.toJson(mapObj.get(key))); - } - ps.print("}"); - } else { - ps.print(gson.toJson(noun.getValue())); - } - ps.print(",\"operationType\":"); - ps.print(gson.toJson(noun.getOpType())); - } - } - - // running a saved insight - else if(nounT == PixelDataType.PIXEL_RUNNER) { - Map runnerWraper = (Map) noun.getValue(); - PixelRunner runner = (PixelRunner) runnerWraper.get("runner"); - Object params = runnerWraper.get("params"); - List additionalPixels = (List) runnerWraper.get("additionalPixels"); - - Insight innerInsight = runner.getInsight(); - ps.print("\"output\":{"); - ps.print("\"name\":" + gson.toJson(innerInsight.getInsightName())); - ps.print(",\"core_engine\":" + gson.toJson(innerInsight.getEngineId())); - ps.print(",\"core_engine_id\":" + gson.toJson(innerInsight.getRdbmsId())); - ps.print(",\"params\":" + gson.toJson(params)); - ps.print(",\"additionalPixels\":" + gson.toJson(additionalPixels)); - ps.flush(); - ps.print(",\"insightData\":"); - // process the inner recipe - processPixelRunner(ps, gson, runner, false); - ps.print("}"); - ps.print(",\"operationType\":"); - ps.print(gson.toJson(noun.getOpType())); - ps.flush(); - } - - // remove variable - else if(nounT == PixelDataType.REMOVE_VARIABLE) { - // we only remove variables at the end - // because the user may want to get the task and then - // remove the frame right after - // so we need to remove only at the end - NounMetadata newNoun = InsightUtility.removeVaraible(in.getVarStore(), noun.getValue().toString()); - ps.print("\"output\":"); - ps.print(gson.toJson(newNoun.getValue())); - ps.print(",\"operationType\":"); - ps.print(gson.toJson(newNoun.getOpType())); - - } - - // remove insight - else if(nounT == PixelDataType.CLEAR_INSIGHT) { - NounMetadata newNoun = InsightUtility.clearInsight(in); - ps.print("\"output\":"); - ps.print(gson.toJson(newNoun.getValue())); - ps.print(",\"operationType\":"); - ps.print(gson.toJson(newNoun.getOpType())); - - } - - else if(nounT == PixelDataType.REMOVE_TASK) { - // we only remove variables at the end - // because the user may want to get the task and then - // remove the frame right after - // so we need to remove only at the end - ITask task = InsightUtility.removeTask(in, noun.getValue().toString()); - ps.print("\"output\":{"); - if(task == null) { - ps.print("\"taskId\":\"Could not find task id = " + noun.getValue().toString() + "\""); - ps.print("}"); - ps.print(",\"operationType\":"); - ps.print(gson.toJson(new PixelOperationType[]{PixelOperationType.ERROR})); - } else { - ps.print("\"taskId\":\"" + task.getId() + "\""); - ps.print("}"); - ps.print(",\"operationType\":"); - ps.print(gson.toJson(noun.getOpType())); - } - } - - // everything else is simple - else { - ps.print("\"output\":"); - ps.print(gson.toJson(noun.getValue())); - ps.print(",\"operationType\":"); - ps.print(gson.toJson(noun.getOpType())); - - // add additional outputs - List addReturns = noun.getAdditionalReturn(); - int numOutputs = addReturns.size(); - if(numOutputs > 0) { - ps.print(",\"additionalOutput\":["); - for(int i = 0; i < numOutputs; i++) { - processNounMetadata(in, ps, gson, addReturns.get(i), null, null); - } - ps.print("]"); - } - } - - // close the map - ps.print("}"); - ps.flush(); - } - - /** - * Logic to more efficiently print out the map formatted data - * @param ps - * @param retData - * @param gson - */ - private static void printMapData(PrintStream ps, Map retData, Gson gson) { - ps.print("\"data\":" ); - // this is a map return - ps.print("{\"" + GraphFormatter.GRAPH_META + "\":" + gson.toJson(retData.get(GraphFormatter.GRAPH_META))); - ps.print(", \"" + GraphFormatter.NODES + "\":["); - - List nodeList = (List) retData.get(GraphFormatter.NODES); - // print first node - if(!nodeList.isEmpty()) { - ps.print(gson.toJson(nodeList.remove(0))); - } - // print rest of nodes - nodeList.stream().forEach(node -> ps.print("," + gson.toJson(node))); - ps.print("], \"" + GraphFormatter.EDGES + "\":["); - List edgeList = (List) retData.get(GraphFormatter.EDGES); - // print first node - if(!edgeList.isEmpty()) { - ps.print(gson.toJson(edgeList.remove(0))); - } - // print rest of nodes - edgeList.stream().forEach(edge -> ps.print("," + gson.toJson(edge))); - ps.print("]}"); - } - -} diff --git a/src/prerna/web/services/util/WebUtility.java b/src/prerna/web/services/util/WebUtility.java index 95db6941d..d5966f82e 100644 --- a/src/prerna/web/services/util/WebUtility.java +++ b/src/prerna/web/services/util/WebUtility.java @@ -51,7 +51,7 @@ public class WebUtility { private static final String CLASS_NAME = WebUtility.class.getName(); private static final Logger LOGGER = Logger.getLogger(CLASS_NAME); - protected static Gson getDefaultGson() { + private static Gson getDefaultGson() { return GsonUtility.getDefaultGson(); } From 56450fc0eb376333e53fe359eef0999e4ed0d071 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 25 Jul 2018 20:03:32 +0000 Subject: [PATCH 0167/1906] BUGFIX ::: Fixing error with setting correct database id for add to existing git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29366 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: c850fddbdab292ca2d1efb8e35c8261b5b37d81c --- src/prerna/upload/DatabaseUploader.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/prerna/upload/DatabaseUploader.java b/src/prerna/upload/DatabaseUploader.java index 3b9746165..26aa8bee8 100644 --- a/src/prerna/upload/DatabaseUploader.java +++ b/src/prerna/upload/DatabaseUploader.java @@ -131,8 +131,12 @@ private void setDefaultOptions(ImportOptions options, Map inputD String errorMessage = "Database name \'" + dbName + "\' is invalid"; throw new IOException(errorMessage); } - options.setDbName(Utility.makeAlphaNumeric(dbName)); - options.setEngineID(UUID.randomUUID().toString()); + if(importMethod == ImportOptions.IMPORT_METHOD.ADD_TO_EXISTING) { + options.setEngineID(dbName); + } else { + options.setDbName(Utility.makeAlphaNumeric(dbName)); + options.setEngineID(UUID.randomUUID().toString()); + } // determine the db type String dbType = inputData.get("dataOutputType"); From da49d037f3f067fd1936928047fcc89344d735cb Mon Sep 17 00:00:00 2001 From: rramirezjimenez Date: Tue, 7 Aug 2018 20:46:12 +0000 Subject: [PATCH 0168/1906] UPDATE ::: Uploading csv using new reactors to upload tinker, rdf, rdbms. git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29479 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 8f2794b1c11959d41508b212303c604c1e07e48e --- src/prerna/upload/DatabaseUploader.java | 225 +++++++++++++++++++++++- 1 file changed, 224 insertions(+), 1 deletion(-) diff --git a/src/prerna/upload/DatabaseUploader.java b/src/prerna/upload/DatabaseUploader.java index 26aa8bee8..29c21479b 100644 --- a/src/prerna/upload/DatabaseUploader.java +++ b/src/prerna/upload/DatabaseUploader.java @@ -48,6 +48,7 @@ import prerna.poi.main.helper.FileHelperUtil; import prerna.poi.main.helper.ImportOptions; import prerna.poi.main.helper.ImportOptions.DB_TYPE; +import prerna.poi.main.helper.ImportOptions.IMPORT_METHOD; import prerna.poi.main.helper.excel.ExcelBlock; import prerna.poi.main.helper.excel.ExcelRange; import prerna.poi.main.helper.excel.ExcelSheetPreProcessor; @@ -57,8 +58,13 @@ import prerna.sablecc2.om.PixelDataType; import prerna.sablecc2.om.ReactorKeysEnum; import prerna.sablecc2.om.nounmeta.NounMetadata; +import prerna.sablecc2.reactor.IReactor; import prerna.sablecc2.reactor.PixelPlanner; +import prerna.sablecc2.reactor.app.upload.UploadInputUtility; +import prerna.sablecc2.reactor.app.upload.gremlin.TinkerCsvUploadReactor; +import prerna.sablecc2.reactor.app.upload.rdbms.csv.RdbmsCsvUploadReactor; import prerna.sablecc2.reactor.app.upload.rdbms.csv.RdbmsExternalUploadReactor; +import prerna.sablecc2.reactor.app.upload.rdf.RdfCsvUploadReactor; import prerna.ui.components.ImportDataProcessor; import prerna.util.Constants; import prerna.util.DIHelper; @@ -633,7 +639,12 @@ public Response uploadCSVFile(MultivaluedMap form, @Context Http // run the import ImportDataProcessor importer = new ImportDataProcessor(); - importer.runProcessor(options); + String appId = reactorImport(options, request); + if (appId != null) { + options.setEngineID(appId); + } else { + importer.runProcessor(options); + } } catch (IOException e) { e.printStackTrace(); Map errorHash = new HashMap(); @@ -779,6 +790,218 @@ public Response uploadCSVFile(MultivaluedMap form, @Context Http ////////////////////////////////////////////// START EXCEL UPLOADING ////////////////////////////////////////////////////////// + private String reactorImport(ImportOptions options, HttpServletRequest request) { + // get upload inputs + DB_TYPE importDBType = options.getDbType(); + IMPORT_METHOD importType = options.getImportMethod(); + + String fileLocations = options.getFileLocations(); + String dbName = options.getDbName(); + // return appId + String appId = null; + // create each specific reactor for upload type + IReactor reactor = getImportReactor(options); + + // if the reactor is supported, get the rest of the upload inputs + if (reactor != null) { + // create new metamodels for the reactor + // index based for each file + List> newMetamodelList = createNewMetamodel(options); + // if importing multiple csvs add to existing + String[] csvFiles = fileLocations.split(";"); + // set up insight to run reactor + reactor.In(); + // make an insight to set + // so we can pass the user + + + // if create new + if (importType == IMPORT_METHOD.CREATE_NEW) { + for (int i = 0; i < csvFiles.length; i++) { + + String csvFileLocation = csvFiles[i]; + + Insight dummyIn = new Insight(); + InsightStore.getInstance().put(dummyIn); + + // TODO do we need this? + // InsightStore.getInstance().addToSessionHash(session.getId(), + // dummyIn.getInsightId()); + // dummyIn.getVarStore().put(JobReactor.SESSION_KEY, new + // NounMetadata(session.getId(), + // PixelDataType.CONST_STRING)); + // dummyIn.setUser(user); + if (this.securityEnabled) { + User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); + dummyIn.setUser(user); + } + reactor.setInsight(dummyIn); + PixelPlanner planner = new PixelPlanner(); + planner.setVarStore(dummyIn.getVarStore()); + reactor.setPixelPlanner(planner); + // if adding multiple csvs to an app + GenRowStruct grs = new GenRowStruct(); + if (appId != null) { + grs = new GenRowStruct(); + grs.add(new NounMetadata(appId, PixelDataType.CONST_STRING)); + reactor.getNounStore().addNoun(ReactorKeysEnum.APP.getKey(), grs); + // add to existing + grs = new GenRowStruct(); + grs.add(new NounMetadata(true, PixelDataType.BOOLEAN)); + reactor.getNounStore().addNoun(ReactorKeysEnum.EXISTING.getKey(), grs); + } else { + // add app name + grs = new GenRowStruct(); + grs.add(new NounMetadata(dbName, PixelDataType.CONST_STRING)); + reactor.getNounStore().addNoun(ReactorKeysEnum.APP.getKey(), grs); + } + + // add metamodel + grs = new GenRowStruct(); + grs.add(new NounMetadata(newMetamodelList.get(i), PixelDataType.MAP)); + reactor.getNounStore().addNoun(ReactorKeysEnum.METAMODEL.getKey(), grs); + + // add file path + grs = new GenRowStruct(); + grs.add(new NounMetadata(csvFileLocation, PixelDataType.CONST_STRING)); + reactor.getNounStore().addNoun(ReactorKeysEnum.FILE_PATH.getKey(), grs); + + // execute! + NounMetadata response = reactor.execute(); + if (i == 0) { + // need to keep app id to override + appId = (String) response.getValue(); + } + reactor = getImportReactor(options); + } + } else if(importType == IMPORT_METHOD.ADD_TO_EXISTING) { + for (int i = 0; i < csvFiles.length; i++) { + String csvFileLocation = csvFiles[i]; + + Insight dummyIn = new Insight(); + InsightStore.getInstance().put(dummyIn); + // TODO do we need this? + // InsightStore.getInstance().addToSessionHash(session.getId(), + // dummyIn.getInsightId()); + // dummyIn.getVarStore().put(JobReactor.SESSION_KEY, new + // NounMetadata(session.getId(), + // PixelDataType.CONST_STRING)); + // dummyIn.setUser(user); + if (this.securityEnabled) { + User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); + dummyIn.setUser(user); + } + reactor.setInsight(dummyIn); + PixelPlanner planner = new PixelPlanner(); + planner.setVarStore(dummyIn.getVarStore()); + reactor.setPixelPlanner(planner); + // if adding multiple csvs to an app + GenRowStruct grs = new GenRowStruct(); + if (appId != null) { + grs = new GenRowStruct(); + grs.add(new NounMetadata(appId, PixelDataType.CONST_STRING)); + reactor.getNounStore().addNoun(ReactorKeysEnum.APP.getKey(), grs); + + } else { + grs = new GenRowStruct(); + grs.add(new NounMetadata(options.getDbName(), PixelDataType.CONST_STRING)); + reactor.getNounStore().addNoun(ReactorKeysEnum.APP.getKey(), grs); + } + // add to existing + grs = new GenRowStruct(); + grs.add(new NounMetadata(true, PixelDataType.BOOLEAN)); + reactor.getNounStore().addNoun(ReactorKeysEnum.EXISTING.getKey(), grs); + + // add metamodel + grs = new GenRowStruct(); + grs.add(new NounMetadata(newMetamodelList.get(i), PixelDataType.MAP)); + reactor.getNounStore().addNoun(ReactorKeysEnum.METAMODEL.getKey(), grs); + + // add file path + grs = new GenRowStruct(); + grs.add(new NounMetadata(csvFileLocation, PixelDataType.CONST_STRING)); + reactor.getNounStore().addNoun(ReactorKeysEnum.FILE_PATH.getKey(), grs); + + // execute! + NounMetadata response = reactor.execute(); + if (i == 0) { + // need to keep app id to override + appId = (String) response.getValue(); + } + reactor = getImportReactor(options); + } + + } + } + return appId; + } + + private IReactor getImportReactor(ImportOptions options) { + DB_TYPE importDBType = options.getDbType(); + IMPORT_METHOD importType = options.getImportMethod(); + IReactor reactor = null; + if (importDBType == DB_TYPE.RDBMS + && (importType == IMPORT_METHOD.CREATE_NEW || importType == IMPORT_METHOD.ADD_TO_EXISTING)) { + reactor = new RdbmsCsvUploadReactor(); + } else if (importDBType == DB_TYPE.RDF + && (importType == IMPORT_METHOD.CREATE_NEW || importType == IMPORT_METHOD.ADD_TO_EXISTING)) { + reactor = new RdfCsvUploadReactor(); + String baseURI = options.getBaseUrl(); + GenRowStruct grs = new GenRowStruct(); + grs = new GenRowStruct(); + grs.add(new NounMetadata(baseURI, PixelDataType.CONST_STRING)); + reactor.getNounStore().addNoun(UploadInputUtility.CUSTOM_BASE_URI, grs); + + } else if (importDBType == DB_TYPE.TINKER + && (importType == IMPORT_METHOD.CREATE_NEW || importType == IMPORT_METHOD.ADD_TO_EXISTING)) { + + reactor = new TinkerCsvUploadReactor(); + GenRowStruct grs = new GenRowStruct(); + grs = new GenRowStruct(); + grs.add(new NounMetadata(options.getTinkerDriverType().toString(), PixelDataType.CONST_STRING)); + reactor.getNounStore().addNoun("tinkerDriver", grs); + + } + return reactor; + } + + private List> createNewMetamodel(ImportOptions options) { + List> newMetamodelList = new ArrayList<>(); + Hashtable[] metamodel = options.getMetamodelArray(); + for (Hashtable mm : metamodel) { + HashMap newMetamodel = new HashMap<>(); + String relationStr = mm.get("RELATION"); + String[] relations = relationStr.split(";"); + ArrayList> relationships = new ArrayList<>(); + for (String relStr : relations) { + String[] rel = relStr.split("@"); + HashMap relMap = new HashMap<>(); + relMap.put(Constants.FROM_TABLE, rel[0]); + relMap.put(Constants.REL_NAME, rel[1]); + relMap.put(Constants.TO_TABLE, rel[2]); + relationships.add(relMap); + } + newMetamodel.put(Constants.RELATION, relationships); + String nodePropStr = mm.get("NODE_PROP"); + String[] nodeProps = nodePropStr.split(";"); + HashMap> nodePropMap = new HashMap<>(); + for (String nodeStr : nodeProps) { + String[] propSplit = nodeStr.split("%"); + String node = propSplit[0]; + String prop = propSplit[1]; + List properties = new ArrayList<>(); + if (nodePropMap.containsKey(node)) { + properties = nodePropMap.get(node); + } + properties.add(prop); + nodePropMap.put(node, properties); + } + newMetamodel.put(Constants.NODE_PROP, nodePropMap); + newMetamodelList.add(newMetamodel); + } + return newMetamodelList; + } + @POST @Path("/excel/uploadFile") @Produces("application/json") From 2801a092218604658152aff28c73248a0b14ac37 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 8 Aug 2018 15:55:38 +0000 Subject: [PATCH 0169/1906] UPDATE ::: Starting to merge additional security methods - not completed yet UPDATE ::: Using chrome driver to take image capture instead of running via process REQUIREMENT ::: DELETE YOUR SECURITY DATABASE AS NEW SCHEMA HAS BEEN PUSHED!!! git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29488 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 2ad534190a91625f37db2fde6cd8a285bc87ef1d --- src/prerna/semoss/web/services/AppResource.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/prerna/semoss/web/services/AppResource.java b/src/prerna/semoss/web/services/AppResource.java index 9eceffab9..48d5dc422 100644 --- a/src/prerna/semoss/web/services/AppResource.java +++ b/src/prerna/semoss/web/services/AppResource.java @@ -94,7 +94,12 @@ private File getAppImageFile(String app) { @Path("/insightImage/download") @Produces(MediaType.APPLICATION_OCTET_STREAM) public Response downloadInsightImage(@Context HttpServletRequest request, @PathParam("appName") String app, @QueryParam("rdbmsId") String id, @QueryParam("params") String params) { - File exportFile = getInsightImageFile(app, id, request.getHeader("Referer"), params); + boolean securityEnabled = Boolean.parseBoolean((String)DIHelper.getInstance().getLocalProp(Constants.SECURITY_ENABLED)); + String sessionId = null; + if(securityEnabled){ + sessionId = request.getSession(false).getId(); + } + File exportFile = getInsightImageFile(app, id, request.getHeader("Referer"), params, sessionId); if(exportFile != null && exportFile.exists()) { String exportName = app + "_Image." + FilenameUtils.getExtension(exportFile.getAbsolutePath()); return Response.status(200).entity(exportFile).header("Content-Disposition", "attachment; filename=" + exportName).build(); @@ -110,7 +115,7 @@ public Response downloadInsightImage(@Context HttpServletRequest request, @PathP * @param app * @return */ - private File getInsightImageFile(String app, String id, String feUrl, String params) { + private File getInsightImageFile(String app, String id, String feUrl, String params, String sessionId) { String appId = MasterDatabaseUtility.testEngineIdIfAlias(app); String propFileLoc = DIHelper.getInstance().getProperty(appId + "_" + Constants.STORE); Properties prop = Utility.loadProperties(propFileLoc); @@ -130,7 +135,7 @@ private File getInsightImageFile(String app, String id, String feUrl, String par } else { // try making the image if(feUrl != null) { - ImageCaptureReactor.runImageCapture(feUrl, appId, id, params); + ImageCaptureReactor.runImageCapture(feUrl, appId, id, params, sessionId); } if(f.exists()) { return f; From 7c2bb4c76a29444433df6563c3b05923fec186e6 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 8 Aug 2018 16:03:21 +0000 Subject: [PATCH 0170/1906] UPDATE ::: Pushing pom.xml requirement for image capture REQUIREMENT ::: MAVEN UPDATE! git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29490 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 77361fb1881107115d4f158e8166324e4a7f5d17 --- pom.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pom.xml b/pom.xml index 5c6dc57ac..3b3b2aab9 100644 --- a/pom.xml +++ b/pom.xml @@ -2792,5 +2792,10 @@ plexus-utils 3.1.0 + + org.seleniumhq.selenium + selenium-java + 3.4.0 + \ No newline at end of file From 8e5e8ccacace7b7f2ecab17ced80f1b33f765963 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 9 Aug 2018 12:33:07 +0000 Subject: [PATCH 0171/1906] UPDATE ::: Adding security to the app image setting UPDATE ::: Adding new rest endpoint to set the insight image git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29506 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 13e709a38a1664ddc206e67003bcea123f6c78ec --- .../semoss/web/services/AppResource.java | 80 +++++------ src/prerna/upload/ImageUploader.java | 130 ++++++++++++++++-- src/prerna/upload/Uploader.java | 3 +- 3 files changed, 163 insertions(+), 50 deletions(-) diff --git a/src/prerna/semoss/web/services/AppResource.java b/src/prerna/semoss/web/services/AppResource.java index 48d5dc422..5bc18dbc1 100644 --- a/src/prerna/semoss/web/services/AppResource.java +++ b/src/prerna/semoss/web/services/AppResource.java @@ -147,44 +147,6 @@ private File getInsightImageFile(String app, String id, String feUrl, String par } } - - /* - * Currently not used below... - */ - - @GET - @Path("/appWidget") - @Produces(MediaType.APPLICATION_OCTET_STREAM) - public Response getAppWidget(@PathParam("appName") String app, @QueryParam("widget") String widgetName, @QueryParam("file") String fileName) { - - final String basePath = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER); - String appWidgetDirLoc = basePath + DIR_SEPARATOR + "db" + - DIR_SEPARATOR + app + - DIR_SEPARATOR + "version" + - DIR_SEPARATOR + "widgets"; - - // Get widget file - String widgetFile = appWidgetDirLoc + DIR_SEPARATOR + widgetName + DIR_SEPARATOR + fileName; - File f = new File(widgetFile); - FileInputStream fis = null; - if (f.exists()) { - try { - fis = new FileInputStream(f); - byte[] byteArray = IOUtils.toByteArray(fis); - // return file - return Response.status(200).entity(byteArray).build(); - } catch (IOException e) { - e.printStackTrace(); - } finally { - closeStream(fis); - } - } - // return error - Map errorMap = new HashMap(); - errorMap.put("errorMessage", "error sending widget file " + widgetName + "\\" + fileName); - return WebUtility.getResponse(errorMap, 400); - } - ///////////////////////////////////////////////////////////////// /* @@ -226,6 +188,46 @@ private void closeStream(FileInputStream fis) { } } + /////////////////////////////////////////////////////// + /////////////////////////////////////////////////////// + /////////////////////////////////////////////////////// + /////////////////////////////////////////////////////// + /////////////////////////////////////////////////////// + + /* + * Currently not used below... + */ - + @GET + @Path("/appWidget") + @Produces(MediaType.APPLICATION_OCTET_STREAM) + public Response getAppWidget(@PathParam("appName") String app, @QueryParam("widget") String widgetName, @QueryParam("file") String fileName) { + final String basePath = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER); + String appWidgetDirLoc = basePath + DIR_SEPARATOR + "db" + + DIR_SEPARATOR + app + + DIR_SEPARATOR + "version" + + DIR_SEPARATOR + "widgets"; + + // Get widget file + String widgetFile = appWidgetDirLoc + DIR_SEPARATOR + widgetName + DIR_SEPARATOR + fileName; + File f = new File(widgetFile); + FileInputStream fis = null; + if (f.exists()) { + try { + fis = new FileInputStream(f); + byte[] byteArray = IOUtils.toByteArray(fis); + // return file + return Response.status(200).entity(byteArray).build(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + closeStream(fis); + } + } + // return error + Map errorMap = new HashMap(); + errorMap.put("errorMessage", "error sending widget file " + widgetName + "\\" + fileName); + return WebUtility.getResponse(errorMap, 400); + } + } diff --git a/src/prerna/upload/ImageUploader.java b/src/prerna/upload/ImageUploader.java index 881d79f56..7f52a2938 100644 --- a/src/prerna/upload/ImageUploader.java +++ b/src/prerna/upload/ImageUploader.java @@ -2,34 +2,41 @@ import java.io.File; import java.io.FileFilter; +import java.util.HashMap; import java.util.List; -import java.util.Properties; +import java.util.Map; import java.util.Vector; import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.Context; +import javax.ws.rs.core.Response; import org.apache.commons.fileupload.FileItem; import org.apache.commons.io.filefilter.WildcardFileFilter; +import prerna.auth.SecurityQueryUtils; +import prerna.auth.User; import prerna.engine.impl.SmssUtilities; import prerna.nameserver.utility.MasterDatabaseUtility; import prerna.util.Constants; -import prerna.util.DIHelper; -import prerna.util.Utility; +import prerna.web.services.util.WebUtility; public class ImageUploader extends Uploader { @POST @Path("/appImage") @Produces("application/json") - public void uploadAppImage(@Context HttpServletRequest request) { + public Response uploadAppImage(@Context HttpServletRequest request) { + Map returnMap = new HashMap(); + List fileItems = processRequest(request); // collect all of the data input on the form FileItem imageFile = null; + String appId = null; String appName = null; for(FileItem fi : fileItems) { @@ -43,11 +50,33 @@ public void uploadAppImage(@Context HttpServletRequest request) { } } - //TODO: account for user here - String appId = MasterDatabaseUtility.testEngineIdIfAlias(appName); - String propFileLoc = DIHelper.getInstance().getProperty(appId + "_" + Constants.STORE); - Properties prop = Utility.loadProperties(propFileLoc); - appName = prop.getProperty(Constants.ENGINE_ALIAS); + if(this.securityEnabled) { + HttpSession session = request.getSession(false); + if(session != null){ + User user = ((User) session.getAttribute(Constants.SESSION_USER)); + try { + appId = SecurityQueryUtils.testUserEngineIdForAlias(user, appName); + } catch(Exception e) { + returnMap.put("errorMessage", e.getMessage()); + return WebUtility.getResponse(returnMap, 401); + } + if(!SecurityQueryUtils.userCanEditEngine(user, appId)) { + throw new IllegalArgumentException("Database " + appId + " does not exist or user does not have access to database"); + } + appName = SecurityQueryUtils.getEngineAliasForId(appId); + } else { + returnMap.put("errorMessage", "User session is invalid"); + return WebUtility.getResponse(returnMap, 401); + } + } else { + appId = MasterDatabaseUtility.testEngineIdIfAlias(appName); + appName = MasterDatabaseUtility.getEngineAliasForId(appId); + String appDir = filePath + DIR_SEPARATOR + SmssUtilities.getUniqueName(appName, appId); + if(!(new File(appDir).exists())) { + returnMap.put("errorMessage", "Could not find app directory"); + return WebUtility.getResponse(returnMap, 401); + } + } // now that we have the app name // and the image file @@ -69,6 +98,89 @@ public void uploadAppImage(@Context HttpServletRequest request) { } } writeFile(imageFile, f); + + returnMap.put("message", "successfully updated app image"); + return WebUtility.getResponse(returnMap, 200); + } + + @POST + @Path("/insightImage") + @Produces("application/json") + public Response uploadInsightImage(@Context HttpServletRequest request) { + Map returnMap = new HashMap(); + + List fileItems = processRequest(request); + // collect all of the data input on the form + FileItem imageFile = null; + String appId = null; + String appName = null; + String insightId = null; + + for(FileItem fi : fileItems) { + String fieldName = fi.getFieldName(); + String value = fi.getString(); + if(fieldName.equals("file")) { + imageFile = fi; + } + if(fieldName.equals("app")) { + appName = value; + } + if(fieldName.equals("insightId")) { + insightId = value; + } + } + + if(this.securityEnabled) { + HttpSession session = request.getSession(false); + if(session != null){ + User user = ((User) session.getAttribute(Constants.SESSION_USER)); + try { + appId = SecurityQueryUtils.testUserEngineIdForAlias(user, appName); + } catch(Exception e) { + returnMap.put("errorMessage", e.getMessage()); + return WebUtility.getResponse(returnMap, 401); + } + if(!SecurityQueryUtils.userCanEditInsight(user, appId, insightId)) { + throw new IllegalArgumentException("User does not have access to edit this insight within the app"); + } + appName = SecurityQueryUtils.getEngineAliasForId(appId); + } else { + returnMap.put("errorMessage", "User session is invalid"); + return WebUtility.getResponse(returnMap, 401); + } + } else { + appId = MasterDatabaseUtility.testEngineIdIfAlias(appName); + appName = MasterDatabaseUtility.getEngineAliasForId(appId); + String appDir = filePath + DIR_SEPARATOR + SmssUtilities.getUniqueName(appName, appId); + if(!(new File(appDir).exists())) { + returnMap.put("errorMessage", "Could not find app directory"); + return WebUtility.getResponse(returnMap, 401); + } + } + + // now that we have the app name + // and the image file + // we want to write it into the app location + String imageDir = filePath + DIR_SEPARATOR + SmssUtilities.getUniqueName(appName, appId) + DIR_SEPARATOR + "version" + DIR_SEPARATOR + insightId; + File f = new File(imageDir); + if(!f.exists()) { + f.mkdirs(); + } + String imageLoc = imageDir + DIR_SEPARATOR + "image." + imageFile.getContentType().split("/")[1]; + f = new File(imageLoc); + // find all the existing image files + // and delete them + File[] oldImages = findImageFile(f.getParentFile()); + // delete if any exist + if(oldImages != null) { + for(File oldI : oldImages) { + oldI.delete(); + } + } + writeFile(imageFile, f); + + returnMap.put("message", "successfully updated insight image"); + return WebUtility.getResponse(returnMap, 200); } /** diff --git a/src/prerna/upload/Uploader.java b/src/prerna/upload/Uploader.java index ba00b3f44..ff67e31fe 100644 --- a/src/prerna/upload/Uploader.java +++ b/src/prerna/upload/Uploader.java @@ -113,8 +113,7 @@ protected void deleteFilesFromServer(String[] files) { } } - protected List processRequest(@Context HttpServletRequest request) - { + protected List processRequest(@Context HttpServletRequest request) { List fileItems = null; try { DiskFileItemFactory factory = new DiskFileItemFactory(); From 797eb039a24642b0645aeba9aa704e7fdc9d2ec5 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 9 Aug 2018 14:08:03 +0000 Subject: [PATCH 0172/1906] UPDATE ::: Pushing additions to pom.xml for jcloud + minio git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29510 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 8b66df888905523c2964f8e399b6e493c1a4ebc5 --- pom.xml | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 3b3b2aab9..41e4c5ba4 100644 --- a/pom.xml +++ b/pom.xml @@ -2796,6 +2796,27 @@ org.seleniumhq.selenium selenium-java 3.4.0 - + + + net.lingala.zip4j + zip4j + 1.3.2 + + + org.apache.jclouds + jclouds-all + 2.1.0 + + + io.minio + minio + 4.0.2 + + + + org.freemarker + freemarker + 2.3.20 + \ No newline at end of file From f33320b243e225124b6d950a722df92ac2f85018 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 9 Aug 2018 14:12:38 +0000 Subject: [PATCH 0173/1906] UPDATE ::: Adding zookeeper jar git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29511 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 3be08b3e3f8a031757443f882e0d92aaa0d50776 --- pom.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pom.xml b/pom.xml index 41e4c5ba4..ea2148946 100644 --- a/pom.xml +++ b/pom.xml @@ -2818,5 +2818,16 @@ freemarker 2.3.20 + + org.apache.zookeeper + zookeeper + 3.4.9 + + + * + * + + + \ No newline at end of file From 4594610b7d6fb0825888f516d48d85a7f0c72be0 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 9 Aug 2018 17:39:05 +0000 Subject: [PATCH 0174/1906] UPDATE ::: Performing some code cleanup on the files git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29519 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: d564da2c0a76c3bc2f82c462d5983da026752cf2 --- .../web/services/AuthorizationResource.java | 175 ++++++++++-------- .../semoss/web/services/UserResource.java | 172 ++++++++++++++++- 2 files changed, 267 insertions(+), 80 deletions(-) diff --git a/src/prerna/semoss/web/services/AuthorizationResource.java b/src/prerna/semoss/web/services/AuthorizationResource.java index f24f0b67a..84e28c64c 100644 --- a/src/prerna/semoss/web/services/AuthorizationResource.java +++ b/src/prerna/semoss/web/services/AuthorizationResource.java @@ -30,6 +30,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.Hashtable; +import java.util.List; import java.util.Map; import javax.servlet.ServletContext; @@ -49,17 +50,14 @@ import com.google.gson.internal.StringMap; import prerna.auth.AuthProvider; +import prerna.auth.SecurityQueryUtils; +import prerna.auth.SecurityUpdateUtils; import prerna.auth.User; -import prerna.auth.UserPermissionsMasterDB; import prerna.util.Constants; import prerna.web.services.util.WebUtility; @Path("/authorization") -public class AuthorizationResource -{ - @Context ServletContext context; - String output = ""; - UserPermissionsMasterDB permissions = new UserPermissionsMasterDB(); +public class AuthorizationResource { /** * Check if the security is enabled in the application. @@ -68,7 +66,7 @@ public class AuthorizationResource @GET @Produces("application/json") @Path("securityEnabled") - public StreamingOutput isSecurityEnabled() { + public StreamingOutput isSecurityEnabled(@Context ServletContext context) { boolean securityEnabled = Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED)); return WebUtility.getSO(securityEnabled); } @@ -90,9 +88,9 @@ public Response getGroupsAndMembers(@Context HttpServletRequest request) { return WebUtility.getResponse(errorMap, 401); } - User user = (User) request.getSession().getAttribute("semoss_user"); + User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); - ArrayList> ret = permissions.getGroupsAndMembersForUser(userId); + ArrayList> ret = SecurityQueryUtils.getGroupsAndMembersForUser(userId); return WebUtility.getResponse(ret, 200); } @@ -101,7 +99,7 @@ public Response getGroupsAndMembers(@Context HttpServletRequest request) { @Produces("application/json") @Path("searchForUser") public StreamingOutput searchForUser(@Context HttpServletRequest request, @QueryParam("searchTerm") String searchTerm) { - ArrayList> ret = permissions.searchForUser(searchTerm.trim()); + List> ret = SecurityQueryUtils.searchForUser(searchTerm.trim()); return WebUtility.getSO(ret); } @@ -115,7 +113,7 @@ public StreamingOutput searchForUser(@Context HttpServletRequest request, @Query @Path("getDatabases") public Response getDatabases(@Context HttpServletRequest request) { Hashtable errorRet = new Hashtable(); - ArrayList> ret = new ArrayList<>(); + List> ret = new ArrayList<>(); HttpSession session = request.getSession(false); if(session == null){ Map errorMap = new HashMap(); @@ -123,9 +121,9 @@ public Response getDatabases(@Context HttpServletRequest request) { return WebUtility.getResponse(errorMap, 401); } try{ - User user = (User) request.getSession().getAttribute("semoss_user"); + User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); - ret = permissions.getUserDatabases(userId, false); + ret = SecurityQueryUtils.getUserDatabases(userId, false); return WebUtility.getResponse(ret, 200); } catch (IllegalArgumentException e){ e.printStackTrace(); @@ -148,11 +146,11 @@ public Response getDatabases(@Context HttpServletRequest request) { @Path("/admin/getDatabases") public Response getAdminDatabases(@Context HttpServletRequest request) { Hashtable errorRet = new Hashtable(); - ArrayList> ret = new ArrayList<>(); + List> ret = new ArrayList<>(); try{ - User user = (User) request.getSession().getAttribute("semoss_user"); + User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); - ret = permissions.getUserDatabases(userId, true); + ret = SecurityQueryUtils.getUserDatabases(userId, true); return WebUtility.getResponse(ret, 200); } catch (IllegalArgumentException e){ e.printStackTrace(); @@ -177,10 +175,10 @@ public Response getAdminDatabaseUsersAndGroups(@Context HttpServletRequest reque Hashtable errorRet = new Hashtable(); StringMap>> ret = new StringMap<>(); try{ - User user = (User) request.getSession().getAttribute("semoss_user"); + User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); String engineId = form.getFirst("engineId"); - ret = permissions.getDatabaseUsersAndGroups(userId, engineId, true); + ret = SecurityQueryUtils.getDatabaseUsersAndGroups(userId, engineId, true); return WebUtility.getResponse(ret, 200); } catch (IllegalArgumentException e){ e.printStackTrace(); @@ -207,9 +205,9 @@ public Response getDatabaseUsersAndGroups(@Context HttpServletRequest request, M StringMap>> ret = new StringMap<>(); try{ String engineId = form.getFirst("engineId"); - User user = (User) request.getSession().getAttribute("semoss_user"); + User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); - ret = permissions.getDatabaseUsersAndGroups(userId, engineId, false); + ret = SecurityQueryUtils.getDatabaseUsersAndGroups(userId, engineId, false); return WebUtility.getResponse(ret, 200); } catch (IllegalArgumentException e){ e.printStackTrace(); @@ -228,14 +226,14 @@ public Response getDatabaseUsersAndGroups(@Context HttpServletRequest request, M public Response addNewGroup(@Context HttpServletRequest request, MultivaluedMap form) { Gson gson = new Gson(); ArrayList users = gson.fromJson(form.getFirst("users"), ArrayList.class); - User user = (User) request.getSession().getAttribute("semoss_user"); + User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); - Boolean success = permissions.addGroup(userId, form.getFirst("groupName").trim(), users); + Boolean success = SecurityUpdateUtils.addGroup(userId, form.getFirst("groupName").trim(), users); if(success) { return WebUtility.getResponse(success, 200); } else { - return WebUtility.getResponse(success, 200); + return WebUtility.getResponse(success, 400); } } @@ -244,9 +242,9 @@ public Response addNewGroup(@Context HttpServletRequest request, MultivaluedMap< @Path("removeGroup") public Response removeGroup(@Context HttpServletRequest request, MultivaluedMap form) { String groupId = form.getFirst("groupId").trim(); - User user = (User) request.getSession().getAttribute("semoss_user"); + User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); - Boolean success = permissions.removeGroup(userId, groupId); + Boolean success = SecurityUpdateUtils.removeGroup(userId, groupId); if(success) { return WebUtility.getResponse(success, 200); @@ -265,15 +263,15 @@ public Response editGroup(@Context HttpServletRequest request, MultivaluedMap toAdd = gson.fromJson(form.getFirst("add"), ArrayList.class); ArrayList toRemove = gson.fromJson(form.getFirst("remove"), ArrayList.class); - User user = (User) request.getSession().getAttribute("semoss_user"); + User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); for(String add : toAdd) { - permissions.addUserToGroup(userId, groupId, add); + SecurityUpdateUtils.addUserToGroup(userId, groupId, add); } for(String remove : toRemove) { - permissions.removeUserFromGroup(userId, groupId, remove); + SecurityUpdateUtils.removeUserFromGroup(userId, groupId, remove); } return WebUtility.getResponse(true, 200); } @@ -285,12 +283,12 @@ public Response savePermissions(@Context HttpServletRequest request, Multivalued Gson gson = new Gson(); Hashtable errorRet = new Hashtable(); try{ - User user = (User) request.getSession().getAttribute("semoss_user"); + User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); String engineId = form.getFirst("engineId").trim(); StringMap>> groups = gson.fromJson(form.getFirst("groups"), StringMap.class); StringMap>> users = gson.fromJson(form.getFirst("users"), StringMap.class); - permissions.savePermissions(userId, false, engineId, groups, users); + SecurityUpdateUtils.savePermissions(userId, false, engineId, groups, users); } catch(IllegalArgumentException e){ errorRet.put("error", e.getMessage()); return WebUtility.getResponse(errorRet, 400); @@ -309,7 +307,7 @@ public Response savePermissions(@Context HttpServletRequest request, Multivalued public Response isUserGroupAddedValid(@Context HttpServletRequest request, MultivaluedMap form) { Gson gson = new Gson(); try { - User user = (User) request.getSession().getAttribute("semoss_user"); + User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); String ret = "true"; @@ -317,21 +315,25 @@ public Response isUserGroupAddedValid(@Context HttpServletRequest request, Multi String groupId = form.getFirst("groupIdAdd").trim(); String engineId = form.getFirst("engineId").trim(); - StringMap> groups = gson.fromJson(form.getFirst("groups"), StringMap.class); - ArrayList groupsToAdd = groups.get("add"); - ArrayList groupsToRemove = groups.get("remove"); + StringMap>> groups = gson.fromJson(form.getFirst("groups"), StringMap.class); + ArrayList> groupsToAddMap = groups.get("add"); + ArrayList groupsToAdd = convertArrayMaptoArrayList(groupsToAddMap); + ArrayList> groupsToRemoveMap = groups.get("remove"); + ArrayList groupsToRemove = convertArrayMaptoArrayList(groupsToRemoveMap); - StringMap> users = gson.fromJson(form.getFirst("users"), StringMap.class); - ArrayList usersToAdd = users.get("add"); - ArrayList usersToRemove = users.get("remove"); + StringMap>> users = gson.fromJson(form.getFirst("users"), StringMap.class); + ArrayList> usersToAddMap = users.get("add"); + ArrayList usersToAdd = convertArrayMaptoArrayList(usersToAddMap); + ArrayList> usersToRemoveMap = users.get("remove"); + ArrayList usersToRemove = convertArrayMaptoArrayList(usersToRemoveMap); - ArrayList groupsFinal = permissions.getAllDbGroupsById(engineId, groupsToAdd, groupsToRemove); - ArrayList usersFinal = permissions.getAllDbUsersById(engineId, usersToAdd, usersToRemove); + ArrayList groupsFinal = SecurityQueryUtils.getAllDbGroupsById(engineId, groupsToAdd, groupsToRemove); + ArrayList usersFinal = SecurityQueryUtils.getAllDbUsersById(engineId, usersToAdd, usersToRemove); if(!userId.isEmpty()){ - ret = permissions.isUserWithDatabasePermissionAlready(userId, groupsFinal, usersFinal); + ret = SecurityQueryUtils.isUserWithDatabasePermissionAlready(userId, groupsFinal, usersFinal); } else if(!groupId.isEmpty()){ - ret = permissions.isGroupUsersWithDatabasePermissionAlready(groupId, groupsFinal, usersFinal); + ret = SecurityQueryUtils.isGroupUsersWithDatabasePermissionAlready(groupId, groupsFinal, usersFinal); } if(ret.equals("true")){ @@ -344,20 +346,28 @@ public Response isUserGroupAddedValid(@Context HttpServletRequest request, Multi } } + private ArrayList convertArrayMaptoArrayList(ArrayList> set){ + ArrayList array = new ArrayList<>(); + for(StringMap map : set){ + array.add(map.get("id")); + } + return array; + } + @POST @Produces("application/json") @Path("isUserAddedToGroupValid") public Response isUserAddedToGroupValid(@Context HttpServletRequest request, MultivaluedMap form) { Gson gson = new Gson(); try { - User user = (User) request.getSession().getAttribute("semoss_user"); + User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); String ret = ""; String userIdAdd = form.getFirst("userIdAdd").trim(); String groupId = form.getFirst("groupId").trim(); - ret += permissions.isUserAddedToGroupValid(userIdAdd, groupId); + ret += SecurityQueryUtils.isUserAddedToGroupValid(userIdAdd, groupId); if(ret.equals("true")){ return WebUtility.getResponse(ret, 200); @@ -369,23 +379,6 @@ public Response isUserAddedToGroupValid(@Context HttpServletRequest request, Mul } } - @GET - @Produces("application/json") - @Path("getInsightPermissions") - public Response getInsightPermissions(@Context HttpServletRequest request, @QueryParam("database") String databaseName, @QueryParam("insight") String insightId) { - return WebUtility.getResponse(permissions.getUserPermissionsForInsight(databaseName, insightId), 200); - } - - - @GET - @Produces("application/json") - @Path("/admin/getAllSeedsForUser") - public Response getAllSeedsForUser(@Context HttpServletRequest request, @QueryParam("userId") String userId) { -// return Response.status(200).entity(WebUtility.getSO(permissions.getMetamodelSeedsForUser(userId, false))).build(); - return WebUtility.getResponse(permissions.getMetamodelSeedsForUser(userId, false), 200); - } - - @GET @Path("/admin/isAdminUser") public Response isAdminUser(@Context HttpServletRequest request) { @@ -397,10 +390,10 @@ public Response isAdminUser(@Context HttpServletRequest request) { return WebUtility.getResponse(errorMap, 401); } - if(session.getAttribute("semoss_user") != null) { - User user = (User) request.getSession().getAttribute("semoss_user"); + if(session.getAttribute(Constants.SESSION_USER) != null) { + User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); - if(!userId.equals(Constants.ANONYMOUS_USER_ID) && permissions.isUserAdmin(userId)) { + if(!userId.equals(Constants.ANONYMOUS_USER_ID) && SecurityQueryUtils.isUserAdmin(userId)) { return WebUtility.getResponse(true, 200); } } @@ -414,10 +407,10 @@ public Response isAdminUser(@Context HttpServletRequest request) { public Response getAllDbUsers(@Context HttpServletRequest request) { ArrayList> ret = new ArrayList<>(); Hashtable errorRet = new Hashtable(); - User user = (User) request.getSession().getAttribute("semoss_user"); + User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); try{ - ret = permissions.getAllDbUsers(userId); + ret = SecurityQueryUtils.getAllDbUsers(userId); } catch (IllegalArgumentException e){ e.printStackTrace(); errorRet.put("error", e.getMessage()); @@ -434,11 +427,11 @@ public Response getAllDbUsers(@Context HttpServletRequest request) { public Response removeUserPermissionsbyDbId(@Context HttpServletRequest request, MultivaluedMap form) { boolean ret = false; Hashtable errorRet = new Hashtable(); - User user = (User) request.getSession().getAttribute("semoss_user"); + User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); String engineId = form.getFirst("engineId"); try{ - ret = permissions.removeUserPermissionsbyDbId(userId, engineId); + ret = SecurityUpdateUtils.removeUserPermissionsbyDbId(userId, engineId); } catch (IllegalArgumentException e){ e.printStackTrace(); errorRet.put("error", e.getMessage()); @@ -463,10 +456,10 @@ public Response editUser(@Context HttpServletRequest request, MultivaluedMap errorRet = new Hashtable(); try{ - User user = (User) request.getSession().getAttribute("semoss_user"); + User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); StringMap userInfo = gson.fromJson(form.getFirst("user"), StringMap.class); - ret = permissions.editUser(userId, userInfo); + ret = SecurityUpdateUtils.editUser(userId, userInfo); } catch (IllegalArgumentException e){ e.printStackTrace(); errorRet.put("error", e.getMessage()); @@ -487,12 +480,12 @@ public Response savePermissionsAdmin(@Context HttpServletRequest request, Multiv Hashtable errorRet = new Hashtable(); try{ - User user = (User) request.getSession().getAttribute("semoss_user"); + User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); String engineId = form.getFirst("engineId").trim(); StringMap>> groups = gson.fromJson(form.getFirst("groups"), StringMap.class); StringMap>> users = gson.fromJson(form.getFirst("users"), StringMap.class); - permissions.savePermissions(userId, true, engineId, groups, users); + SecurityUpdateUtils.savePermissions(userId, true, engineId, groups, users); } catch(IllegalArgumentException e){ errorRet.put("error", e.getMessage()); return WebUtility.getResponse(errorRet, 400); @@ -511,11 +504,11 @@ public Response savePermissionsAdmin(@Context HttpServletRequest request, Multiv public Response setDbVisibility(@Context HttpServletRequest request, MultivaluedMap form) { Hashtable errorRet = new Hashtable(); try{ - User user = (User) request.getSession().getAttribute("semoss_user"); + User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); String engineId = form.getFirst("engineId"); String visibility = form.getFirst("visibility"); - permissions.setDbVisibility(userId, engineId, visibility); + SecurityUpdateUtils.setDbVisibility(userId, engineId, visibility); } catch (IllegalArgumentException e){ e.printStackTrace(); errorRet.put("error", e.getMessage()); @@ -534,11 +527,11 @@ public Response setDbVisibility(@Context HttpServletRequest request, Multivalued public Response setAdminDbPublic(@Context HttpServletRequest request, MultivaluedMap form) { Hashtable errorRet = new Hashtable(); try{ - User user = (User) request.getSession().getAttribute("semoss_user"); + User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); String engineId = form.getFirst("engineId"); String isPublic = form.getFirst("public"); - permissions.setDbPublic(userId, engineId, isPublic, true); + SecurityUpdateUtils.setDbPublic(userId, engineId, isPublic, true); } catch (IllegalArgumentException e){ e.printStackTrace(); errorRet.put("error", e.getMessage()); @@ -557,11 +550,11 @@ public Response setAdminDbPublic(@Context HttpServletRequest request, Multivalue public Response setDbPublic(@Context HttpServletRequest request, MultivaluedMap form) { Hashtable errorRet = new Hashtable(); try{ - User user = (User) request.getSession().getAttribute("semoss_user"); + User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); String engineId = form.getFirst("engineId"); String isPublic = form.getFirst("public"); - permissions.setDbPublic(userId, engineId, isPublic, false); + SecurityUpdateUtils.setDbPublic(userId, engineId, isPublic, false); } catch (IllegalArgumentException e){ e.printStackTrace(); errorRet.put("error", e.getMessage()); @@ -580,10 +573,10 @@ public Response setDbPublic(@Context HttpServletRequest request, MultivaluedMap< public Response deleteUser(@Context HttpServletRequest request, MultivaluedMap form) { Hashtable errorRet = new Hashtable(); try{ - User user = (User) request.getSession().getAttribute("semoss_user"); + User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); String adminId = user.getAccessToken(AuthProvider.NATIVE).getId(); String userId = form.getFirst("userId"); - permissions.deleteUser(adminId, userId); + SecurityUpdateUtils.deleteUser(adminId, userId); if(adminId.equals(userId)){ request.getSession().invalidate(); } @@ -598,7 +591,31 @@ public Response deleteUser(@Context HttpServletRequest request, MultivaluedMap ret = new Hashtable(); + try{ + String username = request.getParameter("username"); + String password = request.getParameter("password"); + boolean emptyCredentials = username == null || password == null || username.isEmpty() || password.isEmpty(); + boolean canLogin = !emptyCredentials && SecurityQueryUtils.logIn(username, password); + if(canLogin){ + ret.put("success", "true"); + ret.put("username", username); + String name = SecurityQueryUtils.getNameUser(username); + ret.put("name", name); + String id = SecurityQueryUtils.getUserId(username); + AccessToken authToken = new AccessToken(); + authToken.setProvider(AuthProvider.NATIVE); + authToken.setId(id); + authToken.setName(username); + User newUser = new User(); + newUser.setAccessToken(authToken); + //If there's another session destroy it. + HttpSession session = request.getSession(false); + if(session != null){ + request.getSession().invalidate(); + } + //Create a new session and add an User object to it. + session = request.getSession(true); + session.setAttribute(Constants.SESSION_USER, newUser); + //User print = (User) session.getAttribute(Constants.SESSION_USER); + //LOGGER.info("Logging in with: " + print); + + return WebUtility.getResponse(ret, 200); + } else { + ret.put("error", "The user name or password are invalid."); + return WebUtility.getResponse(ret, 401); + } + } catch(Exception e){ + e.printStackTrace(); + ret.put("error", "An unexpected error happened. Please try again."); + return WebUtility.getResponse(ret, 500); + } + } + + /** + * Logs user out when authenticated in a native way. + */ + @GET + @Produces("application/json") + @Path("/logout") + public Response logoutNative(@Context HttpServletRequest request) throws IOException { + Hashtable ret = new Hashtable(); + try{ + if(request.getSession(false) != null){ + HttpSession session = request.getSession(false); + User print = (User) session.getAttribute(Constants.SESSION_USER); + //LOGGER.info("Logging out with: " + print); + request.getSession().invalidate(); + } else { + ret.put("error", "User is not connected."); + return WebUtility.getResponse(ret, 401); + } + // Only disconnect a connected user. + } catch (Exception ex) { + ex.printStackTrace(); + ret.put("error", "Unexpected error."); + return WebUtility.getResponse(ret, 500); + } + ret.put("success", "true"); + return WebUtility.getResponse(ret, 200); + } + /** + * Create an user according to the information provided (user name, password, email) + * @param request + * @return true if the user is created otherwise error. + */ + @POST + @Produces("application/json") + @Path("createUser") + public Response createUser(@Context HttpServletRequest request) { + Hashtable ret = new Hashtable(); + try{ + String username = request.getParameter("username"); + String name = request.getParameter("name"); + String password = request.getParameter("password"); + String email = request.getParameter("email"); + AccessToken newUser = new AccessToken(); + newUser.setProvider(AuthProvider.NATIVE); + newUser.setEmail(email); + newUser.setName(name); + newUser.setUsername(username); + boolean userCreated = SecurityUpdateUtils.addNativeUser(newUser, password); + if(userCreated){ + ret.put("success", "true"); + ret.put("username", username); + return WebUtility.getResponse(ret, 200); + } else { + ret.put("error", "The user name or email aready exists."); + return WebUtility.getResponse(ret, 400); + } + } catch (IllegalArgumentException e){ + e.printStackTrace(); + ret.put("error", e.getMessage()); + return WebUtility.getResponse(ret, 500); + } catch (Exception e){ + e.printStackTrace(); + ret.put("error", "An unexpected error happened. Please try again."); + return WebUtility.getResponse(ret, 500); + } + } + + @GET + @Produces("application/json") + @Path("/isUserRegistrationOn/") + public Response isUserRegistrationOn(@Context HttpServletRequest request) throws IOException { + boolean reg_allowed = Boolean.parseBoolean(socialData.getProperty("reg_allowed")); + return WebUtility.getResponse(reg_allowed, 200); + } + + @POST + @Produces("application/json") + @Path("/setUserRegistration/") + public Response setUserRegistration(@Context HttpServletRequest request) throws IOException { + OutputStream output = null; + Hashtable errorRet = new Hashtable(); + try { + User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); + String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); + if(SecurityQueryUtils.isUserAdmin(userId)){ + String user_reg = request.getParameter("user_reg"); + PropertiesConfiguration config = new PropertiesConfiguration(DIHelper.getInstance().getProperty("SOCIAL")); + socialData.setProperty("reg_allowed", user_reg); + config.setProperty("reg_allowed", user_reg); + config.save(); + } else { + errorRet.put("error", "User is not allowed to perform this action."); + return WebUtility.getResponse(errorRet, 500); + } + } catch (Exception e) { + e.printStackTrace(); + errorRet.put("error", "An unexpected error happened. Please try again."); + return WebUtility.getResponse(errorRet, 500); + } finally { + if (output != null) { + output.close(); + } + } + return WebUtility.getResponse(true, 200); + } + } From 6cc8fb1fd135a76508c810a75247391a8869422f Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 13 Aug 2018 13:40:29 +0000 Subject: [PATCH 0175/1906] UPDATE ::: Removing StringMap gson object casting to generic Map git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29536 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: e42cf65e6dbb987ec2e4a04134949eacc397eeba --- .../web/services/AuthorizationResource.java | 64 +++++++++---------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/src/prerna/semoss/web/services/AuthorizationResource.java b/src/prerna/semoss/web/services/AuthorizationResource.java index 84e28c64c..8d92f9a24 100644 --- a/src/prerna/semoss/web/services/AuthorizationResource.java +++ b/src/prerna/semoss/web/services/AuthorizationResource.java @@ -90,7 +90,7 @@ public Response getGroupsAndMembers(@Context HttpServletRequest request) { User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); - ArrayList> ret = SecurityQueryUtils.getGroupsAndMembersForUser(userId); + List> ret = SecurityQueryUtils.getGroupsAndMembersForUser(userId); return WebUtility.getResponse(ret, 200); } @@ -99,7 +99,7 @@ public Response getGroupsAndMembers(@Context HttpServletRequest request) { @Produces("application/json") @Path("searchForUser") public StreamingOutput searchForUser(@Context HttpServletRequest request, @QueryParam("searchTerm") String searchTerm) { - List> ret = SecurityQueryUtils.searchForUser(searchTerm.trim()); + List> ret = SecurityQueryUtils.searchForUser(searchTerm.trim()); return WebUtility.getSO(ret); } @@ -173,7 +173,7 @@ public Response getAdminDatabases(@Context HttpServletRequest request) { @Path("/admin/getDatabaseUsersAndGroups") public Response getAdminDatabaseUsersAndGroups(@Context HttpServletRequest request, MultivaluedMap form) { Hashtable errorRet = new Hashtable(); - StringMap>> ret = new StringMap<>(); + Map>> ret = new HashMap<>(); try{ User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); @@ -202,7 +202,7 @@ public Response getAdminDatabaseUsersAndGroups(@Context HttpServletRequest reque @Path("getDatabaseUsersAndGroups") public Response getDatabaseUsersAndGroups(@Context HttpServletRequest request, MultivaluedMap form) { Hashtable errorRet = new Hashtable(); - StringMap>> ret = new StringMap<>(); + Map>> ret = new HashMap<>(); try{ String engineId = form.getFirst("engineId"); User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); @@ -225,7 +225,7 @@ public Response getDatabaseUsersAndGroups(@Context HttpServletRequest request, M @Path("addGroup") public Response addNewGroup(@Context HttpServletRequest request, MultivaluedMap form) { Gson gson = new Gson(); - ArrayList users = gson.fromJson(form.getFirst("users"), ArrayList.class); + List users = gson.fromJson(form.getFirst("users"), ArrayList.class); User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); Boolean success = SecurityUpdateUtils.addGroup(userId, form.getFirst("groupName").trim(), users); @@ -260,8 +260,8 @@ public Response editGroup(@Context HttpServletRequest request, MultivaluedMap toAdd = gson.fromJson(form.getFirst("add"), ArrayList.class); - ArrayList toRemove = gson.fromJson(form.getFirst("remove"), ArrayList.class); + List toAdd = gson.fromJson(form.getFirst("add"), ArrayList.class); + List toRemove = gson.fromJson(form.getFirst("remove"), ArrayList.class); User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); @@ -286,8 +286,8 @@ public Response savePermissions(@Context HttpServletRequest request, Multivalued User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); String engineId = form.getFirst("engineId").trim(); - StringMap>> groups = gson.fromJson(form.getFirst("groups"), StringMap.class); - StringMap>> users = gson.fromJson(form.getFirst("users"), StringMap.class); + Map>> groups = gson.fromJson(form.getFirst("groups"), StringMap.class); + Map>> users = gson.fromJson(form.getFirst("users"), StringMap.class); SecurityUpdateUtils.savePermissions(userId, false, engineId, groups, users); } catch(IllegalArgumentException e){ errorRet.put("error", e.getMessage()); @@ -315,20 +315,20 @@ public Response isUserGroupAddedValid(@Context HttpServletRequest request, Multi String groupId = form.getFirst("groupIdAdd").trim(); String engineId = form.getFirst("engineId").trim(); - StringMap>> groups = gson.fromJson(form.getFirst("groups"), StringMap.class); - ArrayList> groupsToAddMap = groups.get("add"); - ArrayList groupsToAdd = convertArrayMaptoArrayList(groupsToAddMap); - ArrayList> groupsToRemoveMap = groups.get("remove"); - ArrayList groupsToRemove = convertArrayMaptoArrayList(groupsToRemoveMap); + Map>> groups = gson.fromJson(form.getFirst("groups"), StringMap.class); + List> groupsToAddMap = groups.get("add"); + List groupsToAdd = convertListMapToList(groupsToAddMap); + List> groupsToRemoveMap = groups.get("remove"); + List groupsToRemove = convertListMapToList(groupsToRemoveMap); - StringMap>> users = gson.fromJson(form.getFirst("users"), StringMap.class); - ArrayList> usersToAddMap = users.get("add"); - ArrayList usersToAdd = convertArrayMaptoArrayList(usersToAddMap); - ArrayList> usersToRemoveMap = users.get("remove"); - ArrayList usersToRemove = convertArrayMaptoArrayList(usersToRemoveMap); + Map>> users = gson.fromJson(form.getFirst("users"), StringMap.class); + List> usersToAddMap = users.get("add"); + List usersToAdd = convertListMapToList(usersToAddMap); + List> usersToRemoveMap = users.get("remove"); + List usersToRemove = convertListMapToList(usersToRemoveMap); - ArrayList groupsFinal = SecurityQueryUtils.getAllDbGroupsById(engineId, groupsToAdd, groupsToRemove); - ArrayList usersFinal = SecurityQueryUtils.getAllDbUsersById(engineId, usersToAdd, usersToRemove); + List groupsFinal = SecurityQueryUtils.getAllDbGroupsById(engineId, groupsToAdd, groupsToRemove); + List usersFinal = SecurityQueryUtils.getAllDbUsersById(engineId, usersToAdd, usersToRemove); if(!userId.isEmpty()){ ret = SecurityQueryUtils.isUserWithDatabasePermissionAlready(userId, groupsFinal, usersFinal); @@ -346,9 +346,9 @@ public Response isUserGroupAddedValid(@Context HttpServletRequest request, Multi } } - private ArrayList convertArrayMaptoArrayList(ArrayList> set){ - ArrayList array = new ArrayList<>(); - for(StringMap map : set){ + private List convertListMapToList(List> set){ + List array = new ArrayList<>(); + for(Map map : set){ array.add(map.get("id")); } return array; @@ -405,8 +405,8 @@ public Response isAdminUser(@Context HttpServletRequest request) { @Path("/getAllDbUsers") @Produces("application/json") public Response getAllDbUsers(@Context HttpServletRequest request) { - ArrayList> ret = new ArrayList<>(); - Hashtable errorRet = new Hashtable(); + List> ret = new ArrayList<>(); + Map errorRet = new Hashtable(); User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); try{ @@ -426,7 +426,7 @@ public Response getAllDbUsers(@Context HttpServletRequest request) { @Produces("application/json") public Response removeUserPermissionsbyDbId(@Context HttpServletRequest request, MultivaluedMap form) { boolean ret = false; - Hashtable errorRet = new Hashtable(); + Map errorRet = new Hashtable(); User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); String engineId = form.getFirst("engineId"); @@ -454,11 +454,11 @@ public Response removeUserPermissionsbyDbId(@Context HttpServletRequest request, public Response editUser(@Context HttpServletRequest request, MultivaluedMap form) { boolean ret = false; Gson gson = new Gson(); - Hashtable errorRet = new Hashtable(); + Map errorRet = new Hashtable(); try{ User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); - StringMap userInfo = gson.fromJson(form.getFirst("user"), StringMap.class); + Map userInfo = gson.fromJson(form.getFirst("user"), HashMap.class); ret = SecurityUpdateUtils.editUser(userId, userInfo); } catch (IllegalArgumentException e){ e.printStackTrace(); @@ -477,14 +477,14 @@ public Response editUser(@Context HttpServletRequest request, MultivaluedMap form) { Gson gson = new Gson(); - Hashtable errorRet = new Hashtable(); + Map errorRet = new Hashtable(); try{ User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); String engineId = form.getFirst("engineId").trim(); - StringMap>> groups = gson.fromJson(form.getFirst("groups"), StringMap.class); - StringMap>> users = gson.fromJson(form.getFirst("users"), StringMap.class); + Map>> groups = gson.fromJson(form.getFirst("groups"), StringMap.class); + Map>> users = gson.fromJson(form.getFirst("users"), StringMap.class); SecurityUpdateUtils.savePermissions(userId, true, engineId, groups, users); } catch(IllegalArgumentException e){ errorRet.put("error", e.getMessage()); From 1d592f53fa4949eb5c413a1e0daf2886f1f1dbe2 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 14 Aug 2018 12:29:16 +0000 Subject: [PATCH 0176/1906] UPDATE ::: Auto-starting r on server startup due to synchronization issues still persisting git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29562 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: d669990e8539d63b375d7d90b2fd876e3318a001 --- src/prerna/web/conf/DBLoader.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/prerna/web/conf/DBLoader.java b/src/prerna/web/conf/DBLoader.java index 922fee559..ffceaf021 100644 --- a/src/prerna/web/conf/DBLoader.java +++ b/src/prerna/web/conf/DBLoader.java @@ -34,6 +34,7 @@ import com.ibm.icu.util.StringTokenizer; +import prerna.sablecc2.reactor.frame.r.util.RJavaTranslatorFactory; import prerna.util.AbstractFileWatcher; import prerna.util.Constants; import prerna.util.DIHelper; @@ -75,6 +76,13 @@ public void contextInitialized(ServletContextEvent arg0) { //Set whether or not security is enabled in DIHelper to be used in PKQL processing DIHelper.getInstance().setLocalProperty(Constants.SECURITY_ENABLED, arg0.getServletContext().getInitParameter(Constants.SECURITY_ENABLED)); + + //Just load R right away to avoid synchronization issues + try { + RJavaTranslatorFactory.initRConnection(); + } catch(Exception e) { + e.printStackTrace(); + } } public void loadEngines() { From 3757d2283c39d5a9c235e256e1edcb3fb7e346a4 Mon Sep 17 00:00:00 2001 From: tbanach Date: Tue, 14 Aug 2018 13:49:27 +0000 Subject: [PATCH 0177/1906] BUGFIX ::: Fixing Docker issue caused by conflicting sesame jars in path. REQUIREMENT ::: Maven update git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29568 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 90df669c4e60ea1cca216591f230622d277b1918 --- pom.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pom.xml b/pom.xml index ea2148946..d9cc27577 100644 --- a/pom.xml +++ b/pom.xml @@ -2773,6 +2773,12 @@ org.semarglproject semargl-sesame 0.6 + + + * + * + + From 8b24d6326749c5bd2d619c4144c1cc2708ef443b Mon Sep 17 00:00:00 2001 From: rramirezjimenez Date: Wed, 15 Aug 2018 16:09:34 +0000 Subject: [PATCH 0178/1906] BUGFIX ::: Upload generate new metamodel when no properties are added git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29610 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 85282fdecc4add7173f22855e971d6533aeb5181 --- src/prerna/upload/DatabaseUploader.java | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/prerna/upload/DatabaseUploader.java b/src/prerna/upload/DatabaseUploader.java index 29c21479b..7836740b8 100644 --- a/src/prerna/upload/DatabaseUploader.java +++ b/src/prerna/upload/DatabaseUploader.java @@ -820,6 +820,7 @@ private String reactorImport(ImportOptions options, HttpServletRequest request) for (int i = 0; i < csvFiles.length; i++) { String csvFileLocation = csvFiles[i]; + csvFileLocation = csvFileLocation.replace("\\\\", "/"); Insight dummyIn = new Insight(); InsightStore.getInstance().put(dummyIn); @@ -983,18 +984,21 @@ private List> createNewMetamodel(ImportOptions options) { } newMetamodel.put(Constants.RELATION, relationships); String nodePropStr = mm.get("NODE_PROP"); - String[] nodeProps = nodePropStr.split(";"); HashMap> nodePropMap = new HashMap<>(); - for (String nodeStr : nodeProps) { - String[] propSplit = nodeStr.split("%"); - String node = propSplit[0]; - String prop = propSplit[1]; - List properties = new ArrayList<>(); - if (nodePropMap.containsKey(node)) { - properties = nodePropMap.get(node); + + if (nodePropStr.contains(";")) { + String[] nodeProps = nodePropStr.split(";"); + for (String nodeStr : nodeProps) { + String[] propSplit = nodeStr.split("%"); + String node = propSplit[0]; + String prop = propSplit[1]; + List properties = new ArrayList<>(); + if (nodePropMap.containsKey(node)) { + properties = nodePropMap.get(node); + } + properties.add(prop); + nodePropMap.put(node, properties); } - properties.add(prop); - nodePropMap.put(node, properties); } newMetamodel.put(Constants.NODE_PROP, nodePropMap); newMetamodelList.add(newMetamodel); From 90fc98232fa739fcb4b4b0d8245bc246ad47647c Mon Sep 17 00:00:00 2001 From: pkapaleeswaran Date: Mon, 20 Aug 2018 21:14:22 +0000 Subject: [PATCH 0179/1906] Adding the code to publish this DB. Only checks to see if the ZK environment variable has been set before publishing. git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29649 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 40674e650f0517c8c3a9172e6b12f46d0355014d --- src/prerna/web/conf/UserDBLoader.java | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/prerna/web/conf/UserDBLoader.java b/src/prerna/web/conf/UserDBLoader.java index a9e493f43..32054166d 100644 --- a/src/prerna/web/conf/UserDBLoader.java +++ b/src/prerna/web/conf/UserDBLoader.java @@ -27,9 +27,13 @@ *******************************************************************************/ package prerna.web.conf; +import java.util.Map; + import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; +import prerna.cluster.util.ZKClient; + public class UserDBLoader implements ServletContextListener { @Override @@ -43,9 +47,25 @@ public void contextInitialized(ServletContextEvent arg0) { // TODO Auto-generated method stub // given a particular user this would load the databases specific to this user System.out.println("Initializing the context 2"); + publish(); // need to think through this later // this would add the user specific databases // picks the users id from the session } + + private void publish() + { + Map envMap = System.getenv(); + + if(envMap.containsKey(ZKClient.ZK_SERVER) || envMap.containsKey(ZKClient.ZK_SERVER.toUpperCase())) + { + // we are in business + ZKClient client = ZKClient.getInstance(); + client.publishDB("all"); + } + // else + // nothing to do proceed + + } } From bcc5b7b80b80ad5aafea3da7a54f20ed7e398c43 Mon Sep 17 00:00:00 2001 From: pkapaleeswaran Date: Tue, 21 Aug 2018 02:05:18 +0000 Subject: [PATCH 0180/1906] UPDATE:::Updated the publish method to enable the IP to be published instead of All. If we did all, then it will over-write one another on the ZK. git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29665 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: f1d89781e53b609027b6e7e6482860f3892e803d --- src/prerna/web/conf/UserDBLoader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prerna/web/conf/UserDBLoader.java b/src/prerna/web/conf/UserDBLoader.java index 32054166d..706259ef8 100644 --- a/src/prerna/web/conf/UserDBLoader.java +++ b/src/prerna/web/conf/UserDBLoader.java @@ -62,7 +62,7 @@ private void publish() { // we are in business ZKClient client = ZKClient.getInstance(); - client.publishDB("all"); + client.publishDB(client.host); } // else // nothing to do proceed From 9d375af6193c269a1293aef77260672295b0ad6a Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 21 Aug 2018 22:13:11 +0000 Subject: [PATCH 0181/1906] UPDATE ::: Adding logic for storage of users when logging in UPDATE ::: Adding keys to determine which login oauth types you want to use on FE git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29691 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: a36978b4985b3e23408db53ddd66c08025825cff --- .../web/services/AuthorizationResource.java | 41 +- .../semoss/web/services/NameServer.java | 1321 +++++++---------- .../semoss/web/services/UserResource.java | 51 +- 3 files changed, 624 insertions(+), 789 deletions(-) diff --git a/src/prerna/semoss/web/services/AuthorizationResource.java b/src/prerna/semoss/web/services/AuthorizationResource.java index 8d92f9a24..7d9af3235 100644 --- a/src/prerna/semoss/web/services/AuthorizationResource.java +++ b/src/prerna/semoss/web/services/AuthorizationResource.java @@ -49,7 +49,6 @@ import com.google.gson.Gson; import com.google.gson.internal.StringMap; -import prerna.auth.AuthProvider; import prerna.auth.SecurityQueryUtils; import prerna.auth.SecurityUpdateUtils; import prerna.auth.User; @@ -89,7 +88,7 @@ public Response getGroupsAndMembers(@Context HttpServletRequest request) { } User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); + String userId = user.getAccessToken(user.getLogins().get(0)).getId(); List> ret = SecurityQueryUtils.getGroupsAndMembersForUser(userId); return WebUtility.getResponse(ret, 200); @@ -122,7 +121,7 @@ public Response getDatabases(@Context HttpServletRequest request) { } try{ User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); + String userId = user.getAccessToken(user.getLogins().get(0)).getId();; ret = SecurityQueryUtils.getUserDatabases(userId, false); return WebUtility.getResponse(ret, 200); } catch (IllegalArgumentException e){ @@ -149,7 +148,7 @@ public Response getAdminDatabases(@Context HttpServletRequest request) { List> ret = new ArrayList<>(); try{ User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); + String userId = user.getAccessToken(user.getLogins().get(0)).getId(); ret = SecurityQueryUtils.getUserDatabases(userId, true); return WebUtility.getResponse(ret, 200); } catch (IllegalArgumentException e){ @@ -176,7 +175,7 @@ public Response getAdminDatabaseUsersAndGroups(@Context HttpServletRequest reque Map>> ret = new HashMap<>(); try{ User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); + String userId = user.getAccessToken(user.getLogins().get(0)).getId(); String engineId = form.getFirst("engineId"); ret = SecurityQueryUtils.getDatabaseUsersAndGroups(userId, engineId, true); return WebUtility.getResponse(ret, 200); @@ -206,7 +205,7 @@ public Response getDatabaseUsersAndGroups(@Context HttpServletRequest request, M try{ String engineId = form.getFirst("engineId"); User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); + String userId = user.getAccessToken(user.getLogins().get(0)).getId(); ret = SecurityQueryUtils.getDatabaseUsersAndGroups(userId, engineId, false); return WebUtility.getResponse(ret, 200); } catch (IllegalArgumentException e){ @@ -227,7 +226,7 @@ public Response addNewGroup(@Context HttpServletRequest request, MultivaluedMap< Gson gson = new Gson(); List users = gson.fromJson(form.getFirst("users"), ArrayList.class); User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); + String userId = user.getAccessToken(user.getLogins().get(0)).getId(); Boolean success = SecurityUpdateUtils.addGroup(userId, form.getFirst("groupName").trim(), users); if(success) { @@ -243,7 +242,7 @@ public Response addNewGroup(@Context HttpServletRequest request, MultivaluedMap< public Response removeGroup(@Context HttpServletRequest request, MultivaluedMap form) { String groupId = form.getFirst("groupId").trim(); User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); + String userId = user.getAccessToken(user.getLogins().get(0)).getId(); Boolean success = SecurityUpdateUtils.removeGroup(userId, groupId); if(success) { @@ -264,7 +263,7 @@ public Response editGroup(@Context HttpServletRequest request, MultivaluedMap toRemove = gson.fromJson(form.getFirst("remove"), ArrayList.class); User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); + String userId = user.getAccessToken(user.getLogins().get(0)).getId(); for(String add : toAdd) { SecurityUpdateUtils.addUserToGroup(userId, groupId, add); @@ -284,7 +283,7 @@ public Response savePermissions(@Context HttpServletRequest request, Multivalued Hashtable errorRet = new Hashtable(); try{ User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); + String userId = user.getAccessToken(user.getLogins().get(0)).getId(); String engineId = form.getFirst("engineId").trim(); Map>> groups = gson.fromJson(form.getFirst("groups"), StringMap.class); Map>> users = gson.fromJson(form.getFirst("users"), StringMap.class); @@ -308,7 +307,7 @@ public Response isUserGroupAddedValid(@Context HttpServletRequest request, Multi Gson gson = new Gson(); try { User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); + String userId = user.getAccessToken(user.getLogins().get(0)).getId(); String ret = "true"; userId = form.getFirst("userIdAdd").trim(); @@ -361,7 +360,7 @@ public Response isUserAddedToGroupValid(@Context HttpServletRequest request, Mul Gson gson = new Gson(); try { User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); + String userId = user.getAccessToken(user.getLogins().get(0)).getId(); String ret = ""; String userIdAdd = form.getFirst("userIdAdd").trim(); @@ -392,7 +391,7 @@ public Response isAdminUser(@Context HttpServletRequest request) { if(session.getAttribute(Constants.SESSION_USER) != null) { User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); + String userId = user.getAccessToken(user.getLogins().get(0)).getId(); if(!userId.equals(Constants.ANONYMOUS_USER_ID) && SecurityQueryUtils.isUserAdmin(userId)) { return WebUtility.getResponse(true, 200); } @@ -408,7 +407,7 @@ public Response getAllDbUsers(@Context HttpServletRequest request) { List> ret = new ArrayList<>(); Map errorRet = new Hashtable(); User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); + String userId = user.getAccessToken(user.getLogins().get(0)).getId(); try{ ret = SecurityQueryUtils.getAllDbUsers(userId); } catch (IllegalArgumentException e){ @@ -428,7 +427,7 @@ public Response removeUserPermissionsbyDbId(@Context HttpServletRequest request, boolean ret = false; Map errorRet = new Hashtable(); User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); + String userId = user.getAccessToken(user.getLogins().get(0)).getId(); String engineId = form.getFirst("engineId"); try{ ret = SecurityUpdateUtils.removeUserPermissionsbyDbId(userId, engineId); @@ -457,7 +456,7 @@ public Response editUser(@Context HttpServletRequest request, MultivaluedMap errorRet = new Hashtable(); try{ User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); + String userId = user.getAccessToken(user.getLogins().get(0)).getId(); Map userInfo = gson.fromJson(form.getFirst("user"), HashMap.class); ret = SecurityUpdateUtils.editUser(userId, userInfo); } catch (IllegalArgumentException e){ @@ -481,7 +480,7 @@ public Response savePermissionsAdmin(@Context HttpServletRequest request, Multiv try{ User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); + String userId = user.getAccessToken(user.getLogins().get(0)).getId(); String engineId = form.getFirst("engineId").trim(); Map>> groups = gson.fromJson(form.getFirst("groups"), StringMap.class); Map>> users = gson.fromJson(form.getFirst("users"), StringMap.class); @@ -505,7 +504,7 @@ public Response setDbVisibility(@Context HttpServletRequest request, Multivalued Hashtable errorRet = new Hashtable(); try{ User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); + String userId = user.getAccessToken(user.getLogins().get(0)).getId(); String engineId = form.getFirst("engineId"); String visibility = form.getFirst("visibility"); SecurityUpdateUtils.setDbVisibility(userId, engineId, visibility); @@ -528,7 +527,7 @@ public Response setAdminDbPublic(@Context HttpServletRequest request, Multivalue Hashtable errorRet = new Hashtable(); try{ User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); + String userId = user.getAccessToken(user.getLogins().get(0)).getId(); String engineId = form.getFirst("engineId"); String isPublic = form.getFirst("public"); SecurityUpdateUtils.setDbPublic(userId, engineId, isPublic, true); @@ -551,7 +550,7 @@ public Response setDbPublic(@Context HttpServletRequest request, MultivaluedMap< Hashtable errorRet = new Hashtable(); try{ User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); + String userId = user.getAccessToken(user.getLogins().get(0)).getId(); String engineId = form.getFirst("engineId"); String isPublic = form.getFirst("public"); SecurityUpdateUtils.setDbPublic(userId, engineId, isPublic, false); @@ -574,7 +573,7 @@ public Response deleteUser(@Context HttpServletRequest request, MultivaluedMap errorRet = new Hashtable(); try{ User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - String adminId = user.getAccessToken(AuthProvider.NATIVE).getId(); + String adminId = user.getAccessToken(user.getLogins().get(0)).getId(); String userId = form.getFirst("userId"); SecurityUpdateUtils.deleteUser(adminId, userId); if(adminId.equals(userId)){ diff --git a/src/prerna/semoss/web/services/NameServer.java b/src/prerna/semoss/web/services/NameServer.java index a35f8f72e..7da2f7b57 100644 --- a/src/prerna/semoss/web/services/NameServer.java +++ b/src/prerna/semoss/web/services/NameServer.java @@ -68,17 +68,14 @@ import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; -import org.apache.log4j.Logger; import org.jsoup.Jsoup; import com.google.gson.Gson; import com.google.gson.internal.StringMap; import com.google.gson.reflect.TypeToken; -import prerna.auth.AuthProvider; import prerna.auth.SecurityQueryUtils; import prerna.auth.User; -import prerna.auth.UserPermissionsMasterDB; import prerna.engine.api.IEngine; import prerna.engine.impl.rdf.RemoteSemossSesameEngine; import prerna.insights.admin.DBAdminResource; @@ -108,248 +105,14 @@ public class NameServer { @Context private ServletContext context; - - private static final Logger logger = Logger.getLogger(NameServer.class.getName()); - private Hashtable helpHash = null; - UserPermissionsMasterDB permissions = new UserPermissionsMasterDB(); - - // gets the engine resource necessary for all engine calls - @Path("e-{engine}") - public Object getLocalDatabase(@Context HttpServletRequest request, @PathParam("engine") String engineId, @QueryParam("api") String api) throws IOException { - // check if api has been passed - // if yes: - // check if remote engine has already been started and stored in context - // -- if so, use that engine - // next check if local engine by that name has been started and stored - // in context - // finally start the remote engine and store in context with api+engine - // name - // otherwise grab local engine -// System.out.println(" Getting DB... " + db); -// HttpSession session = request.getSession(); -// if(api != null && api.equalsIgnoreCase("undefined")) { -// api = null; -// } -// IEngine engine = null; -// if(api != null) { -// String remoteEngineKey = api + ":" + db; -// engine = (IEngine) session.getAttribute(remoteEngineKey); -// if (engine == null && session.getAttribute(db) instanceof IEngine) { -// engine = (IEngine) session.getAttribute(db); -// } -// if (engine == null && !api.equalsIgnoreCase("null")) { // this is a legit API -// addEngine(request, api, db); -// engine = (IEngine) session.getAttribute(remoteEngineKey); -// } -// else if(engine == null){ // this is when the api is null.. need to understand how -// engine = loadEngine(db); -// session.setAttribute(remoteEngineKey, engine); -// } -// } else { -// String remoteEngineKey = db; -// if(session.getAttribute(remoteEngineKey) instanceof IEngine) { -// engine = (IEngine) session.getAttribute(remoteEngineKey); -// } else { -// engine = loadEngine(db); -// session.setAttribute(remoteEngineKey, engine); -// } -// } -// // error at the end -// if(engine == null) { -// throw new IOException("The engine " + db + " at " + api + " cannot be found"); -// } - - Object securityObj = DIHelper.getInstance().getLocalProp(Constants.SECURITY_ENABLED); - boolean security = (securityObj instanceof Boolean && ((boolean) securityObj) ) || (Boolean.parseBoolean(securityObj.toString())); - - if(security) { - HttpSession session = request.getSession(false); - if(session == null) { - return WebUtility.getSO("Not properly authenticated"); - } - User user = (User) session.getAttribute(Constants.SESSION_USER); - if(user == null) { - return WebUtility.getSO("Not properly authenticated"); - } - engineId = SecurityQueryUtils.testUserEngineIdForAlias(user, engineId); - if(!SecurityQueryUtils.getUserEngineIds(user).contains(engineId)) { - Map errorMap = new HashMap(); - errorMap.put("errorMessage", "Database " + engineId + " does not exist or user does not have access to database"); - return WebUtility.getResponse(errorMap, 400); - } - } else { - engineId = MasterDatabaseUtility.testEngineIdIfAlias(engineId); - if(!MasterDatabaseUtility.getAllEngineIds().contains(engineId)) { - Map errorMap = new HashMap(); - errorMap.put("errorMessage", "Database " + engineId + " does not exist"); - return WebUtility.getResponse(errorMap, 400); - } - } - - IEngine engine = Utility.getEngine(engineId); - EngineResource res = new EngineResource(); - res.setEngine(engine); - return res; - } - - @Path("s-{engine}") - public Object getEngineProxy(@PathParam("engine") String db, @Context HttpServletRequest request) { - // this is the name server - // this needs to return stuff - System.out.println(" Getting DB... " + db); - HttpSession session = request.getSession(); - IEngine engine = (IEngine) session.getAttribute(db); - EngineRemoteResource res = new EngineRemoteResource(); - res.setEngine(engine); - return res; - } - - // Controls all calls controlling the central name server - @Path("centralNameServer") - public Object getCentralNameServer(@QueryParam("centralServerUrl") String url, - @Context HttpServletRequest request) { - // this is the name server - // this needs to return stuff - System.out.println(" Going to central name server ... " + url); - CentralNameServer cns = new CentralNameServer(); - cns.setCentralApi(url); - return cns; - } - - // gets all the tags for a given insight across all the engines - @GET - @Path("tags") - @Produces("application/json") - public StreamingOutput getTags(@QueryParam("insight") String insight, @Context HttpServletRequest request) { - // if the tag is empty, this will give back all the tags in the engines - return null; - } - -// // gets a particular insight -// @GET -// @Path("central/context/getInsight") -// @Produces("application/xml") -// public StreamingOutput getInsight(@QueryParam("insight") String uniqueId) { -// // returns the insight -// // typically is a JSON of the insight -// SolrDocument results = null; -// try { -// results = SolrIndexEngine.getInstance().getInsight(uniqueId); -// } catch (KeyManagementException | NoSuchAlgorithmException | KeyStoreException | SolrServerException | IOException e1) { -// e1.printStackTrace(); -// return WebUtility.getSO("Error executing solr query"); -// } -// return WebUtility.getSO(results); -// } - - /** - * Get the basic information of all engines from solr. - * @param request - * @return all engines. - */ - @GET - @Path("all") - @Produces("application/json") - public StreamingOutput printEngines(@Context HttpServletRequest request) { - Object securityObj = DIHelper.getInstance().getLocalProp(Constants.SECURITY_ENABLED); - boolean security = (securityObj instanceof Boolean && ((boolean) securityObj) ) || (Boolean.parseBoolean(securityObj.toString())); - - List> engines = null; - if(security) { - HttpSession session = request.getSession(false); - if(session == null) { - return WebUtility.getSO("Not properly authenticated"); - } - User user = (User) session.getAttribute(Constants.SESSION_USER); - if(user == null) { - return WebUtility.getSO("Not properly authenticated"); - } - engines = SecurityQueryUtils.getUserDatabaseList(user); - } else { - engines = SecurityQueryUtils.getAllDatabaseList(); - } - - return WebUtility.getSO(engines); - } @GET - @Path("add") + @Path("/sessionTimeout") @Produces("application/json") - public void addEngine(@Context HttpServletRequest request, @QueryParam("api") String api, @QueryParam("database") String database) { - // would be cool to give this as an HTML - RemoteSemossSesameEngine newEngine = new RemoteSemossSesameEngine(); - newEngine.setAPI(api); - newEngine.setDatabase(database); - HttpSession session = request.getSession(); - ArrayList> engines = (ArrayList>) session.getAttribute(Constants.ENGINES); - // temporal - String remoteDbKey = api + ":" + database; - newEngine.openDB(null); - if (newEngine.isConnected()) { - Hashtable engineHash = new Hashtable(); - engineHash.put("name", database); - engineHash.put("api", api); - engines.add(engineHash); - session.setAttribute(Constants.ENGINES, engines); - session.setAttribute(remoteDbKey, newEngine); - DIHelper.getInstance().setLocalProperty(remoteDbKey, newEngine); - } - } - - // gets a particular insight - @GET - @Path("help") - @Produces("text/html") - public StreamingOutput printURL(@Context HttpServletRequest request, @Context HttpServletResponse response) { - // would be cool to give this as an HTML - if (helpHash == null) { - Hashtable urls = new Hashtable(); - urls.put("Help - this menu (GET)", "hostname:portname/Monolith/api/engine/help"); - urls.put("Get All the engines (GET)", "hostname:portname/Monolith/api/engine/all"); - urls.put("Perspectives in a specific engine (GET)", - "hostname:portname/Monolith/api/engine/e-{engineName}/perspectives"); - urls.put("All Insights in a engine (GET)", "hostname:portname/Monolith/api/engine/e-{engineName}/insights"); - urls.put("All Perspectives and Insights in a engine (GET)", - "hostname:portname/Monolith/api/engine/e-{engineName}/pinsights"); - urls.put("Insights for specific perspective specific engine (GET)", - "hostname:portname/Monolith/api/engine/e-{engineName}/insights?perspective={perspective}"); - urls.put("Insight definition for a particular insight (GET)", - "hostname:portname/Monolith/api/engine/e-{engineName}/insight?insight={label of insight (NOT ID)}"); - urls.put("Execute insight without parameter (GET)", - "hostname:portname/Monolith/api/engine/e-{engineName}/output?insight={label of insight (NOT ID)}"); - urls.put("Execute insight with parameter (GET)", - "hostname:portname/Monolith/api/engine/e-{engineName}/output?insight={label of insight (NOT ID)}¶ms=key$value~key2$value2~key3$value3"); - urls.put("Execute Custom Query Select (POST)", - "hostname:portname/Monolith/api/engine/e-{engineName}/querys?query={sparql query}"); - urls.put("Execute Custom Query Construct (GET)", - "hostname:portname/Monolith/api/engine/e-{engineName}/queryc?query={sparql query}"); - urls.put("Execute Custom Query Insert/Delete (POST)", - "hostname:portname/Monolith/api/engine/e-{engineName}/update?query={sparql query}"); - urls.put("Numeric properties of a given node type (GET)", - "hostname:portname/Monolith/api/engine/e-{engineName}/properties/node/type/numeric?nodeType={URI}"); - urls.put("Fill Values for a given parameter (You already get this in insights) (GET)", - "hostname:portname/Monolith/api/engine/e-{engineName}/fill?type={type}"); - urls.put("Get Neighbors of a particular node (GET)", - "hostname:portname/Monolith/api/engine/e-{engineName}/neighbors/instance?node={URI}"); - urls.put("Tags for an insight (Specific Engine)", - "hostname:portname/Monolith/api/engine/e-{engineName}/tags?insight={insight label}"); - urls.put("Insights for a given tag (Tag is optional) (Specific Engine) ", - "hostname:portname/Monolith/api/engine/e-{engineName}/insight?tag={xyz}"); - urls.put("Neighbors of across all engine", "hostname:portname/Monolith/api/engine/neighbors?node={URI}"); - urls.put("Tags for an insight", "hostname:portname/Monolith/api/engine/tags?insight={insight label}"); - urls.put("Insights for a given tag (Tag is optional)", - "hostname:portname/Monolith/api/engine/insight?tag={xyz}"); - urls.put("Create a new engine using excel (requires form submission) (POST)", - "hostname:portname/Monolith/api/engine/insight/upload/excel/upload"); - urls.put("Create a new engine using csv (requires form submission) (POST)", - "hostname:portname/Monolith/api/engine/insight/upload/csv/upload"); - urls.put("Create a new engine using nlp (requires form submission) (POST)", - "hostname:portname/Monolith/api/engine/insight/upload/nlp/upload (GET)"); - helpHash = urls; - } - return getSOHTML(); + public Response getTimeoutValue(@Context HttpServletRequest request) { + return WebUtility.getResponse((double) request.getSession().getMaxInactiveInterval() / 60, 200); } - + // uploader functionality @Path("/uploadDatabase") public Uploader uploadDatabase(@Context HttpServletRequest request) { @@ -361,7 +124,7 @@ public Uploader uploadDatabase(@Context HttpServletRequest request) { upload.setSecurityEnabled(Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED))); return upload; } - + @Path("/uploadFile") public Uploader uploadFile(@Context HttpServletRequest request) { Uploader upload = new FileUploader(); @@ -372,7 +135,7 @@ public Uploader uploadFile(@Context HttpServletRequest request) { upload.setSecurityEnabled(Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED))); return upload; } - + @Path("/uploadImage") public Uploader uploadImage(@Context HttpServletRequest request) { Uploader upload = new ImageUploader(); @@ -383,321 +146,32 @@ public Uploader uploadImage(@Context HttpServletRequest request) { upload.setSecurityEnabled(Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED))); return upload; } - - //////////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////////// - ////////////////////////////// START SEARCH BAR /////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////////// - - /** - * Complete user search based on string input - * @return - */ + @GET - @Path("central/context/getAutoCompleteResults") - @Produces("application/json") - public StreamingOutput getAutoCompleteResults(@QueryParam("completeTerm") String searchString, @Context HttpServletRequest request) { - List searchResults = null; - boolean securityEnabled = Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED)); - if(securityEnabled) { - HttpSession session = request.getSession(false); - User user = (User) session.getAttribute(Constants.SESSION_USER); - searchResults = SecurityQueryUtils.predictUserInsightSearch(user, searchString, "15", "0"); - } else { - searchResults = SecurityQueryUtils.predictInsightSearch(searchString, "15", "0"); - } - return WebUtility.getSO(searchResults); - } - - /** - * Search based on a string input - * @param form - information passes in from the front end - * @return a string version of the results attained from the query search - */ - /** - * Search based on a string input - * @param form - information passes in from the front end - * @return a string version of the results attained from the query search - */ - @POST - @Path("central/context/getSearchInsightsResults") + @Path("playsheets") @Produces("application/json") - public StreamingOutput getSearchInsightsResults(MultivaluedMap form, @Context HttpServletRequest request) { - // text searched in search bar - String searchString = form.getFirst("searchString"); - logger.info("Searching based on input: " + searchString); - - // offset for call - String offset = form.getFirst("offset"); - logger.info("Offset is: " + offset); - - // offset for call - String limit = form.getFirst("limit"); - logger.info("Limit is: " + limit); + public StreamingOutput getPlaySheets(@Context HttpServletRequest request) { + Hashtable hashTable = new Hashtable(); - // If security is enabled, remove the engines in the filters that aren't - // accessible - if none in filters, add all accessible engines to filter - // list - boolean securityEnabled = Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED)); - List> queryResults = null; - if (securityEnabled) { - // filter insights based on what the user has access to - HttpSession session = request.getSession(false); - User user = ((User) session.getAttribute(Constants.SESSION_USER)); - queryResults = SecurityQueryUtils.searchUserInsightDataByName(user, searchString, limit, offset); - } else { - queryResults = SecurityQueryUtils.searchAllInsightDataByName(searchString, limit, offset); + List sheetNames = PlaySheetRDFMapBasedEnum.getAllSheetNames(); + for (int i = 0; i < sheetNames.size(); i++) { + hashTable.put(sheetNames.get(i), PlaySheetRDFMapBasedEnum.getClassFromName(sheetNames.get(i))); } + return WebUtility.getSO(hashTable); + } - return WebUtility.getSO(queryResults); + @Path("/dbAdmin") + public Object modifyInsight(@Context HttpServletRequest request) { + DBAdminResource questionAdmin = new DBAdminResource(); + questionAdmin.setSecurityEnabled(Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED))); + return questionAdmin; } - - //////////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////////// - /////////////////////////////// END SEARCH BAR //////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////////////////// - - @POST - @Path("central/context/getConnectedConcepts2") - @Produces("application/json") - public StreamingOutput getConnectedConcepts(MultivaluedMap form, @Context HttpServletRequest request) { - Gson gson = new Gson(); - List conceptLogicalNames = gson.fromJson(form.getFirst("conceptURI"), new TypeToken>() {}.getType()); - if(conceptLogicalNames == null || conceptLogicalNames.isEmpty()) { - return WebUtility.getSO(""); - } - return WebUtility.getSO(MasterDatabaseUtility.getConnectedConceptsRDBMS(conceptLogicalNames, null)); - } - - @POST - @Path("central/context/conceptProperties") - @Produces("application/json") - public Response getConceptProperties(MultivaluedMap form, @Context HttpServletRequest request) - { - Gson gson = new Gson(); - List conceptLogicalNames = gson.fromJson(form.getFirst("conceptURI"), new TypeToken>() {}.getType()); - if(conceptLogicalNames == null || conceptLogicalNames.isEmpty()) { -// return Response.status(200).entity(WebUtility.getSO("")).build(); - return WebUtility.getResponse("", 200); - } -// return Response.status(200).entity(WebUtility.getSO(DatabasePkqlService.getConceptProperties(conceptLogicalNames, null))).build(); - return WebUtility.getResponse(MasterDatabaseUtility.getConceptPropertiesRDBMS(conceptLogicalNames, null), 200); - } - - @POST - @Path("central/context/conceptLogicals") - @Produces("application/json") - public Response getAllLogicalNamesFromConceptual(MultivaluedMap form, @Context HttpServletRequest request) - { - Gson gson = new Gson(); - List conceptualName = gson.fromJson(form.getFirst("conceptURI"), new TypeToken>() {}.getType()); - if(conceptualName == null || conceptualName.isEmpty()) { -// return Response.status(200).entity(WebUtility.getSO("")).build(); - return WebUtility.getResponse("", 200); - } - int size = conceptualName.size(); - -// List parentConceptualName = gson.fromJson(form.getFirst("parentConcept"), new TypeToken>() {}.getType()); -// if(parentConceptualName != null) { -// // TODO: yell at FE -// // ugh, FE, why do you send parent as the string "undefined" -// // ugh, BE, how to tell FE that the prim key that is generated for metamodel view is fake -// List cleanParentConceptualName = new Vector(); -// for(int i = 0; i < size; i++) { -// String val = parentConceptualName.get(i); -// if(val == null) { -// cleanParentConceptualName.add(null); -// } else if(val.equals("undefined") || val.startsWith(TinkerFrame.PRIM_KEY) || val.isEmpty()) { -// cleanParentConceptualName.add(null); -// } else { -// cleanParentConceptualName.add(val); -// } -// } -// -// // override reference to parent conceptual name -// // can just keep it as null when we pass back the info to the FE -// parentConceptualName = cleanParentConceptualName; -// } -// return Response.status(200).entity(WebUtility.getSO(DatabasePkqlService.getAllLogicalNamesFromConceptual(conceptualName, parentConceptualName))).build(); - return WebUtility.getResponse(MasterDatabaseUtility.getAllLogicalNamesFromConceptualRDBMS(conceptualName, null), 200); - } - - @GET - @Path("central/context/metamodel") - @Produces("application/json") - public Response getMetamodel(@Context HttpServletRequest request, @QueryParam("engineName") String engineName) { - if(engineName == null || engineName.isEmpty()) { -// return Response.status(200).entity(WebUtility.getSO("")).build(); - return WebUtility.getResponse("", 200); - } - - - Map ret = new HashMap(); - if(Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED))) { - User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); - HashMap> metamodelFilter = new HashMap>(); - if(permissions.getMetamodelSeedsForUser(userId).get(engineName) != null) { - metamodelFilter = permissions.getMetamodelSeedsForUser(userId).get(engineName); - } - - //ret = MasterDatabaseUtility.getMetamodelSecure(engineName, metamodelFilter); - } else { - ret = MasterDatabaseUtility.getMetamodelRDBMS(engineName); - } - -// return Response.status(200).entity(WebUtility.getSO(ret)).build(); - return WebUtility.getResponse(ret, 200); - } - -// // get all insights related to a specific uri -// // preferably we would also pass vert store and edge store... the more -// // context the better. Don't have any of that for now though. -// @POST -// @Path("central/context/insights") -// @Produces("application/json") -// public Response getCentralContextInsights(MultivaluedMap form, @Context HttpServletRequest request) throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException, SolrServerException, IOException { -//// Gson gson = new Gson(); -//// ArrayList selectedUris; -//// try { -//// selectedUris = gson.fromJson(form.getFirst("selectedURI"), ArrayList.class); -//// } catch (ClassCastException e) { -//// Map errorHash = new HashMap(); -//// errorHash.put("errorMessage", "Can only run related insights on concepts and properties!"); -//// return Response.status(400).entity(WebUtility.getSO(errorHash)).build(); -//// } -//// -//// // TODO: need to change the format for this call!!!!!!!!!! -//// String type = Utility.getClassName(selectedUris.get(0)); -//// if (type == null) { -//// // this occurs when a column is artificially created in a query -//// type = selectedUris.get(0); -//// } -//// -//// SolrIndexEngineQueryBuilder queryBuilder = new SolrIndexEngineQueryBuilder(); -//// queryBuilder.setSearchString(type); -//// //TODO: should the params be different for this than the default search? -//// //TODO: need to test this out more -//// queryBuilder.setDefaultDisMaxWeighting(); -//// // facet still requires a df -//// queryBuilder.setDefaultSearchField(SolrIndexEngine.INDEX_NAME); -//// -//// List facetList = new ArrayList<>(); -//// facetList.add(SolrIndexEngine.APP_ID); -//// facetList.add(SolrIndexEngine.LAYOUT); -//// facetList.add(SolrIndexEngine.TAGS); -//// queryBuilder.setFacetField(facetList); -//// -//// // offset for call -//// String offset = form.getFirst("offset"); -//// logger.info("Offset is: " + offset); -//// -//// // offset for call -//// String limit = form.getFirst("limit"); -//// logger.info("Limit is: " + limit); -//// -//// Integer offsetInt = null; -//// Integer limitInt = null; -//// if (offset != null && !offset.isEmpty()) { -//// offsetInt = Integer.parseInt(offset); -//// queryBuilder.setOffset(offsetInt); -//// } -//// if (limit != null && !limit.isEmpty()) { -//// limitInt = Integer.parseInt(limit); -//// queryBuilder.setLimit(limitInt); -//// } -//// -//// // filter based on the boxes checked in the facet filter (filtered with an exact filter) -//// String filterDataStr = form.getFirst("filterData"); -//// Gson gsonVar = new Gson(); -//// Map> filterData = gsonVar.fromJson(filterDataStr, new TypeToken>>() {}.getType()); -//// if (filterData != null && !filterData.isEmpty()) { -//// queryBuilder.setFilterOptions(filterData); -//// } -//// -//// // always sort by score and name desc -//// queryBuilder.setSort(SolrIndexEngine.SCORE, SolrIndexEngine.DESC); -//// queryBuilder.setSort(SolrIndexEngine.STORAGE_NAME, SolrIndexEngine.ASC); -//// -//// SolrDocumentList results = SolrIndexEngine.getInstance().queryDocument(queryBuilder); -//// // throw an error if there are no results -//// if (results == null) { -//// Map errorHash = new HashMap(); -//// errorHash.put("errorMessage", "No related insights found!"); -////// return Response.status(400).entity(WebUtility.getSO(errorHash)).build(); -//// return WebUtility.getResponse(errorHash, 400); -//// } -//// // query for facet results -//// Map> facetCount = SolrIndexEngine.getInstance().executeQueryFacetResults(type, facetList, SOLR_PATHS.SOLR_INSIGHTS_PATH); -//// -//// Map retMap = new HashMap(); -//// retMap.put(SolrIndexEngine.NUM_FOUND, results.getNumFound()); -//// retMap.put("results", results); -//// retMap.put("facet", facetCount); -////// return Response.status(200).entity(WebUtility.getSO(retMap)).build(); -//// return WebUtility.getResponse(retMap, 200); -// return null; -// } - - private StreamingOutput getSOHTML() { - return new StreamingOutput() { - public void write(OutputStream outputStream) throws IOException, WebApplicationException { - PrintStream out = new PrintStream(outputStream); - try { - // java.io.PrintWriter out = response.getWriter(); - out.println(""); - out.println(""); - out.println("Servlet upload"); - out.println(""); - out.println(""); - - Enumeration keys = helpHash.keys(); - while (keys.hasMoreElements()) { - String key = keys.nextElement(); - String value = (String) helpHash.get(key); - out.println("" + key + ""); - out.println("" + value + ""); - out.println("
"); - } - - out.println(""); - out.println(""); - } catch (Exception e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - }; - } - - @GET - @Path("playsheets") - @Produces("application/json") - public StreamingOutput getPlaySheets(@Context HttpServletRequest request) { - Hashtable hashTable = new Hashtable(); - - List sheetNames = PlaySheetRDFMapBasedEnum.getAllSheetNames(); - for (int i = 0; i < sheetNames.size(); i++) { - hashTable.put(sheetNames.get(i), PlaySheetRDFMapBasedEnum.getClassFromName(sheetNames.get(i))); - } - return WebUtility.getSO(hashTable); - } - - @Path("/dbAdmin") - public Object modifyInsight(@Context HttpServletRequest request) { - DBAdminResource questionAdmin = new DBAdminResource(); - questionAdmin.setSecurityEnabled(Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED))); - return questionAdmin; - } - - @Path("i-{insightID}") - public Object getInsightDataFrame(@PathParam("insightID") String insightID, @QueryParam("dataFrameType") String dataFrameType, @Context HttpServletRequest request) { - // eventually I want to pick this from session - // but for now let us pick it from the insight store - System.out.println("Came into this point.. " + insightID); + @Path("i-{insightID}") + public Object getInsightDataFrame(@PathParam("insightID") String insightID, @QueryParam("dataFrameType") String dataFrameType, @Context HttpServletRequest request) { + // eventually I want to pick this from session + // but for now let us pick it from the insight store + System.out.println("Came into this point.. " + insightID); Insight existingInsight = null; if (insightID != null && !insightID.isEmpty() && !insightID.startsWith("new")) { @@ -705,43 +179,43 @@ public Object getInsightDataFrame(@PathParam("insightID") String insightID, @Que if (existingInsight == null) { Map errorHash = new HashMap(); errorHash.put("errorMessage", "Existing insight based on passed insightID is not found"); -// return Response.status(400).entity(WebUtility.getSO(errorHash)).build(); + // return Response.status(400).entity(WebUtility.getSO(errorHash)).build(); return WebUtility.getResponse(errorHash, 400); } -// else if(!existingInsight.hasInstantiatedDataMaker()) { -// synchronized(existingInsight) { -// if(!existingInsight.hasInstantiatedDataMaker()) { -//// IDataMaker dm = null; -//// // check if the insight is from a csv -//// if(!existingInsight.isDbInsight()) { -//// // it better end up being created here since it must be serialized as a tinker -//// InsightCache inCache = CacheFactory.getInsightCache(CacheFactory.CACHE_TYPE.CSV_CACHE); -//// dm = inCache.getDMCache(existingInsight); -//// DataMakerComponent dmc = new DataMakerComponent(inCache.getDMFilePath(existingInsight)); -//// -//// Vector dmcList = new Vector(); -//// dmcList.add(dmc); -//// existingInsight.setDataMakerComponents(dmcList); -//// } else { -// // otherwise, grab the serialization if it is there -// IDataMaker dm = CacheFactory.getInsightCache(CacheFactory.CACHE_TYPE.DB_INSIGHT_CACHE).getDMCache(existingInsight); -//// } -// -// if(dm != null) { -// // this means the serialization was good and pushing it into the insight object -// existingInsight.setDataMaker(dm); -// } else { -//// this means the serialization has never occurred -//// could be because hasn't happened, or could be because it is not a tinker frame -// InsightCreateRunner run = new InsightCreateRunner(existingInsight); -// Map webData = run.runWeb(); -// // try to serialize -// // this will do nothing if not a tinker frame -// CacheFactory.getInsightCache(CacheFactory.CACHE_TYPE.DB_INSIGHT_CACHE).cacheInsight(existingInsight, webData); -// } -// } -// } -// } + // else if(!existingInsight.hasInstantiatedDataMaker()) { + // synchronized(existingInsight) { + // if(!existingInsight.hasInstantiatedDataMaker()) { + //// IDataMaker dm = null; + //// // check if the insight is from a csv + //// if(!existingInsight.isDbInsight()) { + //// // it better end up being created here since it must be serialized as a tinker + //// InsightCache inCache = CacheFactory.getInsightCache(CacheFactory.CACHE_TYPE.CSV_CACHE); + //// dm = inCache.getDMCache(existingInsight); + //// DataMakerComponent dmc = new DataMakerComponent(inCache.getDMFilePath(existingInsight)); + //// + //// Vector dmcList = new Vector(); + //// dmcList.add(dmc); + //// existingInsight.setDataMakerComponents(dmcList); + //// } else { + // // otherwise, grab the serialization if it is there + // IDataMaker dm = CacheFactory.getInsightCache(CacheFactory.CACHE_TYPE.DB_INSIGHT_CACHE).getDMCache(existingInsight); + //// } + // + // if(dm != null) { + // // this means the serialization was good and pushing it into the insight object + // existingInsight.setDataMaker(dm); + // } else { + //// this means the serialization has never occurred + //// could be because hasn't happened, or could be because it is not a tinker frame + // InsightCreateRunner run = new InsightCreateRunner(existingInsight); + // Map webData = run.runWeb(); + // // try to serialize + // // this will do nothing if not a tinker frame + // CacheFactory.getInsightCache(CacheFactory.CACHE_TYPE.DB_INSIGHT_CACHE).cacheInsight(existingInsight, webData); + // } + // } + // } + // } } else if(insightID.equals("new")) { @@ -749,58 +223,30 @@ else if(insightID.equals("new")) if(dataFrameType == null) { dataFrameType = "H2Frame"; } -// existingInsight = new Insight(null, dataFrameType, "Grid"); + // existingInsight = new Insight(null, dataFrameType, "Grid"); existingInsight = new Insight(); // set the user id into the insight existingInsight.setUser( ((User) request.getSession().getAttribute(Constants.SESSION_USER)) ); InsightStore.getInstance().put(existingInsight); } -// else if(insightID.equals("newDashboard")) { -// // get the data frame type and set it from the FE -//// existingInsight = new Insight(null, "Dashboard", "Dashboard"); -// existingInsight = new Insight(); -// // set the user id into the insight -// existingInsight.setUserId( ((User) request.getSession().getAttribute(Constants.SESSION_USER)).getId() ); -// Dashboard dashboard = new Dashboard(); -// existingInsight.setDataMaker(dashboard); -// String insightid = InsightStore.getInstance().put(existingInsight); -// dashboard.setInsightID(insightid); -// } - + // else if(insightID.equals("newDashboard")) { + // // get the data frame type and set it from the FE + //// existingInsight = new Insight(null, "Dashboard", "Dashboard"); + // existingInsight = new Insight(); + // // set the user id into the insight + // existingInsight.setUserId( ((User) request.getSession().getAttribute(Constants.SESSION_USER)).getId() ); + // Dashboard dashboard = new Dashboard(); + // existingInsight.setDataMaker(dashboard); + // String insightid = InsightStore.getInstance().put(existingInsight); + // dashboard.setInsightID(insightid); + // } + DataframeResource dfr = new DataframeResource(); dfr.insight = existingInsight; return dfr; } - @POST - @Path("runPkql") - @Produces("application/json") - public StreamingOutput runPkql(MultivaluedMap form ) { - /* - * This is only used for calls that do not require us to hold state - * pkql that run in here should not touch a data farme - */ - String expression = form.getFirst("expression"); - PKQLRunner runner = new PKQLRunner(); - runner.runPKQL(expression); - - Map resultHash = new HashMap(); - - // this is technically the only piece of information the FE needs - // but to keep the return consistent for them - // i am sending back the information in the same weird ordering - Map pkqlDataHash = new HashMap(); - pkqlDataHash.put("pkqlData", runner.getResults()); - - Object[] insightArr = new Object[1]; - insightArr[0] = pkqlDataHash; - - resultHash.put("insights", insightArr); - - return WebUtility.getSO(resultHash); - } - @GET @Path("/downloadFile") @Produces(MediaType.APPLICATION_OCTET_STREAM) @@ -815,7 +261,7 @@ public Response downloadFile(@QueryParam("insightId") String insightId, @QueryPa errorMap.put("errorMessage", "Could not find the insight id"); return WebUtility.getResponse(errorMap, 400); } - + String filePath = insight.getExportFileLocation(fileKey); File exportFile = new File(filePath); if(!exportFile.exists()) { @@ -823,22 +269,22 @@ public Response downloadFile(@QueryParam("insightId") String insightId, @QueryPa errorMap.put("errorMessage", "Could not find the file for given file id"); return WebUtility.getResponse(errorMap, 400); } - + Date date = new Date(); String modifiedDate = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_SSSS").format(date); String exportName = "SEMOSS_Export_" + modifiedDate + "." + FilenameUtils.getExtension(filePath); - + return Response.status(200).entity(exportFile).header("Content-Disposition", "attachment; filename=" + exportName).build(); } - + /////////////////////////////////////////////// /////////////////////////////////////////////// /////////////////////////////////////////////// - + /* * TODO: move FE to use app resource calls */ - + @GET @Path("/appImage") @Produces("image/*") @@ -846,7 +292,7 @@ public Response getAppImage(@Context HttpServletRequest request, @QueryParam("ap AppResource r = new AppResource(); return r.downloadAppImage(request, app); } - + @GET @Path("/insightImage") @Produces("image/*") @@ -854,12 +300,12 @@ public Response getInsightImage(@Context HttpServletRequest request, @QueryParam AppResource r = new AppResource(); return r.downloadInsightImage(request, app, insightId, params); } - + /////////////////////////////////////////////// /////////////////////////////////////////////// /////////////////////////////////////////////// - + @POST @Path("/runPixel") @Produces("application/json") @@ -869,11 +315,11 @@ public Response runPixelSync(MultivaluedMap form, @Context HttpS // create a thread // set the insight and pixels into the thread // and then let it lose - + // I need a couple of different statistics for this user and panel // is user (initially I had he, but then diversity) listening for stdout / stderr or both // what is the level of log the user wants and the panel wants - + // other than that - // there is a jobID status Hash - this can eventually be zookeeper // Then there is a jobID to message if the user has turned on the stdout, then it has a stack of messages @@ -882,7 +328,7 @@ public Response runPixelSync(MultivaluedMap form, @Context HttpS HttpSession session; String sessionId; User user; - + boolean securityEnabled = Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED)); //If security is enabled try to get an existing session. //Otherwise get a session with the default user. @@ -902,14 +348,14 @@ public Response runPixelSync(MultivaluedMap form, @Context HttpS user = ((User) session.getAttribute(Constants.SESSION_USER)); sessionId = session.getId(); } - + String jobId = ""; final String tempInsightId = "TempInsightNotStored"; - + String insightId = form.getFirst("insightId"); String expression = form.getFirst("expression"); Insight insight = null; - + // figure out the type of insight // first is temp if(insightId == null || insightId.toString().isEmpty() || insightId.equals("undefined")) { @@ -935,12 +381,12 @@ public Response runPixelSync(MultivaluedMap form, @Context HttpS } // make sure we have the correct session trying to get this id // #soMuchSecurity -// Set sessionStore = InsightStore.getInstance().getInsightIDsForSession(sessionId); -// if(sessionStore == null || !sessionStore.contains(insightId)) { -// Map errorMap = new HashMap(); -// errorMap.put("errorMessage", "Trying to access insight id from incorrect session"); -// return WebUtility.getResponse(errorMap, 400); -// } + // Set sessionStore = InsightStore.getInstance().getInsightIDsForSession(sessionId); + // if(sessionStore == null || !sessionStore.contains(insightId)) { + // Map errorMap = new HashMap(); + // errorMap.put("errorMessage", "Trying to access insight id from incorrect session"); + // return WebUtility.getResponse(errorMap, 400); + // } } synchronized(insight) { // set the user @@ -966,7 +412,7 @@ public Response runPixelSync(MultivaluedMap form, @Context HttpS return Response.status(200).entity(PixelStreamUtility.collectPixelData(pixelRunner)).build(); } } - + @POST @Path("runPixelAsync") @Produces("application/json") @@ -981,14 +427,14 @@ public Response runPixelAsync(MultivaluedMap form, @Context Http session = request.getSession(true); } String sessionId = session.getId(); - + String jobId = ""; Map dataReturn = new HashMap(); - + String insightId = form.getFirst("insightId"); String expression = form.getFirst("expression"); Insight insight = null; - + // figure out the type of insight // first is temp if(insightId == null || insightId.toString().isEmpty() || insightId.equals("undefined")) { @@ -1009,12 +455,12 @@ public Response runPixelAsync(MultivaluedMap form, @Context Http } // make sure we have the correct session trying to get this id // #soMuchSecurity -// Set sessionStore = InsightStore.getInstance().getInsightIDsForSession(sessionId); -// if(sessionStore == null || !sessionStore.contains(insightId)) { -// Map errorMap = new HashMap(); -// errorMap.put("errorMessage", "Trying to access insight id from incorrect session"); -// return WebUtility.getResponse(errorMap, 400); -// } + // Set sessionStore = InsightStore.getInstance().getInsightIDsForSession(sessionId); + // if(sessionStore == null || !sessionStore.contains(insightId)) { + // Map errorMap = new HashMap(); + // errorMap.put("errorMessage", "Trying to access insight id from incorrect session"); + // return WebUtility.getResponse(errorMap, 400); + // } } if(insight != null) { @@ -1026,7 +472,7 @@ public Response runPixelAsync(MultivaluedMap form, @Context Http session.setAttribute(jobId+"", "TRUE"); String job = "META | Job(\"" + jobId + "\", \"" + insightId + "\", \"" + sessionId + "\");"; expression = job + expression; - + jt.setInsight(insight); jt.addPixel(expression); jt.start(); @@ -1035,7 +481,7 @@ public Response runPixelAsync(MultivaluedMap form, @Context Http } return WebUtility.getResponse(dataReturn, 200); } - + // get result of the operation @POST @Path("/result") @@ -1049,7 +495,7 @@ public StreamingOutput result(MultivaluedMap form, @Context Http } return WebUtility.getSO(dataReturn); } - + // is the status of the operation // get result of the operation @POST @@ -1072,23 +518,23 @@ public StreamingOutput status(MultivaluedMap form, @Context Http public StreamingOutput console(MultivaluedMap form, @Context HttpServletRequest request) { Object dataReturn = "NULL"; String jobId = form.getFirst("jobId"); -// HttpSession session = request.getSession(true); -// if(session.getAttribute(jobId) != null) { - dataReturn = JobManager.getManager().getStdOut(jobId); -// } + // HttpSession session = request.getSession(true); + // if(session.getAttribute(jobId) != null) { + dataReturn = JobManager.getManager().getStdOut(jobId); + // } return WebUtility.getSO(dataReturn); } - + @POST @Path("/error") @Produces("application/json") public StreamingOutput error(MultivaluedMap form, @Context HttpServletRequest request) { Object dataReturn = "NULL"; String jobId = form.getFirst("jobId"); -// HttpSession session = request.getSession(true); -// if(session.getAttribute(jobId) != null) { - dataReturn = JobManager.getManager().getError(jobId); -// } + // HttpSession session = request.getSession(true); + // if(session.getAttribute(jobId) != null) { + dataReturn = JobManager.getManager().getError(jobId); + // } return WebUtility.getSO(dataReturn); } @@ -1098,27 +544,102 @@ public StreamingOutput error(MultivaluedMap form, @Context HttpS @Produces("application/json") public StreamingOutput terminate(MultivaluedMap form, @Context HttpServletRequest request) { String jobId = form.getFirst("jobId"); -// HttpSession session = request.getSession(true); -// if(session.getAttribute(jobId) != null) { - JobManager.getManager().flushJob(jobId); -// } -// session.removeAttribute(jobId); + // HttpSession session = request.getSession(true); + // if(session.getAttribute(jobId) != null) { + JobManager.getManager().flushJob(jobId); + // } + // session.removeAttribute(jobId); return WebUtility.getSO("success"); } - - + + // reset job @POST @Path("/reset") @Produces("application/json") public StreamingOutput reset(MultivaluedMap form, @Context HttpServletRequest request) { String jobId = form.getFirst("jobId"); -// HttpSession session = request.getSession(true); -// if(session.getAttribute(jobId) != null) { - JobManager.getManager().resetJob(jobId); -// } + // HttpSession session = request.getSession(true); + // if(session.getAttribute(jobId) != null) { + JobManager.getManager().resetJob(jobId); + // } return WebUtility.getSO("success"); } + + @GET + @Path("/comet") + @Produces("text/plain") + public String cometTry(@Context HttpServletRequest request) { + // I need to create a job id + // then I need to start the thread with this job id + // I need to keep the response in the response hash with this job id.. so when I have + SemossExecutorSingleton threader = SemossExecutorSingleton.getInstance(); + SemossThread newThread = new SemossThread(); + //newThread.setResponse(response); + String jId = threader.execute(newThread); + //ResponseHashSingleton.setResponse(jId, response); + ResponseHashSingleton.setThread(jId, newThread); + //request.getSession(true).setAttribute("JOB_ID", jId); + return jId; // store this in session so the user doesn't need to provide this + } + + @GET + @Path("/joutput") + @Produces("text/plain") + public String getJobOutput(@QueryParam("jobId") String jobId, @Context HttpServletRequest request){ + + String output = "Job Longer Available"; + AsyncResponse myResponse = (AsyncResponse)ResponseHashSingleton.getResponseforJobId(jobId); + // if(ResponseHashSingleton.getThread(jobId) != null) + // { + // SemossThread thread = (SemossThread)ResponseHashSingleton.getThread(jobId); + // output = thread.getOutput() + ""; + // } + if(myResponse != null ) { + System.out.println("Respons Done ? " + myResponse.isDone()); + System.out.println("Respons suspended ? " + myResponse.isSuspended()); + System.out.println("Is the response done.. ? " + myResponse.isDone()); + myResponse.resume("Hello2222"); + myResponse.resume("Hola again"); + System.out.println("MyResponse is not null"); + } + + return output; + } + + @GET + @Path("/jkill") + @Produces("application/xml") + public void killJob(@QueryParam("jobId") String jobId, @Context HttpServletRequest request){ + //AsyncResponse myResponse = (AsyncResponse)ResponseHashSingleton.getResponseforJobId(jobId); + SemossThread thread = (SemossThread)ResponseHashSingleton.getThread(jobId); + thread.setComplete(true); + ResponseHashSingleton.removeThread(jobId); + + /* if(myResponse != null ) { + System.out.println("Respons Done ? " + myResponse.isDone()); + System.out.println("Respons suspended ? " + myResponse.isSuspended()); + System.out.println("Is the response done.. ? " + myResponse.isDone()); + myResponse.resume("Hello2222"); + myResponse.resume("Hola again"); + System.out.println("MyResponse is not null"); + } + */ + //return thread.getOutput() + ""; + } + + /////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////// + + + /* + * Legacy code that isn't really used anymore + * + * + */ /** * Executes search on MediaWiki/Wikipedia for a given search term and returns the top results. @@ -1133,7 +654,7 @@ public StreamingOutput getMediaWikiTagsForSearchTerm(@QueryParam("searchTerm") S String MEDAWIKI_ENDPOINT = "https://en.wikipedia.org/w/api.php?action=query&srlimit=" + numResults + "&list=search&format=json&utf8=1&srprop=snippet&srsearch="; String PRODUCT_ONTOLOGY_PREFIX = "http://www.productontology.org/id/"; StringMap ret = new StringMap(); - + if(searchTerm != null && !searchTerm.isEmpty()) { try { CloseableHttpClient httpClient = null; @@ -1142,7 +663,7 @@ public StreamingOutput getMediaWikiTagsForSearchTerm(@QueryParam("searchTerm") S httpClient = HttpClients.createDefault(); HttpGet http = new HttpGet(MEDAWIKI_ENDPOINT + URLEncoder.encode(searchTerm)); response = httpClient.execute(http); - + HttpEntity entity = response.getEntity(); if (entity != null) { InputStream is = entity.getContent(); @@ -1151,7 +672,7 @@ public StreamingOutput getMediaWikiTagsForSearchTerm(@QueryParam("searchTerm") S Gson gson = new Gson(); HashMap>>> k = gson.fromJson(resp, HashMap.class);; List> mapsList = (List>)k.get("query").get("search"); - + for(StringMap s : mapsList) { ret.put(PRODUCT_ONTOLOGY_PREFIX + s.get("title"), Jsoup.parse(s.get("snippet")).text()); } @@ -1167,78 +688,374 @@ public StreamingOutput getMediaWikiTagsForSearchTerm(@QueryParam("searchTerm") S e.printStackTrace(); } } - + return WebUtility.getSO(ret); } - @GET - @Path("/comet") - @Produces("text/plain") - public String cometTry(@Context HttpServletRequest request) { - // I need to create a job id - // then I need to start the thread with this job id - // I need to keep the response in the response hash with this job id.. so when I have - SemossExecutorSingleton threader = SemossExecutorSingleton.getInstance(); - SemossThread newThread = new SemossThread(); - //newThread.setResponse(response); - String jId = threader.execute(newThread); - //ResponseHashSingleton.setResponse(jId, response); - ResponseHashSingleton.setThread(jId, newThread); - //request.getSession(true).setAttribute("JOB_ID", jId); - return jId; // store this in session so the user doesn't need to provide this - } - - @GET - @Path("/joutput") - @Produces("text/plain") - public String getJobOutput(@QueryParam("jobId") String jobId, @Context HttpServletRequest request){ - - String output = "Job Longer Available"; - AsyncResponse myResponse = (AsyncResponse)ResponseHashSingleton.getResponseforJobId(jobId); -// if(ResponseHashSingleton.getThread(jobId) != null) -// { -// SemossThread thread = (SemossThread)ResponseHashSingleton.getThread(jobId); -// output = thread.getOutput() + ""; -// } - if(myResponse != null ) { - System.out.println("Respons Done ? " + myResponse.isDone()); - System.out.println("Respons suspended ? " + myResponse.isSuspended()); - System.out.println("Is the response done.. ? " + myResponse.isDone()); - myResponse.resume("Hello2222"); - myResponse.resume("Hola again"); - System.out.println("MyResponse is not null"); - } - - return output; - } + + + // gets the engine resource necessary for all engine calls + @Path("e-{engine}") + public Object getLocalDatabase(@Context HttpServletRequest request, @PathParam("engine") String engineId, @QueryParam("api") String api) throws IOException { + Object securityObj = DIHelper.getInstance().getLocalProp(Constants.SECURITY_ENABLED); + boolean security = (securityObj instanceof Boolean && ((boolean) securityObj) ) || (Boolean.parseBoolean(securityObj.toString())); - @GET - @Path("/jkill") - @Produces("application/xml") - public void killJob(@QueryParam("jobId") String jobId, @Context HttpServletRequest request){ - - //AsyncResponse myResponse = (AsyncResponse)ResponseHashSingleton.getResponseforJobId(jobId); - SemossThread thread = (SemossThread)ResponseHashSingleton.getThread(jobId); - thread.setComplete(true); - ResponseHashSingleton.removeThread(jobId); - -/* if(myResponse != null ) { - System.out.println("Respons Done ? " + myResponse.isDone()); - System.out.println("Respons suspended ? " + myResponse.isSuspended()); - System.out.println("Is the response done.. ? " + myResponse.isDone()); - myResponse.resume("Hello2222"); - myResponse.resume("Hola again"); - System.out.println("MyResponse is not null"); - } -*/ - //return thread.getOutput() + ""; + if(security) { + HttpSession session = request.getSession(false); + if(session == null) { + return WebUtility.getSO("Not properly authenticated"); + } + User user = (User) session.getAttribute(Constants.SESSION_USER); + if(user == null) { + return WebUtility.getSO("Not properly authenticated"); + } + engineId = SecurityQueryUtils.testUserEngineIdForAlias(user, engineId); + if(!SecurityQueryUtils.getUserEngineIds(user).contains(engineId)) { + Map errorMap = new HashMap(); + errorMap.put("errorMessage", "Database " + engineId + " does not exist or user does not have access to database"); + return WebUtility.getResponse(errorMap, 400); + } + } else { + engineId = MasterDatabaseUtility.testEngineIdIfAlias(engineId); + if(!MasterDatabaseUtility.getAllEngineIds().contains(engineId)) { + Map errorMap = new HashMap(); + errorMap.put("errorMessage", "Database " + engineId + " does not exist"); + return WebUtility.getResponse(errorMap, 400); + } } - @GET - @Path("/sessionTimeout") - @Produces("application/json") - public Response getTimeoutValue(@Context HttpServletRequest request) { - return WebUtility.getResponse((double) request.getSession().getMaxInactiveInterval() / 60, 200); - } - + IEngine engine = Utility.getEngine(engineId); + EngineResource res = new EngineResource(); + res.setEngine(engine); + return res; + } + @Path("s-{engine}") + public Object getEngineProxy(@PathParam("engine") String db, @Context HttpServletRequest request) { + // this is the name server + // this needs to return stuff + System.out.println(" Getting DB... " + db); + HttpSession session = request.getSession(); + IEngine engine = (IEngine) session.getAttribute(db); + EngineRemoteResource res = new EngineRemoteResource(); + res.setEngine(engine); + return res; + } + + // Controls all calls controlling the central name server + @Path("centralNameServer") + public Object getCentralNameServer(@QueryParam("centralServerUrl") String url, + @Context HttpServletRequest request) { + // this is the name server + // this needs to return stuff + System.out.println(" Going to central name server ... " + url); + CentralNameServer cns = new CentralNameServer(); + cns.setCentralApi(url); + return cns; + } + + /** + * Get the basic information of all engines from solr. + * @param request + * @return all engines. + */ + @GET + @Path("all") + @Produces("application/json") + public StreamingOutput printEngines(@Context HttpServletRequest request) { + Object securityObj = DIHelper.getInstance().getLocalProp(Constants.SECURITY_ENABLED); + boolean security = (securityObj instanceof Boolean && ((boolean) securityObj) ) || (Boolean.parseBoolean(securityObj.toString())); + + List> engines = null; + if(security) { + HttpSession session = request.getSession(false); + if(session == null) { + return WebUtility.getSO("Not properly authenticated"); + } + User user = (User) session.getAttribute(Constants.SESSION_USER); + if(user == null) { + return WebUtility.getSO("Not properly authenticated"); + } + engines = SecurityQueryUtils.getUserDatabaseList(user); + } else { + engines = SecurityQueryUtils.getAllDatabaseList(); + } + + return WebUtility.getSO(engines); + } + + @GET + @Path("add") + @Produces("application/json") + public void addEngine(@Context HttpServletRequest request, @QueryParam("api") String api, @QueryParam("database") String database) { + // would be cool to give this as an HTML + RemoteSemossSesameEngine newEngine = new RemoteSemossSesameEngine(); + newEngine.setAPI(api); + newEngine.setDatabase(database); + HttpSession session = request.getSession(); + ArrayList> engines = (ArrayList>) session.getAttribute(Constants.ENGINES); + // temporal + String remoteDbKey = api + ":" + database; + newEngine.openDB(null); + if (newEngine.isConnected()) { + Hashtable engineHash = new Hashtable(); + engineHash.put("name", database); + engineHash.put("api", api); + engines.add(engineHash); + session.setAttribute(Constants.ENGINES, engines); + session.setAttribute(remoteDbKey, newEngine); + DIHelper.getInstance().setLocalProperty(remoteDbKey, newEngine); + } + } + + @GET + @Path("help") + @Produces("text/html") + public StreamingOutput printURL(@Context HttpServletRequest request, @Context HttpServletResponse response) { + Hashtable helpHash = null; + // would be cool to give this as an HTML + if (helpHash == null) { + Hashtable urls = new Hashtable(); + urls.put("Help - this menu (GET)", "hostname:portname/Monolith/api/engine/help"); + urls.put("Get All the engines (GET)", "hostname:portname/Monolith/api/engine/all"); + urls.put("Perspectives in a specific engine (GET)", + "hostname:portname/Monolith/api/engine/e-{engineName}/perspectives"); + urls.put("All Insights in a engine (GET)", "hostname:portname/Monolith/api/engine/e-{engineName}/insights"); + urls.put("All Perspectives and Insights in a engine (GET)", + "hostname:portname/Monolith/api/engine/e-{engineName}/pinsights"); + urls.put("Insights for specific perspective specific engine (GET)", + "hostname:portname/Monolith/api/engine/e-{engineName}/insights?perspective={perspective}"); + urls.put("Insight definition for a particular insight (GET)", + "hostname:portname/Monolith/api/engine/e-{engineName}/insight?insight={label of insight (NOT ID)}"); + urls.put("Execute insight without parameter (GET)", + "hostname:portname/Monolith/api/engine/e-{engineName}/output?insight={label of insight (NOT ID)}"); + urls.put("Execute insight with parameter (GET)", + "hostname:portname/Monolith/api/engine/e-{engineName}/output?insight={label of insight (NOT ID)}¶ms=key$value~key2$value2~key3$value3"); + urls.put("Execute Custom Query Select (POST)", + "hostname:portname/Monolith/api/engine/e-{engineName}/querys?query={sparql query}"); + urls.put("Execute Custom Query Construct (GET)", + "hostname:portname/Monolith/api/engine/e-{engineName}/queryc?query={sparql query}"); + urls.put("Execute Custom Query Insert/Delete (POST)", + "hostname:portname/Monolith/api/engine/e-{engineName}/update?query={sparql query}"); + urls.put("Numeric properties of a given node type (GET)", + "hostname:portname/Monolith/api/engine/e-{engineName}/properties/node/type/numeric?nodeType={URI}"); + urls.put("Fill Values for a given parameter (You already get this in insights) (GET)", + "hostname:portname/Monolith/api/engine/e-{engineName}/fill?type={type}"); + urls.put("Get Neighbors of a particular node (GET)", + "hostname:portname/Monolith/api/engine/e-{engineName}/neighbors/instance?node={URI}"); + urls.put("Tags for an insight (Specific Engine)", + "hostname:portname/Monolith/api/engine/e-{engineName}/tags?insight={insight label}"); + urls.put("Insights for a given tag (Tag is optional) (Specific Engine) ", + "hostname:portname/Monolith/api/engine/e-{engineName}/insight?tag={xyz}"); + urls.put("Neighbors of across all engine", "hostname:portname/Monolith/api/engine/neighbors?node={URI}"); + urls.put("Tags for an insight", "hostname:portname/Monolith/api/engine/tags?insight={insight label}"); + urls.put("Insights for a given tag (Tag is optional)", + "hostname:portname/Monolith/api/engine/insight?tag={xyz}"); + urls.put("Create a new engine using excel (requires form submission) (POST)", + "hostname:portname/Monolith/api/engine/insight/upload/excel/upload"); + urls.put("Create a new engine using csv (requires form submission) (POST)", + "hostname:portname/Monolith/api/engine/insight/upload/csv/upload"); + urls.put("Create a new engine using nlp (requires form submission) (POST)", + "hostname:portname/Monolith/api/engine/insight/upload/nlp/upload (GET)"); + helpHash = urls; + } + return getSOHTML(helpHash); + } + + private StreamingOutput getSOHTML(Hashtable helpHash) { + return new StreamingOutput() { + public void write(OutputStream outputStream) throws IOException, WebApplicationException { + PrintStream out = new PrintStream(outputStream); + try { + // java.io.PrintWriter out = response.getWriter(); + out.println(""); + out.println(""); + out.println("Servlet upload"); + out.println(""); + out.println(""); + + Enumeration keys = helpHash.keys(); + while (keys.hasMoreElements()) { + String key = keys.nextElement(); + String value = (String) helpHash.get(key); + out.println("" + key + ""); + out.println("" + value + ""); + out.println("
"); + } + + out.println(""); + out.println(""); + } catch (Exception e) { + e.printStackTrace(); + } + } + }; + } + + @POST + @Path("runPkql") + @Produces("application/json") + @Deprecated + public StreamingOutput runPkql(MultivaluedMap form ) { + /* + * This is only used for calls that do not require us to hold state + * pkql that run in here should not touch a data farme + */ + String expression = form.getFirst("expression"); + PKQLRunner runner = new PKQLRunner(); + runner.runPKQL(expression); + + Map resultHash = new HashMap(); + + // this is technically the only piece of information the FE needs + // but to keep the return consistent for them + // i am sending back the information in the same weird ordering + Map pkqlDataHash = new HashMap(); + pkqlDataHash.put("pkqlData", runner.getResults()); + + Object[] insightArr = new Object[1]; + insightArr[0] = pkqlDataHash; + + resultHash.put("insights", insightArr); + + return WebUtility.getSO(resultHash); + } + + + + + //////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////// START SEARCH BAR /////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////////// + + /** + * Complete user search based on string input + * @return + */ + @GET + @Path("central/context/getAutoCompleteResults") + @Produces("application/json") + public StreamingOutput getAutoCompleteResults(@QueryParam("completeTerm") String searchString, @Context HttpServletRequest request) { + List searchResults = null; + boolean securityEnabled = Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED)); + if(securityEnabled) { + HttpSession session = request.getSession(false); + User user = (User) session.getAttribute(Constants.SESSION_USER); + searchResults = SecurityQueryUtils.predictUserInsightSearch(user, searchString, "15", "0"); + } else { + searchResults = SecurityQueryUtils.predictInsightSearch(searchString, "15", "0"); + } + return WebUtility.getSO(searchResults); + } + + /** + * Search based on a string input + * @param form - information passes in from the front end + * @return a string version of the results attained from the query search + */ + /** + * Search based on a string input + * @param form - information passes in from the front end + * @return a string version of the results attained from the query search + */ + @POST + @Path("central/context/getSearchInsightsResults") + @Produces("application/json") + public StreamingOutput getSearchInsightsResults(MultivaluedMap form, @Context HttpServletRequest request) { + // text searched in search bar + String searchString = form.getFirst("searchString"); + // offset for call + String offset = form.getFirst("offset"); + // offset for call + String limit = form.getFirst("limit"); + + // If security is enabled, remove the engines in the filters that aren't + // accessible - if none in filters, add all accessible engines to filter + // list + boolean securityEnabled = Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED)); + List> queryResults = null; + if (securityEnabled) { + // filter insights based on what the user has access to + HttpSession session = request.getSession(false); + User user = ((User) session.getAttribute(Constants.SESSION_USER)); + queryResults = SecurityQueryUtils.searchUserInsightDataByName(user, searchString, limit, offset); + } else { + queryResults = SecurityQueryUtils.searchAllInsightDataByName(searchString, limit, offset); + } + + return WebUtility.getSO(queryResults); + } + + + //////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////// END SEARCH BAR //////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////////////////////// + + @POST + @Path("central/context/getConnectedConcepts2") + @Produces("application/json") + public StreamingOutput getConnectedConcepts(MultivaluedMap form, @Context HttpServletRequest request) { + Gson gson = new Gson(); + List conceptLogicalNames = gson.fromJson(form.getFirst("conceptURI"), new TypeToken>() {}.getType()); + if(conceptLogicalNames == null || conceptLogicalNames.isEmpty()) { + return WebUtility.getSO(""); + } + return WebUtility.getSO(MasterDatabaseUtility.getConnectedConceptsRDBMS(conceptLogicalNames, null)); + } + + @POST + @Path("central/context/conceptProperties") + @Produces("application/json") + public Response getConceptProperties(MultivaluedMap form, @Context HttpServletRequest request) + { + Gson gson = new Gson(); + List conceptLogicalNames = gson.fromJson(form.getFirst("conceptURI"), new TypeToken>() {}.getType()); + if(conceptLogicalNames == null || conceptLogicalNames.isEmpty()) { + // return Response.status(200).entity(WebUtility.getSO("")).build(); + return WebUtility.getResponse("", 200); + } + // return Response.status(200).entity(WebUtility.getSO(DatabasePkqlService.getConceptProperties(conceptLogicalNames, null))).build(); + return WebUtility.getResponse(MasterDatabaseUtility.getConceptPropertiesRDBMS(conceptLogicalNames, null), 200); + } + + @POST + @Path("central/context/conceptLogicals") + @Produces("application/json") + public Response getAllLogicalNamesFromConceptual(MultivaluedMap form, @Context HttpServletRequest request) + { + Gson gson = new Gson(); + List conceptualName = gson.fromJson(form.getFirst("conceptURI"), new TypeToken>() {}.getType()); + if(conceptualName == null || conceptualName.isEmpty()) { + // return Response.status(200).entity(WebUtility.getSO("")).build(); + return WebUtility.getResponse("", 200); + } + int size = conceptualName.size(); + + // List parentConceptualName = gson.fromJson(form.getFirst("parentConcept"), new TypeToken>() {}.getType()); + // if(parentConceptualName != null) { + // // TODO: yell at FE + // // ugh, FE, why do you send parent as the string "undefined" + // // ugh, BE, how to tell FE that the prim key that is generated for metamodel view is fake + // List cleanParentConceptualName = new Vector(); + // for(int i = 0; i < size; i++) { + // String val = parentConceptualName.get(i); + // if(val == null) { + // cleanParentConceptualName.add(null); + // } else if(val.equals("undefined") || val.startsWith(TinkerFrame.PRIM_KEY) || val.isEmpty()) { + // cleanParentConceptualName.add(null); + // } else { + // cleanParentConceptualName.add(val); + // } + // } + // + // // override reference to parent conceptual name + // // can just keep it as null when we pass back the info to the FE + // parentConceptualName = cleanParentConceptualName; + // } + // return Response.status(200).entity(WebUtility.getSO(DatabasePkqlService.getAllLogicalNamesFromConceptual(conceptualName, parentConceptualName))).build(); + return WebUtility.getResponse(MasterDatabaseUtility.getAllLogicalNamesFromConceptualRDBMS(conceptualName, null), 200); + } } diff --git a/src/prerna/semoss/web/services/UserResource.java b/src/prerna/semoss/web/services/UserResource.java index 281c74e05..1441507ec 100644 --- a/src/prerna/semoss/web/services/UserResource.java +++ b/src/prerna/semoss/web/services/UserResource.java @@ -288,14 +288,16 @@ private void addAccessToken(AccessToken token, HttpServletRequest request) { } else { semossUser = new User(); if(twitToken != null) { - semossUser.setAccessToken(twitToken); + semossUser.setGlobalAccessToken(twitToken); } if(googAppToken != null) { - semossUser.setAccessToken(googAppToken); + semossUser.setGlobalAccessToken(googAppToken); } } semossUser.setAccessToken(token); request.getSession().setAttribute(Constants.SESSION_USER, semossUser); + // add new users into the database + SecurityUpdateUtils.addOAuthUser(token); } /** @@ -848,6 +850,7 @@ public Response loginGoogle(@Context HttpServletRequest request, @Context HttpSe params.put("client_secret", clientSecret); String url = "https://www.googleapis.com/oauth2/v4/token"; + AccessToken accessToken = AbstractHttpHelper.getAccessToken(url, params, true, true); if(accessToken == null) { // not authenticated @@ -859,11 +862,15 @@ public Response loginGoogle(@Context HttpServletRequest request, @Context HttpSe // Shows how to make a google credential from an access token System.out.println("Access Token is.. " + accessToken.getAccess_token()); accessToken.setProvider(AuthProvider.GOOGLE); + + // fill the access token with the other properties so we can properly create the user + GoogleProfile.fillAccessToken(accessToken, null); addAccessToken(accessToken, request); // this is just for testing... // but i will get yelled at if i remove it so here it is... - performGoogleOps(request, ret); + // TODO: adding this todo to easily locate it +// performGoogleOps(request, ret); } else { ret.put("success", true); ret.put("Already_Authenticated", true); @@ -1287,17 +1294,8 @@ public Response authentication(@Context HttpServletRequest request) { AccessToken authToken = new AccessToken(); authToken.setProvider(AuthProvider.NATIVE); authToken.setId(id); - authToken.setName(username); - User newUser = new User(); - newUser.setAccessToken(authToken); - //If there's another session destroy it. - HttpSession session = request.getSession(false); - if(session != null){ - request.getSession().invalidate(); - } - //Create a new session and add an User object to it. - session = request.getSession(true); - session.setAttribute(Constants.SESSION_USER, newUser); + authToken.setName(username); + addAccessToken(authToken, request); //User print = (User) session.getAttribute(Constants.SESSION_USER); //LOGGER.info("Logging in with: " + print); @@ -1326,7 +1324,8 @@ public Response logoutNative(@Context HttpServletRequest request) throws IOExcep HttpSession session = request.getSession(false); User print = (User) session.getAttribute(Constants.SESSION_USER); //LOGGER.info("Logging out with: " + print); - request.getSession().invalidate(); + print.dropAccessToken(AuthProvider.NATIVE.name().toUpperCase()); + request.getSession().setAttribute(Constants.SESSION_USER, print); } else { ret.put("error", "User is not connected."); return WebUtility.getResponse(ret, 401); @@ -1397,7 +1396,7 @@ public Response setUserRegistration(@Context HttpServletRequest request) throws Hashtable errorRet = new Hashtable(); try { User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - String userId = user.getAccessToken(AuthProvider.NATIVE).getId(); + String userId = user.getAccessToken(user.getLogins().get(0)).getId(); if(SecurityQueryUtils.isUserAdmin(userId)){ String user_reg = request.getParameter("user_reg"); PropertiesConfiguration config = new PropertiesConfiguration(DIHelper.getInstance().getProperty("SOCIAL")); @@ -1420,4 +1419,24 @@ public Response setUserRegistration(@Context HttpServletRequest request) throws return WebUtility.getResponse(true, 200); } + @GET + @Produces("application/json") + @Path("/loginProperties/") + public Response loginProperties(@Context HttpServletRequest request) throws IOException { + boolean nativeLogin = Boolean.parseBoolean(socialData.getProperty("native_login")); + boolean githubLogin = Boolean.parseBoolean(socialData.getProperty("github_login")); + boolean googleLogin = Boolean.parseBoolean(socialData.getProperty("google_login")); + boolean onedriveLogin = Boolean.parseBoolean(socialData.getProperty("onedrive_login")); + boolean dropboxLogin = Boolean.parseBoolean(socialData.getProperty("dropbox_login")); + boolean cacLogin = Boolean.parseBoolean(socialData.getProperty("cac_login")); + Map logins = new HashMap<>(); + logins.put("native", nativeLogin); + logins.put("google", googleLogin); + logins.put("github", githubLogin); + logins.put("onedrive", onedriveLogin); + logins.put("dropbox", dropboxLogin); + logins.put("cac", cacLogin); + return WebUtility.getResponse(logins, 200); + } + } From 768deb457a17615f927c55bd75b4374f4bb4a382 Mon Sep 17 00:00:00 2001 From: rramirezjimenez Date: Thu, 23 Aug 2018 19:25:37 +0000 Subject: [PATCH 0182/1906] BUGFIX ::: Upload csv metamodel with no relationships git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29721 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 11ece7b3030813dc8ae433530c9beb7e7192dafd --- src/prerna/upload/DatabaseUploader.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/prerna/upload/DatabaseUploader.java b/src/prerna/upload/DatabaseUploader.java index 7836740b8..e7d9ff8ae 100644 --- a/src/prerna/upload/DatabaseUploader.java +++ b/src/prerna/upload/DatabaseUploader.java @@ -975,12 +975,14 @@ private List> createNewMetamodel(ImportOptions options) { String[] relations = relationStr.split(";"); ArrayList> relationships = new ArrayList<>(); for (String relStr : relations) { - String[] rel = relStr.split("@"); - HashMap relMap = new HashMap<>(); - relMap.put(Constants.FROM_TABLE, rel[0]); - relMap.put(Constants.REL_NAME, rel[1]); - relMap.put(Constants.TO_TABLE, rel[2]); - relationships.add(relMap); + if (relStr.contains("@")) { + String[] rel = relStr.split("@"); + HashMap relMap = new HashMap<>(); + relMap.put(Constants.FROM_TABLE, rel[0]); + relMap.put(Constants.REL_NAME, rel[1]); + relMap.put(Constants.TO_TABLE, rel[2]); + relationships.add(relMap); + } } newMetamodel.put(Constants.RELATION, relationships); String nodePropStr = mm.get("NODE_PROP"); From 4a2b45c68ebcf27fac0d3d8051e224f6dcc7ecb9 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 27 Aug 2018 15:03:47 +0000 Subject: [PATCH 0183/1906] UPDATE ::: Adding context destroyed to close connections and insights to prevent memory leaks git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29734 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 7f5e2c56bc0e21ce447f3f31c2b2b1e8ade927fd --- src/prerna/web/conf/DBLoader.java | 63 +++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/src/prerna/web/conf/DBLoader.java b/src/prerna/web/conf/DBLoader.java index ffceaf021..44bc205f4 100644 --- a/src/prerna/web/conf/DBLoader.java +++ b/src/prerna/web/conf/DBLoader.java @@ -27,17 +27,31 @@ *******************************************************************************/ package prerna.web.conf; +import static org.quartz.impl.StdSchedulerFactory.getDefaultScheduler; + +import java.util.List; +import java.util.Set; + import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import org.apache.log4j.PropertyConfigurator; +import org.quartz.Scheduler; +import org.quartz.SchedulerException; import com.ibm.icu.util.StringTokenizer; +import prerna.engine.api.IEngine; +import prerna.forms.AbstractFormBuilder; +import prerna.nameserver.utility.MasterDatabaseUtility; +import prerna.om.Insight; +import prerna.om.InsightStore; import prerna.sablecc2.reactor.frame.r.util.RJavaTranslatorFactory; import prerna.util.AbstractFileWatcher; import prerna.util.Constants; import prerna.util.DIHelper; +import prerna.util.Utility; +import prerna.util.insight.InsightUtility; public class DBLoader implements ServletContextListener { @@ -112,6 +126,55 @@ public void loadEngines() { @Override public void contextDestroyed(ServletContextEvent arg0) { + System.out.println("Start shutdown"); + + Set insights = InsightStore.getInstance().getAllInsights(); + for(String id : insights) { + Insight in = InsightStore.getInstance().get(id); + System.out.println("Closing insight " + id); + InsightUtility.dropInsight(in); + } + // we need to close all the engine ids + List eIds = MasterDatabaseUtility.getAllEngineIds(); + for(String id : eIds) { + // grab only loaded engines + IEngine engine = (IEngine) DIHelper.getInstance().getLocalProp(id); + if(engine != null) { + // if it is loaded, close it + System.out.println("Closing database " + id); + engine.closeDB(); + } + } + + // these are not loaded in the normal fashion + // so specifically pull them to close + IEngine engine = Utility.getEngine(AbstractFormBuilder.FORM_BUILDER_ENGINE_NAME); + if(engine != null) { + System.out.println("Closing database " + AbstractFormBuilder.FORM_BUILDER_ENGINE_NAME); + engine.closeDB(); + } + engine = Utility.getEngine(Constants.SECURITY_DB); + if(engine != null) { + System.out.println("Closing database " + Constants.SECURITY_DB); + engine.closeDB(); + } + engine = Utility.getEngine(Constants.LOCAL_MASTER_DB_NAME); + if(engine != null) { + System.out.println("Closing database " + Constants.LOCAL_MASTER_DB_NAME); + engine.closeDB(); + } + + try { + Scheduler scheduler = getDefaultScheduler(); + if(scheduler != null) { + System.out.println("Closing scheduler"); + scheduler.clear(); + } + } catch (SchedulerException e) { + e.printStackTrace(); + } + System.out.println("Finished shutdown"); + } } From f06f9e1ab147e44e59f18fd856d387bb550fbc9c Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 27 Aug 2018 18:28:05 +0000 Subject: [PATCH 0184/1906] UPDATE ::: Adding logic to properly close connections/threads on shutdown git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29737 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 1e3ae1af46276ab5f24c35c6ffe776df3e7fff0e --- src/prerna/web/conf/DBLoader.java | 32 ++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/src/prerna/web/conf/DBLoader.java b/src/prerna/web/conf/DBLoader.java index 44bc205f4..55f5cae80 100644 --- a/src/prerna/web/conf/DBLoader.java +++ b/src/prerna/web/conf/DBLoader.java @@ -31,6 +31,7 @@ import java.util.List; import java.util.Set; +import java.util.Vector; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; @@ -55,8 +56,11 @@ public class DBLoader implements ServletContextListener { - public static final String RDFMAP = "RDF-MAP"; - + private static final String RDFMAP = "RDF-MAP"; + + // keep track of all the watcher threads to kill + private static List watcherList = new Vector(); + @Override public void contextInitialized(ServletContextEvent arg0) { System.out.println("Initializing application context..." + arg0.getServletContext().getContextPath()); @@ -117,6 +121,7 @@ public void loadEngines() { { Thread thread = new Thread(watcherInstance); thread.start(); + watcherList.add(watcherInstance); } } } catch (Exception ex) { @@ -134,6 +139,12 @@ public void contextDestroyed(ServletContextEvent arg0) { System.out.println("Closing insight " + id); InsightUtility.dropInsight(in); } + + // close watchers + for(AbstractFileWatcher watcher : watcherList) { + watcher.shutdown(); + } + // we need to close all the engine ids List eIds = MasterDatabaseUtility.getAllEngineIds(); for(String id : eIds) { @@ -152,18 +163,27 @@ public void contextDestroyed(ServletContextEvent arg0) { if(engine != null) { System.out.println("Closing database " + AbstractFormBuilder.FORM_BUILDER_ENGINE_NAME); engine.closeDB(); + } else { + System.out.println("Couldn't find database " + AbstractFormBuilder.FORM_BUILDER_ENGINE_NAME); } + engine = Utility.getEngine(Constants.SECURITY_DB); if(engine != null) { System.out.println("Closing database " + Constants.SECURITY_DB); engine.closeDB(); + } else { + System.out.println("Couldn't find database " + Constants.SECURITY_DB); } + engine = Utility.getEngine(Constants.LOCAL_MASTER_DB_NAME); if(engine != null) { System.out.println("Closing database " + Constants.LOCAL_MASTER_DB_NAME); engine.closeDB(); + } else { + System.out.println("Couldn't find database " + Constants.LOCAL_MASTER_DB_NAME); } + // close scheduler try { Scheduler scheduler = getDefaultScheduler(); if(scheduler != null) { @@ -174,7 +194,13 @@ public void contextDestroyed(ServletContextEvent arg0) { e.printStackTrace(); } + // close r + try { + RJavaTranslatorFactory.stopRConnection(); + } catch(Exception e) { + e.printStackTrace(); + } + System.out.println("Finished shutdown"); - } } From 1d7840c63de6be223c1cef71b84db51389445a8f Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 28 Aug 2018 22:09:14 +0000 Subject: [PATCH 0185/1906] BUGFIX ::: Adding better security block for runpixel method call UPDATE ::: Using utility method for shutting down schedule server git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29752 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 366ce37ca3bb4cbc5ab419923881cb4c5565a2e8 --- src/prerna/semoss/web/services/NameServer.java | 10 ++++++---- src/prerna/web/conf/DBLoader.java | 11 +++-------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/prerna/semoss/web/services/NameServer.java b/src/prerna/semoss/web/services/NameServer.java index 7da2f7b57..78ce3ffe0 100644 --- a/src/prerna/semoss/web/services/NameServer.java +++ b/src/prerna/semoss/web/services/NameServer.java @@ -325,9 +325,9 @@ public Response runPixelSync(MultivaluedMap form, @Context HttpS // Then there is a jobID to message if the user has turned on the stdout, then it has a stack of messages // once the job is done, the stack is also cleared - HttpSession session; - String sessionId; - User user; + HttpSession session = null; + String sessionId = null; + User user = null; boolean securityEnabled = Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED)); //If security is enabled try to get an existing session. @@ -337,7 +337,9 @@ public Response runPixelSync(MultivaluedMap form, @Context HttpS if(session != null){ sessionId = session.getId(); user = ((User) session.getAttribute(Constants.SESSION_USER)); - } else { + } + + if(user == null) { Map errorMap = new HashMap(); errorMap.put("error", "User session is invalid"); System.out.println("User session is invalid"); diff --git a/src/prerna/web/conf/DBLoader.java b/src/prerna/web/conf/DBLoader.java index 55f5cae80..7412d1138 100644 --- a/src/prerna/web/conf/DBLoader.java +++ b/src/prerna/web/conf/DBLoader.java @@ -27,8 +27,6 @@ *******************************************************************************/ package prerna.web.conf; -import static org.quartz.impl.StdSchedulerFactory.getDefaultScheduler; - import java.util.List; import java.util.Set; import java.util.Vector; @@ -37,7 +35,6 @@ import javax.servlet.ServletContextListener; import org.apache.log4j.PropertyConfigurator; -import org.quartz.Scheduler; import org.quartz.SchedulerException; import com.ibm.icu.util.StringTokenizer; @@ -47,6 +44,7 @@ import prerna.nameserver.utility.MasterDatabaseUtility; import prerna.om.Insight; import prerna.om.InsightStore; +import prerna.rpa.quartz.SchedulerUtil; import prerna.sablecc2.reactor.frame.r.util.RJavaTranslatorFactory; import prerna.util.AbstractFileWatcher; import prerna.util.Constants; @@ -185,11 +183,8 @@ public void contextDestroyed(ServletContextEvent arg0) { // close scheduler try { - Scheduler scheduler = getDefaultScheduler(); - if(scheduler != null) { - System.out.println("Closing scheduler"); - scheduler.clear(); - } + System.out.println("Closing scheduler"); + SchedulerUtil.shutdownScheduler(true); } catch (SchedulerException e) { e.printStackTrace(); } From da1c2c2efee5692b94fcf5a743eccebf80002fc2 Mon Sep 17 00:00:00 2001 From: kunalppatel9 Date: Wed, 29 Aug 2018 18:10:43 +0000 Subject: [PATCH 0186/1906] BUGFIX ::: Exception/Error in runImageCapture kills the rest, preventing stock image pulls git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29776 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: aedff65df40c7ca50a18a61c63cbafebad371ed0 --- src/prerna/semoss/web/services/AppResource.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/prerna/semoss/web/services/AppResource.java b/src/prerna/semoss/web/services/AppResource.java index 5bc18dbc1..9086fd01e 100644 --- a/src/prerna/semoss/web/services/AppResource.java +++ b/src/prerna/semoss/web/services/AppResource.java @@ -135,7 +135,15 @@ private File getInsightImageFile(String app, String id, String feUrl, String par } else { // try making the image if(feUrl != null) { + try { ImageCaptureReactor.runImageCapture(feUrl, appId, id, params, sessionId); + } + catch(Exception | NoSuchMethodError er) { + //Image Capture will not run. No image exists nor will be made. The exception kills the rest. + // return stock image + f = AbstractSecurityUtils.getStockImage(appId, id); + return f; + } } if(f.exists()) { return f; From 6f8091be96770f2c99d550d460b2afb15f673c93 Mon Sep 17 00:00:00 2001 From: kunalppatel9 Date: Wed, 29 Aug 2018 21:11:42 +0000 Subject: [PATCH 0187/1906] BUGFIX ::: Exception/Error in runImageCapture - adding stackTrack git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29784 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 6d4f3172f7d97450c8a8ef5c6fe3b263bb8d13ae --- src/prerna/semoss/web/services/AppResource.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/prerna/semoss/web/services/AppResource.java b/src/prerna/semoss/web/services/AppResource.java index 9086fd01e..3ddf15e63 100644 --- a/src/prerna/semoss/web/services/AppResource.java +++ b/src/prerna/semoss/web/services/AppResource.java @@ -141,6 +141,7 @@ private File getInsightImageFile(String app, String id, String feUrl, String par catch(Exception | NoSuchMethodError er) { //Image Capture will not run. No image exists nor will be made. The exception kills the rest. // return stock image + er.printStackTrace(); f = AbstractSecurityUtils.getStockImage(appId, id); return f; } From 5633fe041ff2cc5c1cfb59d1882bd555c085cb27 Mon Sep 17 00:00:00 2001 From: rramirezjimenez Date: Wed, 29 Aug 2018 21:24:29 +0000 Subject: [PATCH 0188/1906] UPDATE ::: Sending upload db metadata for csv git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29786 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 0b54b4df0f95203d620914d72b5a69d9f8c156c7 --- src/prerna/upload/DatabaseUploader.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/prerna/upload/DatabaseUploader.java b/src/prerna/upload/DatabaseUploader.java index e7d9ff8ae..1fea46d96 100644 --- a/src/prerna/upload/DatabaseUploader.java +++ b/src/prerna/upload/DatabaseUploader.java @@ -61,6 +61,7 @@ import prerna.sablecc2.reactor.IReactor; import prerna.sablecc2.reactor.PixelPlanner; import prerna.sablecc2.reactor.app.upload.UploadInputUtility; +import prerna.sablecc2.reactor.app.upload.UploadUtilities; import prerna.sablecc2.reactor.app.upload.gremlin.TinkerCsvUploadReactor; import prerna.sablecc2.reactor.app.upload.rdbms.csv.RdbmsCsvUploadReactor; import prerna.sablecc2.reactor.app.upload.rdbms.csv.RdbmsExternalUploadReactor; @@ -687,8 +688,9 @@ public Response uploadCSVFile(MultivaluedMap form, @Context Http return Response.status(400).entity(gson.toJson(errorHash)).build(); } - String outputText = "CSV Loading was a success."; - return Response.status(200).entity(gson.toJson(outputText)).build(); + String appId = options.getEngineID(); + Map retMap = UploadUtilities.getAppReturnData(appId); + return Response.status(200).entity(gson.toJson(retMap)).build(); } // @POST @@ -871,7 +873,8 @@ private String reactorImport(ImportOptions options, HttpServletRequest request) NounMetadata response = reactor.execute(); if (i == 0) { // need to keep app id to override - appId = (String) response.getValue(); + Map retMap = (Map) response.getValue(); + appId = retMap.get("app_id"); } reactor = getImportReactor(options); } @@ -927,7 +930,8 @@ private String reactorImport(ImportOptions options, HttpServletRequest request) NounMetadata response = reactor.execute(); if (i == 0) { // need to keep app id to override - appId = (String) response.getValue(); + Map retMap = (Map) response.getValue(); + appId = retMap.get("app_id"); } reactor = getImportReactor(options); } From b6ae3bd4a53ebd342b09c57f0aebbc8f99ab4ae2 Mon Sep 17 00:00:00 2001 From: rramirezjimenez Date: Wed, 29 Aug 2018 21:43:47 +0000 Subject: [PATCH 0189/1906] UPDATE ::: Sending app meta data from security utils git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29788 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 1a5d19dce4fe6c5c8fd920637710ec042b5c9f1f --- src/prerna/upload/DatabaseUploader.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/prerna/upload/DatabaseUploader.java b/src/prerna/upload/DatabaseUploader.java index 1fea46d96..efdea8310 100644 --- a/src/prerna/upload/DatabaseUploader.java +++ b/src/prerna/upload/DatabaseUploader.java @@ -689,7 +689,8 @@ public Response uploadCSVFile(MultivaluedMap form, @Context Http } String appId = options.getEngineID(); - Map retMap = UploadUtilities.getAppReturnData(appId); + User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); + Map retMap = UploadUtilities.getAppReturnData(user, appId); return Response.status(200).entity(gson.toJson(retMap)).build(); } From fc7e5f4d1bac29669d6875d61fa30cf3af334a28 Mon Sep 17 00:00:00 2001 From: rramirezjimenez Date: Wed, 29 Aug 2018 22:13:21 +0000 Subject: [PATCH 0190/1906] UPDATE ::: Sending app upload metadata for excel git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29789 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 50841a85aa17bce81cef21c084cab13ff417b5d1 --- src/prerna/upload/DatabaseUploader.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/prerna/upload/DatabaseUploader.java b/src/prerna/upload/DatabaseUploader.java index efdea8310..d81c85dc9 100644 --- a/src/prerna/upload/DatabaseUploader.java +++ b/src/prerna/upload/DatabaseUploader.java @@ -1280,8 +1280,10 @@ public Response processExcelFile(@Context HttpServletRequest request) return Response.status(400).entity(gson.toJson(errorHash)).build(); } - String outputText = "Excel Loading was a success."; - return Response.status(200).entity(gson.toJson(outputText)).build(); + String appId = options.getEngineID(); + User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); + Map retMap = UploadUtilities.getAppReturnData(user, appId); + return Response.status(200).entity(gson.toJson(retMap)).build(); } @POST @@ -1347,8 +1349,10 @@ public Response uploadExcelPOIFormat(@Context HttpServletRequest request) } } - String outputText = "Excel Loading was a success."; - return Response.status(200).entity(gson.toJson(outputText)).build(); + String appId = options.getEngineID(); + User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); + Map retMap = UploadUtilities.getAppReturnData(user, appId); + return Response.status(200).entity(gson.toJson(retMap)).build(); } // @POST From d0b4151a6e30dbfa361662bf672a65f20ca6550e Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 29 Aug 2018 22:46:44 +0000 Subject: [PATCH 0191/1906] UPDATE ::: Adding placeholder for no user filter git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29791 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 892e69c278ce6af4c29146020027b41373c5ff63 --- src/prerna/web/conf/NoUserFilter.java | 32 +++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 src/prerna/web/conf/NoUserFilter.java diff --git a/src/prerna/web/conf/NoUserFilter.java b/src/prerna/web/conf/NoUserFilter.java new file mode 100644 index 000000000..34c80d3d9 --- /dev/null +++ b/src/prerna/web/conf/NoUserFilter.java @@ -0,0 +1,32 @@ +package prerna.web.conf; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; + +public class NoUserFilter implements Filter { + + @Override + public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { + // TODO Auto-generated method stub + + } + + @Override + public void destroy() { + // TODO Auto-generated method stub + + } + + @Override + public void init(FilterConfig arg0) throws ServletException { + // TODO Auto-generated method stub + + } + +} From 095f32f320172f6d2e91b39fa586df718637b2cb Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 30 Aug 2018 14:24:11 +0000 Subject: [PATCH 0192/1906] UPDATE ::: Adding register user method for admins to add a user. TODO: need to add a completeRegistration method to fill in missing details when a user comes into the app to fill in the missing details git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29795 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 25f6a9f20febae2a3a58f4b71c7f044a0e4ed2f5 --- .../web/services/AuthorizationResource.java | 32 ++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/prerna/semoss/web/services/AuthorizationResource.java b/src/prerna/semoss/web/services/AuthorizationResource.java index 7d9af3235..fd949b250 100644 --- a/src/prerna/semoss/web/services/AuthorizationResource.java +++ b/src/prerna/semoss/web/services/AuthorizationResource.java @@ -565,7 +565,37 @@ public Response setDbPublic(@Context HttpServletRequest request, MultivaluedMap< } return WebUtility.getResponse(true, 200); } - + + @POST + @Produces("application/json") + @Path("/admin/registerUser") + public Response registerUser(@Context HttpServletRequest request, MultivaluedMap form) { + Hashtable errorRet = new Hashtable(); + boolean success = false; + try{ + User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); + String adminId = user.getAccessToken(user.getLogins().get(0)).getId(); + + String userId = form.getFirst("userId"); + Boolean adminUser = Boolean.parseBoolean(form.getFirst("admin")); + if(SecurityQueryUtils.isUserAdmin(adminId)){ + success = SecurityUpdateUtils.registerUser(userId, adminUser); + } else { + errorRet.put("error", "The user doesn't have the permissions to perform this action."); + return WebUtility.getResponse(errorRet, 400); + } + } catch (IllegalArgumentException e){ + e.printStackTrace(); + errorRet.put("error", e.getMessage()); + return WebUtility.getResponse(errorRet, 400); + } catch (Exception e){ + e.printStackTrace(); + errorRet.put("error", "An unexpected error happened. Please try again."); + return WebUtility.getResponse(errorRet, 500); + } + return WebUtility.getResponse(success, 200); + } + @POST @Produces("application/json") @Path("/admin/deleteUser") From 9c4d4b9dd401d84c0eb266885dbc4f68e82e646a Mon Sep 17 00:00:00 2001 From: pkapaleeswaran Date: Thu, 30 Aug 2018 15:02:27 +0000 Subject: [PATCH 0193/1906] Added the context destroyed event to delete the host manually from ZK. There is a latency in terms of when the server is killed and the publish to take out the node. This forces it. git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29802 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 0a30e6c111be13f94f73cfda585ffeeb1aad9298 --- src/prerna/web/conf/UserDBLoader.java | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/prerna/web/conf/UserDBLoader.java b/src/prerna/web/conf/UserDBLoader.java index 706259ef8..5d9a5ea9b 100644 --- a/src/prerna/web/conf/UserDBLoader.java +++ b/src/prerna/web/conf/UserDBLoader.java @@ -39,7 +39,8 @@ public class UserDBLoader implements ServletContextListener { @Override public void contextDestroyed(ServletContextEvent arg0) { // TODO Auto-generated method stub - + // unpublish + unpublish(); } @Override @@ -68,4 +69,25 @@ private void publish() // nothing to do proceed } + + private void unpublish() + { + Map envMap = System.getenv(); + + if(envMap.containsKey(ZKClient.ZK_SERVER) || envMap.containsKey(ZKClient.ZK_SERVER.toUpperCase())) + { + // we are in business + + ZKClient client = ZKClient.getInstance(); + client.zkClient = null; + client = ZKClient.getInstance(); + client.deleteDB(client.host); + } + // else + // nothing to do proceed + + } + + + } From 46db86a1203d9d1f472639c8fda2b72bdd0f65ba Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 31 Aug 2018 14:18:21 +0000 Subject: [PATCH 0194/1906] UPDATE ::: Modifying AZURE_GRAPH to be MS since the endpoint is using MS git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29823 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 65b1ec231d57c57895b2f052fefe4df3cebb98e4 --- src/prerna/semoss/web/services/UserResource.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/prerna/semoss/web/services/UserResource.java b/src/prerna/semoss/web/services/UserResource.java index 1441507ec..c05de6b43 100644 --- a/src/prerna/semoss/web/services/UserResource.java +++ b/src/prerna/semoss/web/services/UserResource.java @@ -363,7 +363,7 @@ public Response userinfoOneDrive(@Context HttpServletRequest request) { if(user == null) { ret.put("ERROR", "Log into your Microsoft account"); } else { - AccessToken msToken = user.getAccessToken(AuthProvider.AZURE_GRAPH); + AccessToken msToken = user.getAccessToken(AuthProvider.MS); accessString = msToken.getAccess_token(); String url = "https://graph.microsoft.com/v1.0/me/"; String output = AbstractHttpHelper.makeGetCall(url, accessString, null, true); @@ -657,7 +657,7 @@ public Response loginMS(@Context HttpServletRequest request, @Context HttpServle String queryString = request.getQueryString(); if(queryString != null && queryString.contains("code=")) { - if(userObj == null || ((User)userObj).getAccessToken(AuthProvider.AZURE_GRAPH) == null) { + if(userObj == null || ((User)userObj).getAccessToken(AuthProvider.MS) == null) { String [] outputs = AbstractHttpHelper.getCodes(queryString); String prefix = "ms_"; @@ -687,7 +687,7 @@ public Response loginMS(@Context HttpServletRequest request, @Context HttpServle return null; } - accessToken.setProvider(AuthProvider.AZURE_GRAPH); + accessToken.setProvider(AuthProvider.MS); addAccessToken(accessToken, request); System.out.println("Access Token is.. " + accessToken.getAccess_token()); @@ -699,13 +699,13 @@ public Response loginMS(@Context HttpServletRequest request, @Context HttpServle ret.put("Already_Authenticated", true); return WebUtility.getResponse(ret, 200); } - } else if(userObj == null || userObj.getAccessToken(AuthProvider.AZURE_GRAPH) == null) { + } else if(userObj == null || userObj.getAccessToken(AuthProvider.MS) == null) { // not authenticated response.setStatus(302); response.sendRedirect(getMSRedirect(request)); } // else if user object is there and ms is there - else if(userObj != null && userObj.getAccessToken(AuthProvider.AZURE_GRAPH) != null) { + else if(userObj != null && userObj.getAccessToken(AuthProvider.MS) != null) { ret.put("success", true); return WebUtility.getResponse(ret, 200); } From 7d00128b525bdcacfbe85f149f54ebb4dd05bfa6 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 31 Aug 2018 19:58:40 +0000 Subject: [PATCH 0195/1906] UPDATE ::: Pushing new structure for logins to also send back name to display git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29838 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 57c1264d88a640107ecf958101bc9cbfce735442 --- src/prerna/semoss/web/services/UserResource.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/prerna/semoss/web/services/UserResource.java b/src/prerna/semoss/web/services/UserResource.java index c05de6b43..9eb2bea18 100644 --- a/src/prerna/semoss/web/services/UserResource.java +++ b/src/prerna/semoss/web/services/UserResource.java @@ -245,14 +245,17 @@ private static void loginGoogleApp() { @GET @Path("logins") public Response getAllLogins(@Context HttpServletRequest request) { + Map retMap = new HashMap(); User semossUser = (User) request.getSession().getAttribute(Constants.SESSION_USER); - List logins = new ArrayList(); - if(semossUser != null) { - logins = semossUser.getLogins(); + if(semossUser == null) { + return WebUtility.getResponse(retMap, 200); } - Map> ret = new HashMap>(); - ret.put("logins", logins); - return WebUtility.getResponse(ret, 200); + List logins = semossUser.getLogins(); + for(AuthProvider p : logins) { + String name = semossUser.getAccessToken(p).getName(); + retMap.put(p.toString(), name); + } + return WebUtility.getResponse(retMap, 200); } @GET From 9c65acd5017fea0d0f3acb561e57f45e9574bdc7 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 31 Aug 2018 20:23:40 +0000 Subject: [PATCH 0196/1906] UPDATE ::: Pushing to upper case login names git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29839 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: bcae3c0b056153895b9d1fa15cc9248a51c19762 --- src/prerna/semoss/web/services/UserResource.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/prerna/semoss/web/services/UserResource.java b/src/prerna/semoss/web/services/UserResource.java index 9eb2bea18..cbe6c55b8 100644 --- a/src/prerna/semoss/web/services/UserResource.java +++ b/src/prerna/semoss/web/services/UserResource.java @@ -245,7 +245,7 @@ private static void loginGoogleApp() { @GET @Path("logins") public Response getAllLogins(@Context HttpServletRequest request) { - Map retMap = new HashMap(); + Map retMap = new HashMap(); User semossUser = (User) request.getSession().getAttribute(Constants.SESSION_USER); if(semossUser == null) { return WebUtility.getResponse(retMap, 200); @@ -253,7 +253,7 @@ public Response getAllLogins(@Context HttpServletRequest request) { List logins = semossUser.getLogins(); for(AuthProvider p : logins) { String name = semossUser.getAccessToken(p).getName(); - retMap.put(p.toString(), name); + retMap.put(p, name); } return WebUtility.getResponse(retMap, 200); } From 8d7cafa33bab536f36a517b96680f791d7b6f3fd Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 31 Aug 2018 20:59:03 +0000 Subject: [PATCH 0197/1906] UPDATE ::: Adding filled in NoUserFilter git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29840 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 14dffb48eec7c20938bdaa7917560f19f0d7a487 --- .../web/services/AdminConfigService.java | 18 +++++++++ src/prerna/web/conf/NoUserFilter.java | 39 ++++++++++++++++++- 2 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 src/prerna/semoss/web/services/AdminConfigService.java diff --git a/src/prerna/semoss/web/services/AdminConfigService.java b/src/prerna/semoss/web/services/AdminConfigService.java new file mode 100644 index 000000000..936c0efb0 --- /dev/null +++ b/src/prerna/semoss/web/services/AdminConfigService.java @@ -0,0 +1,18 @@ +package prerna.semoss.web.services; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.core.Response; + +import prerna.web.services.util.WebUtility; + +@Path("/adminConfig") +public class AdminConfigService { + + @GET + @Path("/alive") + public Response isAlive() { + return WebUtility.getResponse("Server is Up", 200); + } + +} diff --git a/src/prerna/web/conf/NoUserFilter.java b/src/prerna/web/conf/NoUserFilter.java index 34c80d3d9..2a815c5cc 100644 --- a/src/prerna/web/conf/NoUserFilter.java +++ b/src/prerna/web/conf/NoUserFilter.java @@ -8,13 +8,50 @@ import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import prerna.engine.api.IEngine; +import prerna.engine.api.IRawSelectWrapper; +import prerna.rdf.engine.wrappers.WrapperManager; +import prerna.util.Constants; +import prerna.util.Utility; public class NoUserFilter implements Filter { @Override public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { - // TODO Auto-generated method stub + boolean security = Boolean.parseBoolean(arg0.getServletContext().getInitParameter(Constants.SECURITY_ENABLED)); + if(security) { + IEngine engine = Utility.getEngine(Constants.SECURITY_DB); + String q = "SELECT * FROM USER LIMIT 1"; + IRawSelectWrapper wrapper = WrapperManager.getInstance().getRawWrapper(engine, q); + try { + boolean hasUser = wrapper.hasNext(); + if(!hasUser) { + ((HttpServletResponse) arg1).setStatus(302); + ((HttpServletResponse) arg1).sendRedirect("http://localhost:8080/MyHTML/index.html"); + return; + } + else if( ((HttpServletRequest) arg0).getSession(true).getAttribute("user") == null) { + ((HttpServletRequest) arg0).getSession(true).setAttribute("user", true); + ((HttpServletResponse) arg1).setStatus(302); + ((HttpServletResponse) arg1).sendRedirect("http://localhost:8080/SemossWeb_AppUi/#!/"); + return; + } else { + String requestUri = ((HttpServletRequest) arg0).getRequestURI(); + if(requestUri.equals("/Monolith_Dev/")) { + ((HttpServletRequest) arg0).getSession(true).setAttribute("user", true); + ((HttpServletResponse) arg1).setStatus(302); + ((HttpServletResponse) arg1).sendRedirect("http://localhost:8080/SemossWeb_AppUi/#!/"); + } + } + } finally { + wrapper.cleanUp(); + } + } + arg2.doFilter(arg0, arg1); } @Override From 930faaf013b18070e2caef6be0f9698d5bbe9ad4 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 4 Sep 2018 13:16:30 +0000 Subject: [PATCH 0198/1906] UPDATE ::: Admin configuration routing pushed and necessary filters pushed but currently commented out git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29844 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: e120a47e1a88f9088e92575ca90cc7f3d8bbf844 --- WebContent/WEB-INF/web.xml | 57 ++++++++++++++---- .../semoss/web/app/AdminApplication.java | 49 +++++++++++++++ .../semoss/web/app/MonolithApplication.java | 1 - .../web/services/AdminConfigService.java | 2 +- src/prerna/web/conf/AdminStartupFilter.java | 59 +++++++++++++++++++ 5 files changed, 156 insertions(+), 12 deletions(-) create mode 100644 src/prerna/semoss/web/app/AdminApplication.java create mode 100644 src/prerna/web/conf/AdminStartupFilter.java diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index 126123801..7836f6913 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -4,6 +4,26 @@ index.html + + + + + - Resteasy + MainApplication org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher javax.ws.rs.Application prerna.semoss.web.app.MonolithApplication + + resteasy.servlet.mapping.prefix + /api + + + + MainApplication + /api/* + + + AdminApplication + org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher + + javax.ws.rs.Application + prerna.semoss.web.app.AdminApplication + + + AdminApplication + /adminconfig/* + + + isLog4jAutoInitializationDisabled false - - resteasy.servlet.mapping.prefix - /api - - - Resteasy - /api/* - security-enabled - false + true Location to store uploaded file @@ -134,6 +170,7 @@ RDF-MAP C:\\workspace\\Semoss_Dev\\RDF_Map.prop + prerna.web.conf.DBLoader diff --git a/src/prerna/semoss/web/app/AdminApplication.java b/src/prerna/semoss/web/app/AdminApplication.java new file mode 100644 index 000000000..817a704d7 --- /dev/null +++ b/src/prerna/semoss/web/app/AdminApplication.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright 2015 Defense Health Agency (DHA) + * + * If your use of this software does not include any GPLv2 components: + * Licensed 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. + * ---------------------------------------------------------------------------- + * If your use of this software includes any GPLv2 components: + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + *******************************************************************************/ +package prerna.semoss.web.app; + +import java.util.HashSet; +import java.util.Set; + +import javax.ws.rs.core.Application; + +import prerna.semoss.web.services.AdminConfigService; + +public class AdminApplication extends Application { + + private Set singletons = new HashSet(); + + public AdminApplication() { + singletons.add(new AdminConfigService()); + } + + @Override + public Set getSingletons() { + return singletons; + } +} diff --git a/src/prerna/semoss/web/app/MonolithApplication.java b/src/prerna/semoss/web/app/MonolithApplication.java index 112614da2..afd00c790 100644 --- a/src/prerna/semoss/web/app/MonolithApplication.java +++ b/src/prerna/semoss/web/app/MonolithApplication.java @@ -27,7 +27,6 @@ *******************************************************************************/ package prerna.semoss.web.app; - import java.util.HashSet; import java.util.Set; diff --git a/src/prerna/semoss/web/services/AdminConfigService.java b/src/prerna/semoss/web/services/AdminConfigService.java index 936c0efb0..db8d83b55 100644 --- a/src/prerna/semoss/web/services/AdminConfigService.java +++ b/src/prerna/semoss/web/services/AdminConfigService.java @@ -6,7 +6,7 @@ import prerna.web.services.util.WebUtility; -@Path("/adminConfig") +@Path("/adminconfig") public class AdminConfigService { @GET diff --git a/src/prerna/web/conf/AdminStartupFilter.java b/src/prerna/web/conf/AdminStartupFilter.java new file mode 100644 index 000000000..929370a66 --- /dev/null +++ b/src/prerna/web/conf/AdminStartupFilter.java @@ -0,0 +1,59 @@ +package prerna.web.conf; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import prerna.engine.api.IEngine; +import prerna.engine.api.IRawSelectWrapper; +import prerna.rdf.engine.wrappers.WrapperManager; +import prerna.util.Constants; +import prerna.util.Utility; + +public class AdminStartupFilter implements Filter { + + @Override + public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { + boolean security = Boolean.parseBoolean(arg0.getServletContext().getInitParameter(Constants.SECURITY_ENABLED)); + if(security) { + IEngine engine = Utility.getEngine(Constants.SECURITY_DB); + String q = "SELECT * FROM USER LIMIT 1"; + IRawSelectWrapper wrapper = WrapperManager.getInstance().getRawWrapper(engine, q); + try { + boolean hasUser = wrapper.hasNext(); + // if there are users, redirect to the main semoss page + // we do not want to allow the person to make any admin requests + if(hasUser) { + ((HttpServletRequest) arg0).getSession(true).setAttribute("user", true); + ((HttpServletResponse) arg1).setStatus(302); + ((HttpServletResponse) arg1).sendRedirect("http://localhost:8080/SemossWeb_AppUi/#!/"); + return; + } + } finally { + wrapper.cleanUp(); + } + } + + arg2.doFilter(arg0, arg1); + } + + @Override + public void destroy() { + // TODO Auto-generated method stub + + } + + @Override + public void init(FilterConfig arg0) throws ServletException { + // TODO Auto-generated method stub + + } + +} From e54b52afce0877f1d30144cc05cefa772b14a456 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 4 Sep 2018 13:46:36 +0000 Subject: [PATCH 0199/1906] UPDATE ::: Setting security to false git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29845 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 184965917eed3f509dc85fbafdb02f2691dc6d3c --- WebContent/WEB-INF/web.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index 7836f6913..1ecb43e7e 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -153,7 +153,7 @@ security-enabled - true + false Location to store uploaded file From 1419b8842b3b8016a4dba2a1f456a4ad468153f9 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 4 Sep 2018 14:30:54 +0000 Subject: [PATCH 0200/1906] UPDATE ::: Setting up further work for redirection to allow for less hardcoding git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29846 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: bb205aaabe6a594ac7c24a1af5f4d4c36946a373 --- src/prerna/web/conf/AdminStartupFilter.java | 6 +-- src/prerna/web/conf/NoUserFilter.java | 55 +++++++++++++++++++-- 2 files changed, 53 insertions(+), 8 deletions(-) diff --git a/src/prerna/web/conf/AdminStartupFilter.java b/src/prerna/web/conf/AdminStartupFilter.java index 929370a66..a8feb263c 100644 --- a/src/prerna/web/conf/AdminStartupFilter.java +++ b/src/prerna/web/conf/AdminStartupFilter.java @@ -5,10 +5,10 @@ import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; +import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import prerna.engine.api.IEngine; @@ -21,7 +21,8 @@ public class AdminStartupFilter implements Filter { @Override public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { - boolean security = Boolean.parseBoolean(arg0.getServletContext().getInitParameter(Constants.SECURITY_ENABLED)); + ServletContext context = arg0.getServletContext(); + boolean security = Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED)); if(security) { IEngine engine = Utility.getEngine(Constants.SECURITY_DB); String q = "SELECT * FROM USER LIMIT 1"; @@ -31,7 +32,6 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 // if there are users, redirect to the main semoss page // we do not want to allow the person to make any admin requests if(hasUser) { - ((HttpServletRequest) arg0).getSession(true).setAttribute("user", true); ((HttpServletResponse) arg1).setStatus(302); ((HttpServletResponse) arg1).sendRedirect("http://localhost:8080/SemossWeb_AppUi/#!/"); return; diff --git a/src/prerna/web/conf/NoUserFilter.java b/src/prerna/web/conf/NoUserFilter.java index 2a815c5cc..1b282d2ac 100644 --- a/src/prerna/web/conf/NoUserFilter.java +++ b/src/prerna/web/conf/NoUserFilter.java @@ -5,12 +5,15 @@ import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; +import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import prerna.auth.User; import prerna.engine.api.IEngine; import prerna.engine.api.IRawSelectWrapper; import prerna.rdf.engine.wrappers.WrapperManager; @@ -21,26 +24,68 @@ public class NoUserFilter implements Filter { @Override public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { - boolean security = Boolean.parseBoolean(arg0.getServletContext().getInitParameter(Constants.SECURITY_ENABLED)); + ServletContext context = arg0.getServletContext(); + boolean security = Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED)); if(security) { IEngine engine = Utility.getEngine(Constants.SECURITY_DB); String q = "SELECT * FROM USER LIMIT 1"; IRawSelectWrapper wrapper = WrapperManager.getInstance().getRawWrapper(engine, q); try { boolean hasUser = wrapper.hasNext(); + + // no users at all registered, we need to send to the admin page if(!hasUser) { + // this will be the full path of the request + // like http://localhost:8080/Monolith_Dev/api/engine/runPixel + String fullUrl = ((HttpServletRequest) arg0).getRequestURL().toString(); + // this will be the deployment name of the app + String contextPath = context.getContextPath(); + + // we redirect to the index.html page where we have pushed the admin page + String redirectUrl = fullUrl.substring(0, fullUrl.indexOf(contextPath) + contextPath.length()); + redirectUrl = redirectUrl + "/index.html"; ((HttpServletResponse) arg1).setStatus(302); - ((HttpServletResponse) arg1).sendRedirect("http://localhost:8080/MyHTML/index.html"); + ((HttpServletResponse) arg1).sendRedirect(redirectUrl); return; } + + // users are registered but dont know who this specific user is + // take them to the login page else if( ((HttpServletRequest) arg0).getSession(true).getAttribute("user") == null) { ((HttpServletRequest) arg0).getSession(true).setAttribute("user", true); ((HttpServletResponse) arg1).setStatus(302); ((HttpServletResponse) arg1).sendRedirect("http://localhost:8080/SemossWeb_AppUi/#!/"); return; - } else { - String requestUri = ((HttpServletRequest) arg0).getRequestURI(); - if(requestUri.equals("/Monolith_Dev/")) { + } + + // have the user + + else { + // make sure someone didn't hack this + HttpSession session = ((HttpServletRequest) arg0).getSession(false); + User user = (User) session.getAttribute(Constants.SESSION_USER); + if(user == null || user.getLogins().isEmpty()) { + ((HttpServletRequest) arg0).getSession(true).setAttribute("user", false); + ((HttpServletResponse) arg1).setStatus(302); + ((HttpServletResponse) arg1).sendRedirect("http://localhost:8080/SemossWeb_AppUi/#!/"); + return; + } + + // now, also adding a check for an aliased endpoint... + // if we have aliased on the tomcat server itself + // as a redirect URL + // we should account for it + + // this will be the full path of the request + // like http://localhost:8080/Monolith_Dev/api/engine/runPixel + String fullUrl = ((HttpServletRequest) arg0).getRequestURL().toString(); + // this will be the deployment name of the app + String contextPath = context.getContextPath(); + // we redirect to the index.html page where we have pushed the admin page + String defaultUrl = fullUrl.substring(0, fullUrl.indexOf(contextPath) + contextPath.length()) + "/"; + + // person is running host:port/Monolith_Dev + // this just means we should redirect + if(fullUrl.equals(defaultUrl)) { ((HttpServletRequest) arg0).getSession(true).setAttribute("user", true); ((HttpServletResponse) arg1).setStatus(302); ((HttpServletResponse) arg1).sendRedirect("http://localhost:8080/SemossWeb_AppUi/#!/"); From 6fe7e1a01b350344206ed648d46a267c8c106126 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 4 Sep 2018 15:33:18 +0000 Subject: [PATCH 0201/1906] UPDATE ::: Adding necessary changes for the FE redirect to work properly to login git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29849 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: d1535c369f436acd1bbc869d39df8fbc8de49018 --- src/prerna/web/conf/NoUserFilter.java | 96 ++++++++++++++++----------- 1 file changed, 57 insertions(+), 39 deletions(-) diff --git a/src/prerna/web/conf/NoUserFilter.java b/src/prerna/web/conf/NoUserFilter.java index 1b282d2ac..b9d492729 100644 --- a/src/prerna/web/conf/NoUserFilter.java +++ b/src/prerna/web/conf/NoUserFilter.java @@ -1,6 +1,8 @@ package prerna.web.conf; import java.io.IOException; +import java.util.List; +import java.util.Vector; import javax.servlet.Filter; import javax.servlet.FilterChain; @@ -22,9 +24,21 @@ public class NoUserFilter implements Filter { + private static List ignoreDueToFE = new Vector(); + static { + ignoreDueToFE.add("authorization/securityEnabled"); + ignoreDueToFE.add("auth/isUserRegistrationOn"); + ignoreDueToFE.add("auth/logins"); + ignoreDueToFE.add("auth/loginProperties"); + } + @Override public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { ServletContext context = arg0.getServletContext(); + // this will be the full path of the request + // like http://localhost:8080/Monolith_Dev/api/engine/runPixel + String fullUrl = ((HttpServletRequest) arg0).getRequestURL().toString(); + boolean security = Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED)); if(security) { IEngine engine = Utility.getEngine(Constants.SECURITY_DB); @@ -35,9 +49,6 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 // no users at all registered, we need to send to the admin page if(!hasUser) { - // this will be the full path of the request - // like http://localhost:8080/Monolith_Dev/api/engine/runPixel - String fullUrl = ((HttpServletRequest) arg0).getRequestURL().toString(); // this will be the deployment name of the app String contextPath = context.getContextPath(); @@ -49,46 +60,37 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 return; } - // users are registered but dont know who this specific user is - // take them to the login page - else if( ((HttpServletRequest) arg0).getSession(true).getAttribute("user") == null) { - ((HttpServletRequest) arg0).getSession(true).setAttribute("user", true); - ((HttpServletResponse) arg1).setStatus(302); - ((HttpServletResponse) arg1).sendRedirect("http://localhost:8080/SemossWeb_AppUi/#!/"); - return; - } - - // have the user + - else { - // make sure someone didn't hack this - HttpSession session = ((HttpServletRequest) arg0).getSession(false); - User user = (User) session.getAttribute(Constants.SESSION_USER); - if(user == null || user.getLogins().isEmpty()) { - ((HttpServletRequest) arg0).getSession(true).setAttribute("user", false); + // REALLY DISLIKE THIS CHECK!!! + else if(!isIgnored(fullUrl)) { + // due to FE being annoying + // we need to push a response for this one end point + // since security is embedded w/ normal semoss and not standalone + + // users are registered but dont know who this specific user is + // take them to the login page + if( ((HttpServletRequest) arg0).getSession(true).getAttribute("user") == null) { + ((HttpServletRequest) arg0).getSession(true).setAttribute("user", true); ((HttpServletResponse) arg1).setStatus(302); - ((HttpServletResponse) arg1).sendRedirect("http://localhost:8080/SemossWeb_AppUi/#!/"); + + String referer = ((HttpServletRequest) arg0).getHeader("referer"); + referer = referer + "#!/login"; + ((HttpServletResponse) arg1).sendRedirect(referer); return; } - // now, also adding a check for an aliased endpoint... - // if we have aliased on the tomcat server itself - // as a redirect URL - // we should account for it - - // this will be the full path of the request - // like http://localhost:8080/Monolith_Dev/api/engine/runPixel - String fullUrl = ((HttpServletRequest) arg0).getRequestURL().toString(); - // this will be the deployment name of the app - String contextPath = context.getContextPath(); - // we redirect to the index.html page where we have pushed the admin page - String defaultUrl = fullUrl.substring(0, fullUrl.indexOf(contextPath) + contextPath.length()) + "/"; - - // person is running host:port/Monolith_Dev - // this just means we should redirect - if(fullUrl.equals(defaultUrl)) { - ((HttpServletRequest) arg0).getSession(true).setAttribute("user", true); - ((HttpServletResponse) arg1).setStatus(302); - ((HttpServletResponse) arg1).sendRedirect("http://localhost:8080/SemossWeb_AppUi/#!/"); + // have the user redirect value + // need to make sure no one did any funny business and doesn't have an actual user object + else { + HttpSession session = ((HttpServletRequest) arg0).getSession(false); + User user = (User) session.getAttribute(Constants.SESSION_USER); + if(user == null || user.getLogins().isEmpty()) { + ((HttpServletResponse) arg1).setStatus(302); + + String referer = ((HttpServletRequest) arg0).getHeader("referer"); + referer = referer + "#!/login"; + ((HttpServletResponse) arg1).sendRedirect(referer); + return; + } } } } finally { @@ -110,5 +112,21 @@ public void init(FilterConfig arg0) throws ServletException { // TODO Auto-generated method stub } + + /** + * Due to how the FE security is set up + * Need to ignore some URLs :( + * I REALLY DISLIKE THIS!!! + * @param fullUrl + * @return + */ + private static boolean isIgnored(String fullUrl) { + for(String ignore : ignoreDueToFE) { + if(fullUrl.endsWith(ignore)) { + return true; + } + } + return false; + } } From 22c264afa306d8e4cf8e51ccfb4b89de94321f72 Mon Sep 17 00:00:00 2001 From: davyzhang Date: Tue, 4 Sep 2018 16:26:18 +0000 Subject: [PATCH 0202/1906] UPDATE ::: basic admin config page to add first admin git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29850 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 1612da3d30993d2b2bfe340b1375bd9146d43b28 --- WebContent/index.html | 33 +++++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/WebContent/index.html b/WebContent/index.html index 4a89653f3..339af886c 100644 --- a/WebContent/index.html +++ b/WebContent/index.html @@ -1,10 +1,35 @@ - - Monolith iz da bomb diggity! + + + - -

Get back to work!

+ +
+
+ Please set your initial admin +
+
+ Admin ID: + + +
\ No newline at end of file From b74ec7d7a72606e4aa3a885ba9be180964382dcb Mon Sep 17 00:00:00 2001 From: davyzhang Date: Tue, 4 Sep 2018 16:33:17 +0000 Subject: [PATCH 0203/1906] UPDATE ::: adjusting placement git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29852 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 41f9d71168e25d699b1f4298a1c57ec48449cda6 --- WebContent/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WebContent/index.html b/WebContent/index.html index 339af886c..f051ce6f0 100644 --- a/WebContent/index.html +++ b/WebContent/index.html @@ -22,7 +22,7 @@ -
+
Please set your initial admin
From ecf55b243d3091fafd9268f79d0ecea0a37ad5ff Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 4 Sep 2018 16:46:31 +0000 Subject: [PATCH 0204/1906] BUGFIX ::: Allowing login to work again git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29853 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 0126454939418f155424ec84690142fb674b31dd --- src/prerna/web/conf/NoUserFilter.java | 30 ++++++++++++++++++++------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/prerna/web/conf/NoUserFilter.java b/src/prerna/web/conf/NoUserFilter.java index b9d492729..f2c647495 100644 --- a/src/prerna/web/conf/NoUserFilter.java +++ b/src/prerna/web/conf/NoUserFilter.java @@ -15,10 +15,12 @@ import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; +import prerna.auth.AuthProvider; import prerna.auth.User; import prerna.engine.api.IEngine; import prerna.engine.api.IRawSelectWrapper; import prerna.rdf.engine.wrappers.WrapperManager; +import prerna.semoss.web.services.AdminConfigService; import prerna.util.Constants; import prerna.util.Utility; @@ -30,6 +32,10 @@ public class NoUserFilter implements Filter { ignoreDueToFE.add("auth/isUserRegistrationOn"); ignoreDueToFE.add("auth/logins"); ignoreDueToFE.add("auth/loginProperties"); + for(AuthProvider v : AuthProvider.values()) { + ignoreDueToFE.add("auth/userinfo/" + v.toString().toLowerCase()); + ignoreDueToFE.add("auth/login/" + v.toString().toLowerCase()); + } } @Override @@ -55,8 +61,14 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 // we redirect to the index.html page where we have pushed the admin page String redirectUrl = fullUrl.substring(0, fullUrl.indexOf(contextPath) + contextPath.length()); redirectUrl = redirectUrl + "/index.html"; - ((HttpServletResponse) arg1).setStatus(302); - ((HttpServletResponse) arg1).sendRedirect(redirectUrl); + ((HttpServletResponse) arg1).setHeader("redirect", redirectUrl); + ((HttpServletResponse) arg1).sendError(302, "Need to redirect to " + redirectUrl); + + // we need to store information in the session + // so that we can properly come back to the referer once an admin has been added + String referer = ((HttpServletRequest) arg0).getHeader("referer"); + referer = referer + "#!/login"; + ((HttpServletRequest) arg0).getSession(true).setAttribute(AdminConfigService.ADMIN_REDIRECT_KEY, referer); return; } @@ -72,9 +84,10 @@ else if(!isIgnored(fullUrl)) { ((HttpServletRequest) arg0).getSession(true).setAttribute("user", true); ((HttpServletResponse) arg1).setStatus(302); - String referer = ((HttpServletRequest) arg0).getHeader("referer"); - referer = referer + "#!/login"; - ((HttpServletResponse) arg1).sendRedirect(referer); + String redirectUrl = ((HttpServletRequest) arg0).getHeader("referer"); + redirectUrl = redirectUrl + "#!/login"; + ((HttpServletResponse) arg1).setHeader("redirect", redirectUrl); + ((HttpServletResponse) arg1).sendError(302, "Need to redirect to " + redirectUrl); return; } @@ -86,9 +99,10 @@ else if(!isIgnored(fullUrl)) { if(user == null || user.getLogins().isEmpty()) { ((HttpServletResponse) arg1).setStatus(302); - String referer = ((HttpServletRequest) arg0).getHeader("referer"); - referer = referer + "#!/login"; - ((HttpServletResponse) arg1).sendRedirect(referer); + String redirectUrl = ((HttpServletRequest) arg0).getHeader("referer"); + redirectUrl = redirectUrl + "#!/login"; + ((HttpServletResponse) arg1).setHeader("redirect", redirectUrl); + ((HttpServletResponse) arg1).sendError(302, "Need to redirect to " + redirectUrl); return; } } From b6aa48da48b1c4af744c7b9256cda9fa1b886c71 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 4 Sep 2018 16:52:54 +0000 Subject: [PATCH 0205/1906] UPDATE ::: Removing index.html from redirect URL git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29854 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: d1cee1db2277d3f6347a563a87e00d2dee5a0ad6 --- .../web/services/AdminConfigService.java | 24 +++++++++++++++---- src/prerna/web/conf/NoUserFilter.java | 1 - 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/prerna/semoss/web/services/AdminConfigService.java b/src/prerna/semoss/web/services/AdminConfigService.java index db8d83b55..082294e7e 100644 --- a/src/prerna/semoss/web/services/AdminConfigService.java +++ b/src/prerna/semoss/web/services/AdminConfigService.java @@ -1,7 +1,11 @@ package prerna.semoss.web.services; -import javax.ws.rs.GET; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; +import javax.ws.rs.POST; import javax.ws.rs.Path; +import javax.ws.rs.core.Context; import javax.ws.rs.core.Response; import prerna.web.services.util.WebUtility; @@ -9,10 +13,20 @@ @Path("/adminconfig") public class AdminConfigService { - @GET - @Path("/alive") - public Response isAlive() { - return WebUtility.getResponse("Server is Up", 200); + public static final String ADMIN_REDIRECT_KEY = "ADMIN_REDIRECT_KEY"; + + @POST + @Path("/setInitialAdmins") + public Response setInitialAdmins(@Context HttpServletRequest request) { + HttpSession session = request.getSession(false); + System.out.println(session.getAttribute(ADMIN_REDIRECT_KEY)); + System.out.println(session.getAttribute(ADMIN_REDIRECT_KEY)); + System.out.println(session.getAttribute(ADMIN_REDIRECT_KEY)); + System.out.println(session.getAttribute(ADMIN_REDIRECT_KEY)); + System.out.println(session.getAttribute(ADMIN_REDIRECT_KEY)); + + + return WebUtility.getResponse("success", 200); } } diff --git a/src/prerna/web/conf/NoUserFilter.java b/src/prerna/web/conf/NoUserFilter.java index f2c647495..61d91dd49 100644 --- a/src/prerna/web/conf/NoUserFilter.java +++ b/src/prerna/web/conf/NoUserFilter.java @@ -60,7 +60,6 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 // we redirect to the index.html page where we have pushed the admin page String redirectUrl = fullUrl.substring(0, fullUrl.indexOf(contextPath) + contextPath.length()); - redirectUrl = redirectUrl + "/index.html"; ((HttpServletResponse) arg1).setHeader("redirect", redirectUrl); ((HttpServletResponse) arg1).sendError(302, "Need to redirect to " + redirectUrl); From fec633da4575718fc1d917b34dc3ce077af36ba0 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 4 Sep 2018 16:56:31 +0000 Subject: [PATCH 0206/1906] BUGFIX ::: Setting session attribute properly before redirecting git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29855 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 05919651b5d8541fa69f985044a691c4c9f02032 --- src/prerna/web/conf/NoUserFilter.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/prerna/web/conf/NoUserFilter.java b/src/prerna/web/conf/NoUserFilter.java index 61d91dd49..f8b33464c 100644 --- a/src/prerna/web/conf/NoUserFilter.java +++ b/src/prerna/web/conf/NoUserFilter.java @@ -55,6 +55,13 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 // no users at all registered, we need to send to the admin page if(!hasUser) { + + // we need to store information in the session + // so that we can properly come back to the referer once an admin has been added + String referer = ((HttpServletRequest) arg0).getHeader("referer"); + referer = referer + "#!/login"; + ((HttpServletRequest) arg0).getSession(true).setAttribute(AdminConfigService.ADMIN_REDIRECT_KEY, referer); + // this will be the deployment name of the app String contextPath = context.getContextPath(); @@ -62,12 +69,6 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 String redirectUrl = fullUrl.substring(0, fullUrl.indexOf(contextPath) + contextPath.length()); ((HttpServletResponse) arg1).setHeader("redirect", redirectUrl); ((HttpServletResponse) arg1).sendError(302, "Need to redirect to " + redirectUrl); - - // we need to store information in the session - // so that we can properly come back to the referer once an admin has been added - String referer = ((HttpServletRequest) arg0).getHeader("referer"); - referer = referer + "#!/login"; - ((HttpServletRequest) arg0).getSession(true).setAttribute(AdminConfigService.ADMIN_REDIRECT_KEY, referer); return; } From 55e5c592844f28caaea410588840df48d27824e4 Mon Sep 17 00:00:00 2001 From: davyzhang Date: Tue, 4 Sep 2018 17:17:34 +0000 Subject: [PATCH 0207/1906] UPDATE ::: sending form data git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29857 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: cf06e62733f2ac0db9123ba5ae4ccf4179876aed --- WebContent/index.html | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/WebContent/index.html b/WebContent/index.html index f051ce6f0..bee7def74 100644 --- a/WebContent/index.html +++ b/WebContent/index.html @@ -6,23 +6,24 @@ - +
Please set your initial admin
From c3c7cebd912a093b7055dacf2d1ef212c090684a Mon Sep 17 00:00:00 2001 From: kunalppatel9 Date: Tue, 4 Sep 2018 17:35:53 +0000 Subject: [PATCH 0208/1906] BUGFIX ::: Added in call to fill MS token with user info git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29859 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 00ad1fd42511ee008dcb85ccfc025a2bf9f02e6b --- src/prerna/semoss/web/services/UserResource.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/prerna/semoss/web/services/UserResource.java b/src/prerna/semoss/web/services/UserResource.java index cbe6c55b8..b5b7d66fa 100644 --- a/src/prerna/semoss/web/services/UserResource.java +++ b/src/prerna/semoss/web/services/UserResource.java @@ -81,6 +81,7 @@ import prerna.io.connector.google.GoogleLatLongGetter; import prerna.io.connector.google.GoogleListFiles; import prerna.io.connector.google.GoogleProfile; +import prerna.io.connector.ms.MSProfile; import prerna.io.connector.twitter.TwitterSearcher; import prerna.om.NLPDocumentInput; import prerna.security.AbstractHttpHelper; @@ -245,6 +246,7 @@ private static void loginGoogleApp() { @GET @Path("logins") public Response getAllLogins(@Context HttpServletRequest request) { + Map retMap = new HashMap(); User semossUser = (User) request.getSession().getAttribute(Constants.SESSION_USER); if(semossUser == null) { @@ -691,6 +693,7 @@ public Response loginMS(@Context HttpServletRequest request, @Context HttpServle } accessToken.setProvider(AuthProvider.MS); + MSProfile.fillAccessToken(accessToken, null); addAccessToken(accessToken, request); System.out.println("Access Token is.. " + accessToken.getAccess_token()); From a9cd9c3ff1ed7943e1fe765fac4e622a323eca7e Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 4 Sep 2018 18:07:55 +0000 Subject: [PATCH 0209/1906] UPDATE ::: Changing to send all upper case for login types git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29861 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 9e23b9985eb046eaa1d4aee88c6deb9c1fa46f70 --- src/prerna/semoss/web/services/UserResource.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/prerna/semoss/web/services/UserResource.java b/src/prerna/semoss/web/services/UserResource.java index b5b7d66fa..93b5cc7d6 100644 --- a/src/prerna/semoss/web/services/UserResource.java +++ b/src/prerna/semoss/web/services/UserResource.java @@ -246,8 +246,7 @@ private static void loginGoogleApp() { @GET @Path("logins") public Response getAllLogins(@Context HttpServletRequest request) { - - Map retMap = new HashMap(); + Map retMap = new HashMap(); User semossUser = (User) request.getSession().getAttribute(Constants.SESSION_USER); if(semossUser == null) { return WebUtility.getResponse(retMap, 200); @@ -255,7 +254,7 @@ public Response getAllLogins(@Context HttpServletRequest request) { List logins = semossUser.getLogins(); for(AuthProvider p : logins) { String name = semossUser.getAccessToken(p).getName(); - retMap.put(p, name); + retMap.put(p.toString().toUpperCase(), name); } return WebUtility.getResponse(retMap, 200); } From 180d670329e92e6c13d5008891da18a47e513a26 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 4 Sep 2018 18:22:14 +0000 Subject: [PATCH 0210/1906] UPDATE ::: Finishing up the redirection after you add the admin users git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29862 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: c434bf9a71a26980d297140359aa4037ba9ef040 --- WebContent/index.html | 21 ++++++---- .../web/services/AdminConfigService.java | 39 +++++++++++++++---- src/prerna/web/conf/AdminStartupFilter.java | 15 ++++++- 3 files changed, 58 insertions(+), 17 deletions(-) diff --git a/WebContent/index.html b/WebContent/index.html index bee7def74..13ee52372 100644 --- a/WebContent/index.html +++ b/WebContent/index.html @@ -11,14 +11,19 @@ inputs = document.getElementById('user-id'); ids = [inputs.value]; - // xhttp.onreadystatechange = function() { - // if (this.readyState == 4 && this.status == 200) { - // alert(this.responseText); - // } - // }; - xhttp.open('POST', endpoint, true); - xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); - xhttp.send('ids=' + encodeURIComponent(JSON.stringify(ids))); + if(inputs.value) { + xhttp.onreadystatechange = function() { + if (this.status == 302) { + var redir = this.getResponseHeader("redirect"); + if(redir) { + window.location.replace(redir); + } + } + }; + xhttp.open('POST', endpoint, true); + xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); + xhttp.send('ids=' + encodeURIComponent(JSON.stringify(ids))); + } } diff --git a/src/prerna/semoss/web/services/AdminConfigService.java b/src/prerna/semoss/web/services/AdminConfigService.java index 082294e7e..03cdf59e1 100644 --- a/src/prerna/semoss/web/services/AdminConfigService.java +++ b/src/prerna/semoss/web/services/AdminConfigService.java @@ -1,31 +1,56 @@ package prerna.semoss.web.services; +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.core.Context; +import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; +import com.google.gson.Gson; + +import prerna.auth.SecurityUpdateUtils; +import prerna.web.conf.AdminStartupFilter; import prerna.web.services.util.WebUtility; @Path("/adminconfig") public class AdminConfigService { + private static final Gson GSON = new Gson(); public static final String ADMIN_REDIRECT_KEY = "ADMIN_REDIRECT_KEY"; @POST @Path("/setInitialAdmins") - public Response setInitialAdmins(@Context HttpServletRequest request) { + public Response setInitialAdmins(@Context HttpServletRequest request, @Context HttpServletResponse response, MultivaluedMap form) throws IOException { HttpSession session = request.getSession(false); - System.out.println(session.getAttribute(ADMIN_REDIRECT_KEY)); - System.out.println(session.getAttribute(ADMIN_REDIRECT_KEY)); - System.out.println(session.getAttribute(ADMIN_REDIRECT_KEY)); - System.out.println(session.getAttribute(ADMIN_REDIRECT_KEY)); - System.out.println(session.getAttribute(ADMIN_REDIRECT_KEY)); - + String idString = form.getFirst("ids"); + if(idString == null || idString.isEmpty()) { + Map errorMessage = new HashMap(); + errorMessage.put("errorMessage", "Need to send valid ids"); + return WebUtility.getResponse(errorMessage, 200); + } + List ids = GSON.fromJson(idString, List.class); + + for(String id : ids) { + SecurityUpdateUtils.registerUser(id, true); + } + + if(session.getAttribute(ADMIN_REDIRECT_KEY) != null) { + String originalRedirect = session.getAttribute(ADMIN_REDIRECT_KEY) + ""; + response.setHeader("redirect", originalRedirect); + response.sendError(302, "Need to redirect to " + originalRedirect); + AdminStartupFilter.setSuccessfulRedirectUrl(originalRedirect); + } + return WebUtility.getResponse("success", 200); } diff --git a/src/prerna/web/conf/AdminStartupFilter.java b/src/prerna/web/conf/AdminStartupFilter.java index a8feb263c..4863cc53f 100644 --- a/src/prerna/web/conf/AdminStartupFilter.java +++ b/src/prerna/web/conf/AdminStartupFilter.java @@ -19,9 +19,12 @@ public class AdminStartupFilter implements Filter { + private static String initialRedirect; + @Override public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { ServletContext context = arg0.getServletContext(); + boolean security = Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED)); if(security) { IEngine engine = Utility.getEngine(Constants.SECURITY_DB); @@ -32,8 +35,12 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 // if there are users, redirect to the main semoss page // we do not want to allow the person to make any admin requests if(hasUser) { - ((HttpServletResponse) arg1).setStatus(302); - ((HttpServletResponse) arg1).sendRedirect("http://localhost:8080/SemossWeb_AppUi/#!/"); + if(initialRedirect != null) { + ((HttpServletResponse) arg1).setHeader("redirect", initialRedirect); + ((HttpServletResponse) arg1).sendError(302, "Need to redirect to " + initialRedirect); + } else { + ((HttpServletResponse) arg1).sendError(404, "Page Not Found"); + } return; } } finally { @@ -55,5 +62,9 @@ public void init(FilterConfig arg0) throws ServletException { // TODO Auto-generated method stub } + + public static void setSuccessfulRedirectUrl(String initialRedirect) { + AdminStartupFilter.initialRedirect = initialRedirect; + } } From 86970f42a941ff83858881fe4d3b8b8556f4d536 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 4 Sep 2018 18:39:28 +0000 Subject: [PATCH 0211/1906] UPDATE ::: Making sure we send the logins even if we do not have the name git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29863 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: f670bddeaa1a07a710bcfb4b1f39dacba2610455 --- src/prerna/semoss/web/services/UserResource.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/prerna/semoss/web/services/UserResource.java b/src/prerna/semoss/web/services/UserResource.java index 93b5cc7d6..57fea8a88 100644 --- a/src/prerna/semoss/web/services/UserResource.java +++ b/src/prerna/semoss/web/services/UserResource.java @@ -254,6 +254,10 @@ public Response getAllLogins(@Context HttpServletRequest request) { List logins = semossUser.getLogins(); for(AuthProvider p : logins) { String name = semossUser.getAccessToken(p).getName(); + if(name == null) { + // need to send something + name = ""; + } retMap.put(p.toString().toUpperCase(), name); } return WebUtility.getResponse(retMap, 200); From 9c532b823f9dd167783eb51aa686830c44f88ca5 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 4 Sep 2018 19:28:13 +0000 Subject: [PATCH 0212/1906] BUGFIX ::: Fixing error with native user login git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29866 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 171076495abd105a3a596ff59177b1a413b571fc --- src/prerna/web/conf/NoUserFilter.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/prerna/web/conf/NoUserFilter.java b/src/prerna/web/conf/NoUserFilter.java index f8b33464c..2099099c1 100644 --- a/src/prerna/web/conf/NoUserFilter.java +++ b/src/prerna/web/conf/NoUserFilter.java @@ -32,6 +32,7 @@ public class NoUserFilter implements Filter { ignoreDueToFE.add("auth/isUserRegistrationOn"); ignoreDueToFE.add("auth/logins"); ignoreDueToFE.add("auth/loginProperties"); + ignoreDueToFE.add("auth/login"); for(AuthProvider v : AuthProvider.values()) { ignoreDueToFE.add("auth/userinfo/" + v.toString().toLowerCase()); ignoreDueToFE.add("auth/login/" + v.toString().toLowerCase()); From f937551279e0ab5c40c7cae8d9961ea17678236d Mon Sep 17 00:00:00 2001 From: nesanghvi Date: Tue, 4 Sep 2018 19:43:23 +0000 Subject: [PATCH 0213/1906] UPDATE ::: changing the admin login css to match. git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29867 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 2039fc5f10da9ecdf170481db10d56308978576c --- WebContent/index.html | 257 ++++++++++++++++++++++++++++++++++------ WebContent/milkyway.jpg | Bin 0 -> 336189 bytes 2 files changed, 223 insertions(+), 34 deletions(-) create mode 100644 WebContent/milkyway.jpg diff --git a/WebContent/index.html b/WebContent/index.html index 13ee52372..c17094889 100644 --- a/WebContent/index.html +++ b/WebContent/index.html @@ -1,41 +1,230 @@ - - - - - - - -
- Please set your initial admin + } + + + + +
+ +
+
+ Please set your initial admin +
+
+ +
+
+ +
+
+
-
- Admin ID: - - - +
+ + \ No newline at end of file diff --git a/WebContent/milkyway.jpg b/WebContent/milkyway.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8f7f53bb5d1cdcf77447da03504e1746a53126e2 GIT binary patch literal 336189 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

jhei@glk#wMB$kqdW#tprRqs5 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

Ov<9~HxM`@0J8juZ7 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
i3p{?Mht3 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

KdQjCj(T#So$pX>u%SOSfcxGL|~WD+>Z-?ak?#W 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

UA@Lcj!6`)YO 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 V&cy58{Og^G*Sq=GI}@*;{U6w~j1&L> literal 0 HcmV?d00001 From 1dd48227e24131eac61643eba77d4e85a7ec5ede Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 4 Sep 2018 19:55:53 +0000 Subject: [PATCH 0214/1906] UPDATE ::: Accounting for create user to be allowed through filters UPDATE ::: Adding CAC User to be stored when entering the app git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29868 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 4837821a119ae3aa700e6d8d8d0206a66f4993f4 --- src/prerna/web/conf/CACFilter.java | 11 +++++++++-- src/prerna/web/conf/NoUserFilter.java | 1 + 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/prerna/web/conf/CACFilter.java b/src/prerna/web/conf/CACFilter.java index f2aaa8ebd..792e69ecc 100644 --- a/src/prerna/web/conf/CACFilter.java +++ b/src/prerna/web/conf/CACFilter.java @@ -22,6 +22,7 @@ import prerna.auth.AccessToken; import prerna.auth.AuthProvider; +import prerna.auth.SecurityUpdateUtils; import prerna.auth.User; import prerna.util.Constants; @@ -34,12 +35,15 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 X509Certificate[] certs = (X509Certificate[]) arg0.getAttribute("javax.servlet.request.X509Certificate"); HttpSession session = ((HttpServletRequest)arg0).getSession(true); + User user = null; + AccessToken token = null; + if(certs != null) { - User user = (User) session.getAttribute(Constants.SESSION_USER); + user = (User) session.getAttribute(Constants.SESSION_USER); if(user == null) { user = new User(); - AccessToken token = new AccessToken(); + token = new AccessToken(); token.setProvider(AuthProvider.CAC); // loop thorugh all the certs CERT_LOOP : for(int i = 0; i < certs.length; i++) { @@ -107,6 +111,9 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 LOGGER.error("COULDN'T AUTHORIZE USER!"); return; } + + // add the user if they do not exist + SecurityUpdateUtils.addOAuthUser(token); arg2.doFilter(arg0, arg1); } diff --git a/src/prerna/web/conf/NoUserFilter.java b/src/prerna/web/conf/NoUserFilter.java index 2099099c1..ddd62dda6 100644 --- a/src/prerna/web/conf/NoUserFilter.java +++ b/src/prerna/web/conf/NoUserFilter.java @@ -33,6 +33,7 @@ public class NoUserFilter implements Filter { ignoreDueToFE.add("auth/logins"); ignoreDueToFE.add("auth/loginProperties"); ignoreDueToFE.add("auth/login"); + ignoreDueToFE.add("auth/createUser"); for(AuthProvider v : AuthProvider.values()) { ignoreDueToFE.add("auth/userinfo/" + v.toString().toLowerCase()); ignoreDueToFE.add("auth/login/" + v.toString().toLowerCase()); From c3039ced78f280c634e2ba51359e18e88340851b Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 4 Sep 2018 20:12:41 +0000 Subject: [PATCH 0215/1906] UPDATE ::: Also parsing out the email in the CAC filter git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29869 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: b6c41bb0949717e0da9fa53a9ac66b92aa6e0bb1 --- src/prerna/web/conf/CACFilter.java | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/prerna/web/conf/CACFilter.java b/src/prerna/web/conf/CACFilter.java index 792e69ecc..4ba8adbd7 100644 --- a/src/prerna/web/conf/CACFilter.java +++ b/src/prerna/web/conf/CACFilter.java @@ -1,7 +1,9 @@ package prerna.web.conf; import java.io.IOException; +import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; +import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -84,6 +86,26 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 // now set the other properties token.setToken_type(cert.getIssuerDN().getName()); token.setExpires_in((int) cert.getNotAfter().getTime()); + + // try to get the email + try { + EMAIL_LOOP : for(List altNames : cert.getSubjectAlternativeNames()) { + for(Object alternative : altNames) { + if(alternative instanceof String) { + String altStr = alternative.toString(); + // really simple email check... + if(altStr.contains("@")) { + token.setEmail(altStr); + break EMAIL_LOOP; + } + } + } + } + } catch (CertificateParsingException e) { + e.printStackTrace(); + } + + break CERT_LOOP; } else { continue; From dbda305abeb0dd03ecb60468a547ed30fa687483 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 4 Sep 2018 20:50:20 +0000 Subject: [PATCH 0216/1906] UPDATE ::: Fixing null pointer issue with request git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29873 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 4cbd9f606c34c35afd2b82371e3715967ee51bd2 --- src/prerna/web/conf/CACFilter.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/prerna/web/conf/CACFilter.java b/src/prerna/web/conf/CACFilter.java index 4ba8adbd7..eec36e68e 100644 --- a/src/prerna/web/conf/CACFilter.java +++ b/src/prerna/web/conf/CACFilter.java @@ -125,6 +125,9 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 LOGGER.info("Valid request coming from user " + token.getName()); user.setAccessToken(token); session.setAttribute(Constants.SESSION_USER, user); + + // add the user if they do not exist + SecurityUpdateUtils.addOAuthUser(token); } } } @@ -134,9 +137,6 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 return; } - // add the user if they do not exist - SecurityUpdateUtils.addOAuthUser(token); - arg2.doFilter(arg0, arg1); } From 78499ba42b083a51d7082759f05bfbfe1faeb856 Mon Sep 17 00:00:00 2001 From: tbanach Date: Tue, 4 Sep 2018 23:31:30 +0000 Subject: [PATCH 0217/1906] UPDATE ::: Including index.html and milkyway.jpg in the pom.xml / war package git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29876 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: f8e5ee4f55247fe9c9fc7b562099e741b3c8ea2f --- pom.xml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pom.xml b/pom.xml index d9cc27577..774deeb31 100644 --- a/pom.xml +++ b/pom.xml @@ -73,6 +73,11 @@ WebContent/WEB-INF/web.xml true + ${basedir}/WebContent + + index.html, + milkyway.jpg + @@ -113,6 +118,11 @@ WebContent/WEB-INF/web.xml true + ${basedir}/WebContent + + index.html, + milkyway.jpg + %regex[WEB-INF/lib/(?!semoss-${ci.version}).*.jar] From f85ac71042b47307bc856d1dc51543d2f5c555c3 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 5 Sep 2018 00:27:22 +0000 Subject: [PATCH 0218/1906] UPDATE ::: Putting temporary code to not try image capture when we have security enabled due to errors with passing the session id into the chrome driver git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29878 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 131bc2a8ad256c330afda6e4d1946aaedf4c43fc --- .../semoss/web/services/AppResource.java | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/prerna/semoss/web/services/AppResource.java b/src/prerna/semoss/web/services/AppResource.java index 3ddf15e63..b15076d18 100644 --- a/src/prerna/semoss/web/services/AppResource.java +++ b/src/prerna/semoss/web/services/AppResource.java @@ -134,16 +134,24 @@ private File getInsightImageFile(String app, String id, String feUrl, String par return f; } else { // try making the image - if(feUrl != null) { - try { - ImageCaptureReactor.runImageCapture(feUrl, appId, id, params, sessionId); - } - catch(Exception | NoSuchMethodError er) { - //Image Capture will not run. No image exists nor will be made. The exception kills the rest. - // return stock image - er.printStackTrace(); - f = AbstractSecurityUtils.getStockImage(appId, id); - return f; + //TODO: TEMPORARY TILL WE GET SECURITY TO WORK WITH IMAGE CAPTURE!!! + //TODO: TEMPORARY TILL WE GET SECURITY TO WORK WITH IMAGE CAPTURE!!! + //TODO: TEMPORARY TILL WE GET SECURITY TO WORK WITH IMAGE CAPTURE!!! + //TODO: TEMPORARY TILL WE GET SECURITY TO WORK WITH IMAGE CAPTURE!!! + //TODO: TEMPORARY TILL WE GET SECURITY TO WORK WITH IMAGE CAPTURE!!! + //TODO: TEMPORARY TILL WE GET SECURITY TO WORK WITH IMAGE CAPTURE!!! + if(!AbstractSecurityUtils.securityEnabled()) { + if(feUrl != null) { + try { + ImageCaptureReactor.runImageCapture(feUrl, appId, id, params, sessionId); + } + catch(Exception | NoSuchMethodError er) { + //Image Capture will not run. No image exists nor will be made. The exception kills the rest. + // return stock image + er.printStackTrace(); + f = AbstractSecurityUtils.getStockImage(appId, id); + return f; + } } } if(f.exists()) { From 7fc6655a7400a8c0b00e4716a5030c47b0cf173f Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 5 Sep 2018 16:26:12 +0000 Subject: [PATCH 0219/1906] UPDATE ::: Fixing image capture when security is enabled git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29890 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 1bb9afc3693180609160900cf46233321fe40f67 --- .../semoss/web/services/AppResource.java | 30 +++++++------------ src/prerna/web/conf/DBLoader.java | 25 +++++++++------- src/prerna/web/conf/NoUserFilter.java | 8 ++--- 3 files changed, 29 insertions(+), 34 deletions(-) diff --git a/src/prerna/semoss/web/services/AppResource.java b/src/prerna/semoss/web/services/AppResource.java index b15076d18..7238ebdba 100644 --- a/src/prerna/semoss/web/services/AppResource.java +++ b/src/prerna/semoss/web/services/AppResource.java @@ -65,7 +65,6 @@ private File getAppImageFile(String app) { if(propFileLoc == null && !app.equals("NEWSEMOSSAPP")) { String imageDir = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER) + "/images/stock/"; return new File(imageDir + "color-logo.png"); -// return null; } Properties prop = Utility.loadProperties(propFileLoc); app = prop.getProperty(Constants.ENGINE_ALIAS); @@ -99,6 +98,7 @@ public Response downloadInsightImage(@Context HttpServletRequest request, @PathP if(securityEnabled){ sessionId = request.getSession(false).getId(); } + File exportFile = getInsightImageFile(app, id, request.getHeader("Referer"), params, sessionId); if(exportFile != null && exportFile.exists()) { String exportName = app + "_Image." + FilenameUtils.getExtension(exportFile.getAbsolutePath()); @@ -134,24 +134,16 @@ private File getInsightImageFile(String app, String id, String feUrl, String par return f; } else { // try making the image - //TODO: TEMPORARY TILL WE GET SECURITY TO WORK WITH IMAGE CAPTURE!!! - //TODO: TEMPORARY TILL WE GET SECURITY TO WORK WITH IMAGE CAPTURE!!! - //TODO: TEMPORARY TILL WE GET SECURITY TO WORK WITH IMAGE CAPTURE!!! - //TODO: TEMPORARY TILL WE GET SECURITY TO WORK WITH IMAGE CAPTURE!!! - //TODO: TEMPORARY TILL WE GET SECURITY TO WORK WITH IMAGE CAPTURE!!! - //TODO: TEMPORARY TILL WE GET SECURITY TO WORK WITH IMAGE CAPTURE!!! - if(!AbstractSecurityUtils.securityEnabled()) { - if(feUrl != null) { - try { - ImageCaptureReactor.runImageCapture(feUrl, appId, id, params, sessionId); - } - catch(Exception | NoSuchMethodError er) { - //Image Capture will not run. No image exists nor will be made. The exception kills the rest. - // return stock image - er.printStackTrace(); - f = AbstractSecurityUtils.getStockImage(appId, id); - return f; - } + if(feUrl != null) { + try { + ImageCaptureReactor.runImageCapture(feUrl, appId, id, params, sessionId); + } + catch(Exception | NoSuchMethodError er) { + //Image Capture will not run. No image exists nor will be made. The exception kills the rest. + // return stock image + er.printStackTrace(); + f = AbstractSecurityUtils.getStockImage(appId, id); + return f; } } if(f.exists()) { diff --git a/src/prerna/web/conf/DBLoader.java b/src/prerna/web/conf/DBLoader.java index 7412d1138..3b9c2b8a2 100644 --- a/src/prerna/web/conf/DBLoader.java +++ b/src/prerna/web/conf/DBLoader.java @@ -31,6 +31,7 @@ import java.util.Set; import java.util.Vector; +import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; @@ -46,6 +47,7 @@ import prerna.om.InsightStore; import prerna.rpa.quartz.SchedulerUtil; import prerna.sablecc2.reactor.frame.r.util.RJavaTranslatorFactory; +import prerna.sablecc2.reactor.utils.ImageCaptureReactor; import prerna.util.AbstractFileWatcher; import prerna.util.Constants; import prerna.util.DIHelper; @@ -61,14 +63,19 @@ public class DBLoader implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent arg0) { - System.out.println("Initializing application context..." + arg0.getServletContext().getContextPath()); + ServletContext context = arg0.getServletContext(); + String contextPath = context.getContextPath(); + + String rdfPropFile = context.getInitParameter(RDFMAP); + String securityEnabled = context.getInitParameter(Constants.SECURITY_ENABLED); + + System.out.println("Initializing application context..." + contextPath); //Set default file separator system variable System.out.println("Changing file separator value to: '/'"); System.setProperty("file.separator", "/"); //Load RDF_Map.prop file - String rdfPropFile = arg0.getServletContext().getInitParameter(RDFMAP); System.out.println("Loading RDF_Map.prop: " + rdfPropFile); DIHelper.getInstance().loadCoreProp(rdfPropFile); @@ -77,21 +84,13 @@ public void contextInitialized(ServletContextEvent arg0) { System.out.println("Setting log4j property: " + log4jConfig); PropertyConfigurator.configure(log4jConfig); -// //Set Solr home variable (~SEMOSS_PROJ_HOME/Solr) -// String solrHome = DIHelper.getInstance().getProperty("BaseFolder") + "/" + Constants.SOLR_HOME_DIR; -// if((new File(solrHome)).exists()) { -// System.out.println("Setting Solr home: " + solrHome); -// System.setProperty("solr.solr.home", solrHome); -// } - //Load empty engine list into DIHelper, then load engines from db folder System.out.println("Loading engines..."); String engines = ""; DIHelper.getInstance().setLocalProperty(Constants.ENGINES, engines); loadEngines(); - //Set whether or not security is enabled in DIHelper to be used in PKQL processing - DIHelper.getInstance().setLocalProperty(Constants.SECURITY_ENABLED, arg0.getServletContext().getInitParameter(Constants.SECURITY_ENABLED)); + DIHelper.getInstance().setLocalProperty(Constants.SECURITY_ENABLED, securityEnabled); //Just load R right away to avoid synchronization issues try { @@ -99,6 +98,10 @@ public void contextInitialized(ServletContextEvent arg0) { } catch(Exception e) { e.printStackTrace(); } + + // need to set the path + // important for taking the image with security + ImageCaptureReactor.setContextPath(contextPath); } public void loadEngines() { diff --git a/src/prerna/web/conf/NoUserFilter.java b/src/prerna/web/conf/NoUserFilter.java index ddd62dda6..b3b808ced 100644 --- a/src/prerna/web/conf/NoUserFilter.java +++ b/src/prerna/web/conf/NoUserFilter.java @@ -80,10 +80,11 @@ else if(!isIgnored(fullUrl)) { // we need to push a response for this one end point // since security is embedded w/ normal semoss and not standalone + HttpSession session = ((HttpServletRequest) arg0).getSession(true); // users are registered but dont know who this specific user is // take them to the login page - if( ((HttpServletRequest) arg0).getSession(true).getAttribute("user") == null) { - ((HttpServletRequest) arg0).getSession(true).setAttribute("user", true); + if(session.getAttribute("user") == null) { + session.setAttribute("user", true); ((HttpServletResponse) arg1).setStatus(302); String redirectUrl = ((HttpServletRequest) arg0).getHeader("referer"); @@ -96,11 +97,10 @@ else if(!isIgnored(fullUrl)) { // have the user redirect value // need to make sure no one did any funny business and doesn't have an actual user object else { - HttpSession session = ((HttpServletRequest) arg0).getSession(false); User user = (User) session.getAttribute(Constants.SESSION_USER); if(user == null || user.getLogins().isEmpty()) { ((HttpServletResponse) arg1).setStatus(302); - + String redirectUrl = ((HttpServletRequest) arg0).getHeader("referer"); redirectUrl = redirectUrl + "#!/login"; ((HttpServletResponse) arg1).setHeader("redirect", redirectUrl); From c0a5683cf90cd6910059e85b156afd221adfad6d Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 6 Sep 2018 16:37:52 +0000 Subject: [PATCH 0220/1906] UPDATE ::: Adding admin check and is_sys_admin check for formresource endpoints UPDATE ::: Allow a instance name to be passed on the FE git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29918 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 0224ef7e42a19787908137110eeaf896dd6e9d7c --- src/prerna/semoss/web/form/FormResource.java | 226 +++++++++++++----- .../semoss/web/services/NameServer.java | 5 +- 2 files changed, 170 insertions(+), 61 deletions(-) diff --git a/src/prerna/semoss/web/form/FormResource.java b/src/prerna/semoss/web/form/FormResource.java index e86db9fd5..4cf16d6ef 100644 --- a/src/prerna/semoss/web/form/FormResource.java +++ b/src/prerna/semoss/web/form/FormResource.java @@ -1,8 +1,6 @@ package prerna.semoss.web.form; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; +import java.io.IOException; import java.util.HashMap; import java.util.Hashtable; import java.util.Map; @@ -20,43 +18,66 @@ import prerna.auth.AuthProvider; import prerna.auth.User; import prerna.engine.api.IEngine; -import prerna.engine.impl.rdbms.RDBMSNativeEngine; +import prerna.engine.api.IRawSelectWrapper; import prerna.forms.AbstractFormBuilder; import prerna.forms.FormBuilder; import prerna.forms.FormFactory; import prerna.nameserver.utility.MasterDatabaseUtility; +import prerna.rdf.engine.wrappers.WrapperManager; import prerna.util.Utility; import prerna.web.services.util.WebUtility; @Path("/form") public class FormResource { + private IEngine formEngine; + @POST @Path("/modifyUserAccess") @Produces("application/json") - public Response modifyUserAccess(MultivaluedMap form) { - IEngine formBuilderEng = Utility.getEngine(FormBuilder.FORM_BUILDER_ENGINE_NAME); - + public Response modifyUserAccess(@Context HttpServletRequest request, MultivaluedMap form) { + String cacId; + try { + cacId = getCacId(request); + } catch (IOException e) { + Map err = new HashMap(); + err.put("errorMessage", e.getMessage()); + return WebUtility.getResponse(err, 400); + } + + try { + throwErrorIfNotAdmin(cacId); + } catch (IllegalAccessException e) { + Map err = new HashMap(); + err.put("errorMessage", e.getMessage()); + return WebUtility.getResponse(err, 400); + } + String addOrRemove = form.getFirst("addOrRemove"); String userid = form.getFirst("userid"); + String instancename = form.getFirst("instanceName"); + // this is only present if we are adding a user + String owner = form.getFirst("ownerStatus"); String query = null; - if (addOrRemove.equals("Remove")) { - query = "DELETE FROM FORMS_USER_ACCESS WHERE USER_ID = '" + userid + "';"; + if (addOrRemove.equals("Remove")) { + if(instancename != null && !instancename.isEmpty() && !instancename.equals("null") && !instancename.equals("undefined")) { + query = "DELETE FROM FORMS_USER_ACCESS WHERE USER_ID = '" + userid + "' AND INSTANCE_NAME = '" + instancename + "';"; + } else { + // remove all of user + query = "DELETE FROM FORMS_USER_ACCESS WHERE USER_ID = '" + userid + "';"; + } } else if (addOrRemove.equals("Add")) { - String instancename = form.getFirst("instanceName"); - // this is a boolean being represented by a string true/false - String owner = form.getFirst("ownerStatus"); - query = "INSERT INTO FORMS_USER_ACCESS (USER_ID, INSTANCE_NAME, IS_SYS_ADMIN) VALUES ('" + userid + "','" + instancename + "','" + owner + "');"; } else { return WebUtility.getResponse("Error: need to specify Add or Remove", 400); } - // execute the insert statement - formBuilderEng.insertData(query); + IEngine formEngine = getEngine(); + // execute the query + formEngine.insertData(query); // commit to engine - formBuilderEng.commit(); + formEngine.commit(); return WebUtility.getResponse("success", 200); } @@ -64,7 +85,24 @@ public Response modifyUserAccess(MultivaluedMap form) { @POST @Path("/renameInstance") @Produces("application/json") - public Response renameInstance(MultivaluedMap form) { + public Response renameInstance(@Context HttpServletRequest request, MultivaluedMap form) { + String cacId; + try { + cacId = getCacId(request); + } catch (IOException e) { + Map err = new HashMap(); + err.put("errorMessage", e.getMessage()); + return WebUtility.getResponse(err, 400); + } + + try { + throwErrorIfNotAdmin(cacId); + } catch (IllegalAccessException e) { + Map err = new HashMap(); + err.put("errorMessage", e.getMessage()); + return WebUtility.getResponse(err, 400); + } + String dbName = form.getFirst("dbName"); String origUri = form.getFirst("originalUri"); String newUri = form.getFirst("newUri"); @@ -73,8 +111,7 @@ public Response renameInstance(MultivaluedMap form) { deleteInstanceBoolean = Boolean.parseBoolean(form.getFirst("deleteInstanceBoolean")); } - IEngine coreEngine = Utility.getEngine(MasterDatabaseUtility.testEngineIdIfAlias(dbName)); - + IEngine coreEngine = Utility.getEngine(MasterDatabaseUtility.testEngineIdIfAlias(dbName)); AbstractFormBuilder formbuilder = FormFactory.getFormBuilder(coreEngine); formbuilder.modifyInstanceValue(origUri, newUri, deleteInstanceBoolean); return WebUtility.getResponse("success", 200); @@ -83,16 +120,31 @@ public Response renameInstance(MultivaluedMap form) { @POST @Path("/certifyInstance") @Produces("application/json") - public Response certifyInstance(MultivaluedMap form) { - String userid = form.getFirst("userid"); + public Response certifyInstance(@Context HttpServletRequest request, MultivaluedMap form) { + String cacId; + try { + cacId = getCacId(request); + } catch (IOException e) { + Map err = new HashMap(); + err.put("errorMessage", e.getMessage()); + return WebUtility.getResponse(err, 400); + } + + String dbName = form.getFirst("dbName"); String instanceType = form.getFirst("instanceType"); String instanceName = form.getFirst("instanceName"); - String dbName = form.getFirst("dbName"); - - IEngine coreEngine = Utility.getEngine(MasterDatabaseUtility.testEngineIdIfAlias(dbName)); + try { + throwErrorIfNotSysAdmin(cacId, instanceName); + } catch (IllegalAccessException e) { + Map err = new HashMap(); + err.put("errorMessage", e.getMessage()); + return WebUtility.getResponse(err, 400); + } + + IEngine coreEngine = Utility.getEngine(MasterDatabaseUtility.testEngineIdIfAlias(dbName)); AbstractFormBuilder formbuilder = FormFactory.getFormBuilder(coreEngine); - formbuilder.setUser(userid); + formbuilder.setUser(cacId); formbuilder.certifyInstance(instanceType, instanceName); return WebUtility.getResponse("success", 200); } @@ -101,53 +153,111 @@ public Response certifyInstance(MultivaluedMap form) { @Path("/getUserInstanceAuth") @Produces("applicaiton/json") public Response getUserInstanceAuth(@Context HttpServletRequest request) throws InvalidNameException { + /* + * Get the specific instances this user has access to + */ + + String cacId; + try { + cacId = getCacId(request); + } catch (IOException e) { + Map err = new HashMap(); + err.put("errorMessage", e.getMessage()); + return WebUtility.getResponse(err, 400); + } + + Map userAccessableInstances = new HashMap(); + + // map to store the valid instances for the given user + String query = "SELECT INSTANCE_NAME, IS_SYS_ADMIN FROM FORMS_USER_ACCESS WHERE USER_ID = '" + cacId + "';"; + IRawSelectWrapper wrapper = WrapperManager.getInstance().getRawWrapper(getEngine(), query); + while(wrapper.hasNext()) { + Object[] values = wrapper.next().getValues(); + userAccessableInstances.put(values[0].toString(), values[1].toString()); + } + + Map returnData = new Hashtable(); + returnData.put("cac_id", cacId); + returnData.put("validInstances", userAccessableInstances); + return WebUtility.getResponse(returnData, 200); + } + + /** + * Get the CAC ID for the user + * @param request + * @return + * @throws IOException + */ + private String getCacId(@Context HttpServletRequest request) throws IOException { String x509Id = null; try { HttpSession session = ((HttpServletRequest)request).getSession(false); User user = (User) session.getAttribute("semoss_user"); x509Id = user.getAccessToken(AuthProvider.CAC).getId(); } catch(Exception e) { - Map err = new HashMap(); - err.put("errorMessage", "Could not identify user"); - return WebUtility.getResponse(err, 400); + throw new IOException("Could not identify user"); } if(x509Id == null) { - Map err = new HashMap(); - err.put("errorMessage", "Could not identify user"); - return WebUtility.getResponse(err, 400); + throw new IOException("Could not identify user"); } - Map userAccessableInstances = new HashMap(); - - IEngine formBuilderEng = Utility.getEngine(FormBuilder.FORM_BUILDER_ENGINE_NAME); - // map to store the valid instances for the given user - String query = "SELECT INSTANCE_NAME, IS_SYS_ADMIN FROM FORMS_USER_ACCESS WHERE USER_ID = '" + x509Id + "';"; - Map ret = (Map) formBuilderEng.execQuery(query); - Statement stmt = (Statement) ret.get(RDBMSNativeEngine.STATEMENT_OBJECT); - ResultSet rs = (ResultSet) ret.get(RDBMSNativeEngine.RESULTSET_OBJECT); + return x509Id; + } + + /** + * Check that user is an admin + * @param cacId + * @throws IllegalAccessException + */ + private void throwErrorIfNotAdmin(String cacId) throws IllegalAccessException { + String isAdminQuery = "SELECT * FROM FORMS_USER_ACCESS " + + "WHERE USER_ID='" + cacId + "' " + + "AND INSTANCE_NAME='ADMIN' " + + "LIMIT 1;"; + + IRawSelectWrapper wrapper = WrapperManager.getInstance().getRawWrapper(getEngine(), isAdminQuery); try { - while(rs.next()) { - userAccessableInstances.put(rs.getString("INSTANCE_NAME"), rs.getString("IS_SYS_ADMIN")); + if(!wrapper.hasNext()) { + throw new IllegalAccessException("User is not an admin and cannot perform this operation"); } - } catch (SQLException e) { - e.printStackTrace(); } finally { - try { - if(rs != null) { - rs.close(); - } - if(stmt != null) { - stmt.close(); - } - } catch (SQLException e) { - e.printStackTrace(); + wrapper.cleanUp(); + } + } + + /** + * Check that user is an admin + * @param cacId + * @throws IllegalAccessException + */ + private void throwErrorIfNotSysAdmin(String cacId, String system) throws IllegalAccessException { + String isAdminQuery = "SELECT * FROM FORMS_USER_ACCESS " + + "WHERE USER_ID='" + cacId + "' " + + "AND INSTANCE_NAME='" + system + "' " + + "AND IS_SYS_ADMIN=TRUE " + + "LIMIT 1;"; + + IRawSelectWrapper wrapper = WrapperManager.getInstance().getRawWrapper(getEngine(), isAdminQuery); + try { + if(!wrapper.hasNext()) { + throw new IllegalAccessException("User is not an admin and cannot perform this operation"); } + } finally { + wrapper.cleanUp(); } - - Map returnData = new Hashtable(); - returnData.put("cac_id", x509Id); - returnData.put("validInstances", userAccessableInstances); - - return WebUtility.getResponse(returnData, 200); + } + + + /** + * Get the form engine + * Since this is a resource, we just need to make sure we load + * after DBLoader is done loading + * @return + */ + public IEngine getEngine() { + if(formEngine == null) { + formEngine = Utility.getEngine(FormBuilder.FORM_BUILDER_ENGINE_NAME); + } + return formEngine; } } diff --git a/src/prerna/semoss/web/services/NameServer.java b/src/prerna/semoss/web/services/NameServer.java index 78ce3ffe0..33499c261 100644 --- a/src/prerna/semoss/web/services/NameServer.java +++ b/src/prerna/semoss/web/services/NameServer.java @@ -74,6 +74,7 @@ import com.google.gson.internal.StringMap; import com.google.gson.reflect.TypeToken; +import prerna.auth.AbstractSecurityUtils; import prerna.auth.SecurityQueryUtils; import prerna.auth.User; import prerna.engine.api.IEngine; @@ -698,9 +699,7 @@ public StreamingOutput getMediaWikiTagsForSearchTerm(@QueryParam("searchTerm") S // gets the engine resource necessary for all engine calls @Path("e-{engine}") public Object getLocalDatabase(@Context HttpServletRequest request, @PathParam("engine") String engineId, @QueryParam("api") String api) throws IOException { - Object securityObj = DIHelper.getInstance().getLocalProp(Constants.SECURITY_ENABLED); - boolean security = (securityObj instanceof Boolean && ((boolean) securityObj) ) || (Boolean.parseBoolean(securityObj.toString())); - + boolean security = AbstractSecurityUtils.securityEnabled(); if(security) { HttpSession session = request.getSession(false); if(session == null) { From f29b1e9474c50b5768fcb618a682b19e01f19853 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 6 Sep 2018 20:51:09 +0000 Subject: [PATCH 0221/1906] UPDATE :: Trying to reduce redundant guava jars git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29931 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 2dfa5df9adde9332e4eca51f9d75a6a69cd95a7f --- pom.xml | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/pom.xml b/pom.xml index 774deeb31..4eee7b1bd 100644 --- a/pom.xml +++ b/pom.xml @@ -841,6 +841,12 @@ com.google.guava guava-collections r03 + + + * + * + + com.github.spullara.mustache.java @@ -2722,12 +2728,14 @@ jmespath-jackson 0.2.0 - + + - + + + + - + + - + + io.burt jmespath-jackson From ade9652ab1a3edd0e1afbc1321a3dac1182831c0 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 7 Sep 2018 18:11:23 +0000 Subject: [PATCH 0224/1906] UPDATE ::: Removing google http client git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29941 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: d0ac76f878e0927dbe36646ca5d3d3f57f6ab57c --- pom.xml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index f1a4d3934..b7c9b714f 100644 --- a/pom.xml +++ b/pom.xml @@ -840,7 +840,7 @@ - + com.github.spullara.mustache.java compiler @@ -2839,6 +2839,12 @@ io.minio minio 4.0.2 + + + com.google.http-client + google-http-client-xml + + From 2f7d782d041ae9c922d8000b1b6bc129104edb28 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 10 Sep 2018 11:42:03 +0000 Subject: [PATCH 0225/1906] UPDATE ::: Adding redirect in CACFilter git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29951 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 81eb460b69c1e236d544f1831bfe6618463320f6 --- src/prerna/semoss/web/form/FormResource.java | 3 ++- src/prerna/web/conf/CACFilter.java | 8 +++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/prerna/semoss/web/form/FormResource.java b/src/prerna/semoss/web/form/FormResource.java index 4cf16d6ef..dbb271e37 100644 --- a/src/prerna/semoss/web/form/FormResource.java +++ b/src/prerna/semoss/web/form/FormResource.java @@ -24,6 +24,7 @@ import prerna.forms.FormFactory; import prerna.nameserver.utility.MasterDatabaseUtility; import prerna.rdf.engine.wrappers.WrapperManager; +import prerna.util.Constants; import prerna.util.Utility; import prerna.web.services.util.WebUtility; @@ -192,7 +193,7 @@ private String getCacId(@Context HttpServletRequest request) throws IOException String x509Id = null; try { HttpSession session = ((HttpServletRequest)request).getSession(false); - User user = (User) session.getAttribute("semoss_user"); + User user = (User) session.getAttribute(Constants.SESSION_USER); x509Id = user.getAccessToken(AuthProvider.CAC).getId(); } catch(Exception e) { throw new IOException("Could not identify user"); diff --git a/src/prerna/web/conf/CACFilter.java b/src/prerna/web/conf/CACFilter.java index eec36e68e..75f8f6188 100644 --- a/src/prerna/web/conf/CACFilter.java +++ b/src/prerna/web/conf/CACFilter.java @@ -17,6 +17,7 @@ import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.apache.log4j.LogManager; @@ -133,7 +134,12 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 } if(session.getAttribute(Constants.SESSION_USER) == null) { - LOGGER.error("COULDN'T AUTHORIZE USER!"); + ((HttpServletResponse) arg1).setStatus(302); + + String redirectUrl = ((HttpServletRequest) arg0).getHeader("referer"); + redirectUrl = redirectUrl + "#!/login"; + ((HttpServletResponse) arg1).setHeader("redirect", redirectUrl); + ((HttpServletResponse) arg1).sendError(302, "Need to redirect to " + redirectUrl); return; } From 8b88a7a1b948b900c8a0f69594cbcf4971a12e93 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 10 Sep 2018 20:02:46 +0000 Subject: [PATCH 0226/1906] UPDATE ::: Starting to create a security admin utils git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29974 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: c290b7db4c5d3abd9d6451a8fb16d2e5b1ccaf74 --- .../web/services/AuthorizationResource.java | 440 ++++++++++-------- .../semoss/web/services/UserResource.java | 3 +- 2 files changed, 248 insertions(+), 195 deletions(-) diff --git a/src/prerna/semoss/web/services/AuthorizationResource.java b/src/prerna/semoss/web/services/AuthorizationResource.java index fd949b250..e3028190a 100644 --- a/src/prerna/semoss/web/services/AuthorizationResource.java +++ b/src/prerna/semoss/web/services/AuthorizationResource.java @@ -27,6 +27,7 @@ *******************************************************************************/ package prerna.semoss.web.services; +import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.Hashtable; @@ -49,6 +50,8 @@ import com.google.gson.Gson; import com.google.gson.internal.StringMap; +import prerna.auth.AbstractSecurityUtils; +import prerna.auth.SecurityAdminUtils; import prerna.auth.SecurityQueryUtils; import prerna.auth.SecurityUpdateUtils; import prerna.auth.User; @@ -58,6 +61,26 @@ @Path("/authorization") public class AuthorizationResource { + /** + * Get the user + * @param request + * @return + * @throws IOException + */ + private User getUser(@Context HttpServletRequest request) throws IllegalAccessException { + HttpSession session = request.getSession(false); + if(session == null){ + throw new IllegalAccessException("User session is invalid"); + } + + User user = (User) session.getAttribute(Constants.SESSION_USER); + if(user == null) { + throw new IllegalAccessException("User session is invalid"); + } + + return user; + } + /** * Check if the security is enabled in the application. * @return true or false @@ -66,33 +89,15 @@ public class AuthorizationResource { @Produces("application/json") @Path("securityEnabled") public StreamingOutput isSecurityEnabled(@Context ServletContext context) { - boolean securityEnabled = Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED)); - return WebUtility.getSO(securityEnabled); + return WebUtility.getSO(AbstractSecurityUtils.securityEnabled()); } + ////////////////////////////////////////////// + ////////////////////////////////////////////// - /** - * Get all the grous the user is part of. - * @param request - * @return get all groups the user is part of + /* + * General methods */ - @GET - @Produces("application/json") - @Path("getGroups") - public Response getGroupsAndMembers(@Context HttpServletRequest request) { - HttpSession session = request.getSession(false); - if(session == null){ - Map errorMap = new HashMap(); - errorMap.put("error", "User session is invalid"); - return WebUtility.getResponse(errorMap, 401); - } - - User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - String userId = user.getAccessToken(user.getLogins().get(0)).getId(); - List> ret = SecurityQueryUtils.getGroupsAndMembersForUser(userId); - - return WebUtility.getResponse(ret, 200); - } @GET @Produces("application/json") @@ -135,6 +140,54 @@ public Response getDatabases(@Context HttpServletRequest request) { } } + ////////////////////////////////////////////// + ////////////////////////////////////////////// + + /* + * Admin methods + */ + + @GET + @Path("/admin/isAdminUser") + public Response isAdminUser(@Context HttpServletRequest request) { + User user = null; + try { + user = getUser(request); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap(); + errorMap.put("error", "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + + boolean isAdmin = SecurityAdminUtils.userIsAdmin(user); + return WebUtility.getResponse(isAdmin, 200); + } + + // TODO: why is this not admin!!! + @GET + @Path("/getAllDbUsers") + @Produces("application/json") + public Response getAllUsers(@Context HttpServletRequest request) { + User user = null; + try { + user = getUser(request); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap(); + errorMap.put("error", "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + + SecurityAdminUtils adminUtils = SecurityAdminUtils.getInstance(user); + if(adminUtils == null) { + Map retMap = new Hashtable(); + retMap.put("error", "User does not have admin priviledges"); + return WebUtility.getResponse(retMap, 400); + } + + List> ret = adminUtils.getAllUsers(user); + return WebUtility.getResponse(ret, 200); + } + /** * Get databases the user has access to * @param request @@ -161,35 +214,94 @@ public Response getAdminDatabases(@Context HttpServletRequest request) { return WebUtility.getResponse(errorRet, 500); } } + - /** - * Get groups and user of database - * @param request - * @return Groups and user of a specific database - */ @POST @Produces("application/json") - @Path("/admin/getDatabaseUsersAndGroups") - public Response getAdminDatabaseUsersAndGroups(@Context HttpServletRequest request, MultivaluedMap form) { + @Path("/admin/registerUser") + public Response registerUser(@Context HttpServletRequest request, MultivaluedMap form) { Hashtable errorRet = new Hashtable(); - Map>> ret = new HashMap<>(); + boolean success = false; try{ User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - String userId = user.getAccessToken(user.getLogins().get(0)).getId(); - String engineId = form.getFirst("engineId"); - ret = SecurityQueryUtils.getDatabaseUsersAndGroups(userId, engineId, true); - return WebUtility.getResponse(ret, 200); + + String newUserId = form.getFirst("userId"); + Boolean newUserAdmin = Boolean.parseBoolean(form.getFirst("admin")); + + if(SecurityQueryUtils.userIsAdmin(user)){ + success = SecurityUpdateUtils.registerUser(newUserId, newUserAdmin); + } else { + errorRet.put("error", "The user doesn't have the permissions to perform this action."); + return WebUtility.getResponse(errorRet, 400); + } } catch (IllegalArgumentException e){ e.printStackTrace(); errorRet.put("error", e.getMessage()); + return WebUtility.getResponse(errorRet, 400); + } catch (Exception e){ + e.printStackTrace(); + errorRet.put("error", "An unexpected error happened. Please try again."); return WebUtility.getResponse(errorRet, 500); + } + return WebUtility.getResponse(success, 200); + } + + @POST + @Produces("application/json") + @Path("/admin/deleteUser") + public Response deleteUser(@Context HttpServletRequest request, MultivaluedMap form) { + Hashtable errorRet = new Hashtable(); + try{ + User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); + String adminId = user.getAccessToken(user.getLogins().get(0)).getId(); + String userId = form.getFirst("userId"); + SecurityUpdateUtils.deleteUser(adminId, userId); + if(adminId.equals(userId)){ + request.getSession().invalidate(); + } + } catch (IllegalArgumentException e){ + e.printStackTrace(); + errorRet.put("error", e.getMessage()); + return WebUtility.getResponse(errorRet, 400); } catch (Exception e){ e.printStackTrace(); errorRet.put("error", "An unexpected error happened. Please try again."); return WebUtility.getResponse(errorRet, 500); } + return WebUtility.getResponse(true, 200); + } + + @POST + @Produces("application/json") + @Path("/admin/savePermissions") + public Response savePermissionsAdmin(@Context HttpServletRequest request, MultivaluedMap form) { + Gson gson = new Gson(); + Map errorRet = new Hashtable(); + + try{ + User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); + String userId = user.getAccessToken(user.getLogins().get(0)).getId(); + String engineId = form.getFirst("engineId").trim(); + Map>> groups = gson.fromJson(form.getFirst("groups"), StringMap.class); + Map>> users = gson.fromJson(form.getFirst("users"), StringMap.class); + SecurityUpdateUtils.savePermissions(userId, true, engineId, groups, users); + } catch(IllegalArgumentException e){ + errorRet.put("error", e.getMessage()); + return WebUtility.getResponse(errorRet, 400); + } catch(Exception e){ + e.printStackTrace(); + errorRet.put("error", "An unexpected error happened. Please try again."); + return WebUtility.getResponse(errorRet, 500); + } + + return WebUtility.getResponse(true, 200); } + + ////////////////////////////////////////////// + ////////////////////////////////////////////// + + /** * Get the groups and users directly associated with * the database requested that the user has access to. @@ -219,61 +331,7 @@ public Response getDatabaseUsersAndGroups(@Context HttpServletRequest request, M } } - @POST - @Produces("application/json") - @Path("addGroup") - public Response addNewGroup(@Context HttpServletRequest request, MultivaluedMap form) { - Gson gson = new Gson(); - List users = gson.fromJson(form.getFirst("users"), ArrayList.class); - User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - String userId = user.getAccessToken(user.getLogins().get(0)).getId(); - Boolean success = SecurityUpdateUtils.addGroup(userId, form.getFirst("groupName").trim(), users); - - if(success) { - return WebUtility.getResponse(success, 200); - } else { - return WebUtility.getResponse(success, 400); - } - } - - @POST - @Produces("application/json") - @Path("removeGroup") - public Response removeGroup(@Context HttpServletRequest request, MultivaluedMap form) { - String groupId = form.getFirst("groupId").trim(); - User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - String userId = user.getAccessToken(user.getLogins().get(0)).getId(); - Boolean success = SecurityUpdateUtils.removeGroup(userId, groupId); - - if(success) { - return WebUtility.getResponse(success, 200); - } else { - return WebUtility.getResponse(success, 400); - } - } - - @POST - @Produces("application/json") - @Path("editGroup") - public Response editGroup(@Context HttpServletRequest request, MultivaluedMap form) { - Gson gson = new Gson(); - - String groupId = form.getFirst("groupId").trim(); - List toAdd = gson.fromJson(form.getFirst("add"), ArrayList.class); - List toRemove = gson.fromJson(form.getFirst("remove"), ArrayList.class); - - User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - String userId = user.getAccessToken(user.getLogins().get(0)).getId(); - - for(String add : toAdd) { - SecurityUpdateUtils.addUserToGroup(userId, groupId, add); - } - - for(String remove : toRemove) { - SecurityUpdateUtils.removeUserFromGroup(userId, groupId, remove); - } - return WebUtility.getResponse(true, 200); - } + @POST @Produces("application/json") @@ -378,48 +436,6 @@ public Response isUserAddedToGroupValid(@Context HttpServletRequest request, Mul } } - @GET - @Path("/admin/isAdminUser") - public Response isAdminUser(@Context HttpServletRequest request) { - - HttpSession session = request.getSession(false); - if(session == null){ - Map errorMap = new HashMap(); - errorMap.put("error", "User session is invalid"); - return WebUtility.getResponse(errorMap, 401); - } - - if(session.getAttribute(Constants.SESSION_USER) != null) { - User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - String userId = user.getAccessToken(user.getLogins().get(0)).getId(); - if(!userId.equals(Constants.ANONYMOUS_USER_ID) && SecurityQueryUtils.isUserAdmin(userId)) { - return WebUtility.getResponse(true, 200); - } - } - - return WebUtility.getResponse(false, 200); - } - - @GET - @Path("/getAllDbUsers") - @Produces("application/json") - public Response getAllDbUsers(@Context HttpServletRequest request) { - List> ret = new ArrayList<>(); - Map errorRet = new Hashtable(); - User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - String userId = user.getAccessToken(user.getLogins().get(0)).getId(); - try{ - ret = SecurityQueryUtils.getAllDbUsers(userId); - } catch (IllegalArgumentException e){ - e.printStackTrace(); - errorRet.put("error", e.getMessage()); - } catch (Exception e){ - e.printStackTrace(); - errorRet.put("error", "An unexpected error happened. Please try again."); - } - return WebUtility.getResponse(ret, 200); - } - @POST @Path("/removeDatabaseAccess") @Produces("application/json") @@ -471,31 +487,7 @@ public Response editUser(@Context HttpServletRequest request, MultivaluedMap form) { - Gson gson = new Gson(); - Map errorRet = new Hashtable(); - - try{ - User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - String userId = user.getAccessToken(user.getLogins().get(0)).getId(); - String engineId = form.getFirst("engineId").trim(); - Map>> groups = gson.fromJson(form.getFirst("groups"), StringMap.class); - Map>> users = gson.fromJson(form.getFirst("users"), StringMap.class); - SecurityUpdateUtils.savePermissions(userId, true, engineId, groups, users); - } catch(IllegalArgumentException e){ - errorRet.put("error", e.getMessage()); - return WebUtility.getResponse(errorRet, 400); - } catch(Exception e){ - e.printStackTrace(); - errorRet.put("error", "An unexpected error happened. Please try again."); - return WebUtility.getResponse(errorRet, 500); - } - - return WebUtility.getResponse(true, 200); - } + @POST @Produces("application/json") @@ -566,61 +558,123 @@ public Response setDbPublic(@Context HttpServletRequest request, MultivaluedMap< return WebUtility.getResponse(true, 200); } + + ///////////////////////////////////////////////// + ///////////////////////////////////////////////// + + /* + * Groups + */ + + /** + * Get groups and user of database + * @param request + * @return Groups and user of a specific database + */ @POST @Produces("application/json") - @Path("/admin/registerUser") - public Response registerUser(@Context HttpServletRequest request, MultivaluedMap form) { + @Path("/admin/getDatabaseUsersAndGroups") + public Response getAdminDatabaseUsersAndGroups(@Context HttpServletRequest request, MultivaluedMap form) { Hashtable errorRet = new Hashtable(); - boolean success = false; + Map>> ret = new HashMap<>(); try{ User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - String adminId = user.getAccessToken(user.getLogins().get(0)).getId(); - - String userId = form.getFirst("userId"); - Boolean adminUser = Boolean.parseBoolean(form.getFirst("admin")); - if(SecurityQueryUtils.isUserAdmin(adminId)){ - success = SecurityUpdateUtils.registerUser(userId, adminUser); - } else { - errorRet.put("error", "The user doesn't have the permissions to perform this action."); - return WebUtility.getResponse(errorRet, 400); - } + String userId = user.getAccessToken(user.getLogins().get(0)).getId(); + String engineId = form.getFirst("engineId"); + ret = SecurityQueryUtils.getDatabaseUsersAndGroups(userId, engineId, true); + return WebUtility.getResponse(ret, 200); } catch (IllegalArgumentException e){ e.printStackTrace(); errorRet.put("error", e.getMessage()); - return WebUtility.getResponse(errorRet, 400); + return WebUtility.getResponse(errorRet, 500); } catch (Exception e){ e.printStackTrace(); errorRet.put("error", "An unexpected error happened. Please try again."); return WebUtility.getResponse(errorRet, 500); } - return WebUtility.getResponse(success, 200); } - + + /** + * Get all the grous the user is part of. + * @param request + * @return get all groups the user is part of + */ + @GET + @Produces("application/json") + @Path("getGroups") + public Response getGroupsAndMembers(@Context HttpServletRequest request) { + User user = null; + try { + user = getUser(request); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap(); + errorMap.put("error", e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + + String userId = user.getAccessToken(user.getLogins().get(0)).getId(); + List> ret = SecurityQueryUtils.getGroupsAndMembersForUser(userId); + return WebUtility.getResponse(ret, 200); + } + @POST @Produces("application/json") - @Path("/admin/deleteUser") - public Response deleteUser(@Context HttpServletRequest request, MultivaluedMap form) { - Hashtable errorRet = new Hashtable(); - try{ - User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - String adminId = user.getAccessToken(user.getLogins().get(0)).getId(); - String userId = form.getFirst("userId"); - SecurityUpdateUtils.deleteUser(adminId, userId); - if(adminId.equals(userId)){ - request.getSession().invalidate(); - } - } catch (IllegalArgumentException e){ - e.printStackTrace(); - errorRet.put("error", e.getMessage()); - return WebUtility.getResponse(errorRet, 400); - } catch (Exception e){ - e.printStackTrace(); - errorRet.put("error", "An unexpected error happened. Please try again."); - return WebUtility.getResponse(errorRet, 500); + @Path("addGroup") + public Response addNewGroup(@Context HttpServletRequest request, MultivaluedMap form) { + Gson gson = new Gson(); + List users = gson.fromJson(form.getFirst("users"), ArrayList.class); + User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); + String userId = user.getAccessToken(user.getLogins().get(0)).getId(); + Boolean success = SecurityUpdateUtils.addGroup(userId, form.getFirst("groupName").trim(), users); + + if(success) { + return WebUtility.getResponse(success, 200); + } else { + return WebUtility.getResponse(success, 400); + } + } + + @POST + @Produces("application/json") + @Path("removeGroup") + public Response removeGroup(@Context HttpServletRequest request, MultivaluedMap form) { + String groupId = form.getFirst("groupId").trim(); + User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); + String userId = user.getAccessToken(user.getLogins().get(0)).getId(); + Boolean success = SecurityUpdateUtils.removeGroup(userId, groupId); + + if(success) { + return WebUtility.getResponse(success, 200); + } else { + return WebUtility.getResponse(success, 400); + } + } + + @POST + @Produces("application/json") + @Path("editGroup") + public Response editGroup(@Context HttpServletRequest request, MultivaluedMap form) { + Gson gson = new Gson(); + + String groupId = form.getFirst("groupId").trim(); + List toAdd = gson.fromJson(form.getFirst("add"), ArrayList.class); + List toRemove = gson.fromJson(form.getFirst("remove"), ArrayList.class); + + User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); + String userId = user.getAccessToken(user.getLogins().get(0)).getId(); + + for(String add : toAdd) { + SecurityUpdateUtils.addUserToGroup(userId, groupId, add); + } + + for(String remove : toRemove) { + SecurityUpdateUtils.removeUserFromGroup(userId, groupId, remove); } return WebUtility.getResponse(true, 200); } - + + + /////////////////////////////////////////// /////////////////////////////////////////// /////////////////////////////////////////// diff --git a/src/prerna/semoss/web/services/UserResource.java b/src/prerna/semoss/web/services/UserResource.java index 57fea8a88..f934b24b1 100644 --- a/src/prerna/semoss/web/services/UserResource.java +++ b/src/prerna/semoss/web/services/UserResource.java @@ -1405,8 +1405,7 @@ public Response setUserRegistration(@Context HttpServletRequest request) throws Hashtable errorRet = new Hashtable(); try { User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - String userId = user.getAccessToken(user.getLogins().get(0)).getId(); - if(SecurityQueryUtils.isUserAdmin(userId)){ + if(SecurityQueryUtils.userIsAdmin(user)){ String user_reg = request.getParameter("user_reg"); PropertiesConfiguration config = new PropertiesConfiguration(DIHelper.getInstance().getProperty("SOCIAL")); socialData.setProperty("reg_allowed", user_reg); From a9b1061e5f539fbae57b3434abad63ac70399418 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 11 Sep 2018 11:18:14 +0000 Subject: [PATCH 0227/1906] UPDATE ::: Creating separate package for security utils git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29983 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 83a2e68e5ab901d66de3babe275b710c72e3855e --- src/prerna/semoss/web/services/AdminConfigService.java | 2 +- src/prerna/semoss/web/services/AppResource.java | 2 +- src/prerna/semoss/web/services/AuthorizationResource.java | 8 ++++---- src/prerna/semoss/web/services/NameServer.java | 4 ++-- src/prerna/semoss/web/services/UserResource.java | 4 ++-- src/prerna/upload/DatabaseUploader.java | 2 +- src/prerna/upload/ImageUploader.java | 2 +- src/prerna/web/conf/CACFilter.java | 2 +- src/prerna/web/conf/UserRestrictionFilter.java | 2 +- 9 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/prerna/semoss/web/services/AdminConfigService.java b/src/prerna/semoss/web/services/AdminConfigService.java index 03cdf59e1..8ab043b5f 100644 --- a/src/prerna/semoss/web/services/AdminConfigService.java +++ b/src/prerna/semoss/web/services/AdminConfigService.java @@ -17,7 +17,7 @@ import com.google.gson.Gson; -import prerna.auth.SecurityUpdateUtils; +import prerna.auth.utils.SecurityUpdateUtils; import prerna.web.conf.AdminStartupFilter; import prerna.web.services.util.WebUtility; diff --git a/src/prerna/semoss/web/services/AppResource.java b/src/prerna/semoss/web/services/AppResource.java index 7238ebdba..bf4988fc8 100644 --- a/src/prerna/semoss/web/services/AppResource.java +++ b/src/prerna/semoss/web/services/AppResource.java @@ -24,7 +24,7 @@ import org.apache.commons.io.IOUtils; import org.apache.commons.io.filefilter.WildcardFileFilter; -import prerna.auth.AbstractSecurityUtils; +import prerna.auth.utils.AbstractSecurityUtils; import prerna.engine.impl.SmssUtilities; import prerna.nameserver.utility.MasterDatabaseUtility; import prerna.sablecc2.reactor.utils.ImageCaptureReactor; diff --git a/src/prerna/semoss/web/services/AuthorizationResource.java b/src/prerna/semoss/web/services/AuthorizationResource.java index e3028190a..38fc1fd7d 100644 --- a/src/prerna/semoss/web/services/AuthorizationResource.java +++ b/src/prerna/semoss/web/services/AuthorizationResource.java @@ -50,11 +50,11 @@ import com.google.gson.Gson; import com.google.gson.internal.StringMap; -import prerna.auth.AbstractSecurityUtils; -import prerna.auth.SecurityAdminUtils; -import prerna.auth.SecurityQueryUtils; -import prerna.auth.SecurityUpdateUtils; import prerna.auth.User; +import prerna.auth.utils.AbstractSecurityUtils; +import prerna.auth.utils.SecurityAdminUtils; +import prerna.auth.utils.SecurityQueryUtils; +import prerna.auth.utils.SecurityUpdateUtils; import prerna.util.Constants; import prerna.web.services.util.WebUtility; diff --git a/src/prerna/semoss/web/services/NameServer.java b/src/prerna/semoss/web/services/NameServer.java index 33499c261..e1be26344 100644 --- a/src/prerna/semoss/web/services/NameServer.java +++ b/src/prerna/semoss/web/services/NameServer.java @@ -74,9 +74,9 @@ import com.google.gson.internal.StringMap; import com.google.gson.reflect.TypeToken; -import prerna.auth.AbstractSecurityUtils; -import prerna.auth.SecurityQueryUtils; import prerna.auth.User; +import prerna.auth.utils.AbstractSecurityUtils; +import prerna.auth.utils.SecurityQueryUtils; import prerna.engine.api.IEngine; import prerna.engine.impl.rdf.RemoteSemossSesameEngine; import prerna.insights.admin.DBAdminResource; diff --git a/src/prerna/semoss/web/services/UserResource.java b/src/prerna/semoss/web/services/UserResource.java index f934b24b1..903a5732a 100644 --- a/src/prerna/semoss/web/services/UserResource.java +++ b/src/prerna/semoss/web/services/UserResource.java @@ -72,9 +72,9 @@ import prerna.auth.AccessToken; import prerna.auth.AppTokens; import prerna.auth.AuthProvider; -import prerna.auth.SecurityQueryUtils; -import prerna.auth.SecurityUpdateUtils; import prerna.auth.User; +import prerna.auth.utils.SecurityQueryUtils; +import prerna.auth.utils.SecurityUpdateUtils; import prerna.io.connector.IConnectorIOp; import prerna.io.connector.google.GoogleEntityResolver; import prerna.io.connector.google.GoogleFileRetriever; diff --git a/src/prerna/upload/DatabaseUploader.java b/src/prerna/upload/DatabaseUploader.java index 2800e371b..59903cace 100644 --- a/src/prerna/upload/DatabaseUploader.java +++ b/src/prerna/upload/DatabaseUploader.java @@ -33,8 +33,8 @@ import com.google.gson.reflect.TypeToken; import prerna.auth.AuthProvider; -import prerna.auth.SecurityUpdateUtils; import prerna.auth.User; +import prerna.auth.utils.SecurityUpdateUtils; import prerna.engine.impl.SmssUtilities; import prerna.nameserver.AddToMasterDB; import prerna.om.Insight; diff --git a/src/prerna/upload/ImageUploader.java b/src/prerna/upload/ImageUploader.java index 7f52a2938..5dc43230e 100644 --- a/src/prerna/upload/ImageUploader.java +++ b/src/prerna/upload/ImageUploader.java @@ -18,8 +18,8 @@ import org.apache.commons.fileupload.FileItem; import org.apache.commons.io.filefilter.WildcardFileFilter; -import prerna.auth.SecurityQueryUtils; import prerna.auth.User; +import prerna.auth.utils.SecurityQueryUtils; import prerna.engine.impl.SmssUtilities; import prerna.nameserver.utility.MasterDatabaseUtility; import prerna.util.Constants; diff --git a/src/prerna/web/conf/CACFilter.java b/src/prerna/web/conf/CACFilter.java index 75f8f6188..32612c3ee 100644 --- a/src/prerna/web/conf/CACFilter.java +++ b/src/prerna/web/conf/CACFilter.java @@ -25,8 +25,8 @@ import prerna.auth.AccessToken; import prerna.auth.AuthProvider; -import prerna.auth.SecurityUpdateUtils; import prerna.auth.User; +import prerna.auth.utils.SecurityUpdateUtils; import prerna.util.Constants; public class CACFilter implements Filter { diff --git a/src/prerna/web/conf/UserRestrictionFilter.java b/src/prerna/web/conf/UserRestrictionFilter.java index 1aafb34de..f2f2e62cd 100644 --- a/src/prerna/web/conf/UserRestrictionFilter.java +++ b/src/prerna/web/conf/UserRestrictionFilter.java @@ -12,8 +12,8 @@ import javax.servlet.http.HttpSession; import prerna.auth.AccessToken; -import prerna.auth.SecurityQueryUtils; import prerna.auth.User; +import prerna.auth.utils.SecurityQueryUtils; import prerna.util.Constants; public class UserRestrictionFilter implements Filter { From f7b78ca5259c76e749085d028b017e7dcd671870 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 11 Sep 2018 12:07:21 +0000 Subject: [PATCH 0228/1906] BUGFIX ::: Fixing error with admin security settings sending back admin as string instead of boolean UPDATE ::: No longer loading twitter and google upon UserResouce instantiation for faster server startup UPDATE ::: No longer starting R on startup for faster server startup git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29984 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 2be4b74cd6f368e623ba1a9360f9d7c855305f60 --- .../web/services/AuthorizationResource.java | 66 +++--- .../semoss/web/services/UserResource.java | 214 +++++++++--------- src/prerna/web/conf/DBLoader.java | 12 +- 3 files changed, 146 insertions(+), 146 deletions(-) diff --git a/src/prerna/semoss/web/services/AuthorizationResource.java b/src/prerna/semoss/web/services/AuthorizationResource.java index 38fc1fd7d..614334e42 100644 --- a/src/prerna/semoss/web/services/AuthorizationResource.java +++ b/src/prerna/semoss/web/services/AuthorizationResource.java @@ -163,7 +163,7 @@ public Response isAdminUser(@Context HttpServletRequest request) { return WebUtility.getResponse(isAdmin, 200); } - // TODO: why is this not admin!!! + // TODO: why is this not /admin!!! @GET @Path("/getAllDbUsers") @Produces("application/json") @@ -184,10 +184,45 @@ public Response getAllUsers(@Context HttpServletRequest request) { return WebUtility.getResponse(retMap, 400); } - List> ret = adminUtils.getAllUsers(user); + List> ret = adminUtils.getAllUsers(user); return WebUtility.getResponse(ret, 200); } + @POST + @Produces("application/json") + @Path("/admin/deleteUser") + public Response deleteUser(@Context HttpServletRequest request, MultivaluedMap form) { + User user = null; + try { + user = getUser(request); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap(); + errorMap.put("error", "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + + SecurityAdminUtils adminUtils = SecurityAdminUtils.getInstance(user); + if(adminUtils == null) { + Map retMap = new Hashtable(); + retMap.put("error", "User does not have admin priviledges"); + return WebUtility.getResponse(retMap, 400); + } + + String userToDelete = form.getFirst("userId"); + boolean success = adminUtils.deleteUser(userToDelete); + return WebUtility.getResponse(success, 200); + } + + + ///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////// + + /** * Get databases the user has access to * @param request @@ -246,31 +281,6 @@ public Response registerUser(@Context HttpServletRequest request, MultivaluedMap return WebUtility.getResponse(success, 200); } - @POST - @Produces("application/json") - @Path("/admin/deleteUser") - public Response deleteUser(@Context HttpServletRequest request, MultivaluedMap form) { - Hashtable errorRet = new Hashtable(); - try{ - User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - String adminId = user.getAccessToken(user.getLogins().get(0)).getId(); - String userId = form.getFirst("userId"); - SecurityUpdateUtils.deleteUser(adminId, userId); - if(adminId.equals(userId)){ - request.getSession().invalidate(); - } - } catch (IllegalArgumentException e){ - e.printStackTrace(); - errorRet.put("error", e.getMessage()); - return WebUtility.getResponse(errorRet, 400); - } catch (Exception e){ - e.printStackTrace(); - errorRet.put("error", "An unexpected error happened. Please try again."); - return WebUtility.getResponse(errorRet, 500); - } - return WebUtility.getResponse(true, 200); - } - @POST @Produces("application/json") @Path("/admin/savePermissions") @@ -473,7 +483,7 @@ public Response editUser(@Context HttpServletRequest request, MultivaluedMap userInfo = gson.fromJson(form.getFirst("user"), HashMap.class); + Map userInfo = gson.fromJson(form.getFirst("user"), HashMap.class); ret = SecurityUpdateUtils.editUser(userId, userInfo); } catch (IllegalArgumentException e){ e.printStackTrace(); diff --git a/src/prerna/semoss/web/services/UserResource.java b/src/prerna/semoss/web/services/UserResource.java index 903a5732a..fa0786918 100644 --- a/src/prerna/semoss/web/services/UserResource.java +++ b/src/prerna/semoss/web/services/UserResource.java @@ -27,18 +27,13 @@ *******************************************************************************/ package prerna.semoss.web.services; -import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; -import java.util.ArrayList; -import java.util.Base64; import java.util.HashMap; import java.util.Hashtable; import java.util.List; @@ -58,13 +53,6 @@ import javax.ws.rs.core.Response; import org.apache.commons.configuration.PropertiesConfiguration; -import org.apache.http.NameValuePair; -import org.apache.http.client.entity.UrlEncodedFormEntity; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.message.BasicNameValuePair; import org.kohsuke.github.GHMyself; import org.kohsuke.github.GitHub; @@ -73,6 +61,7 @@ import prerna.auth.AppTokens; import prerna.auth.AuthProvider; import prerna.auth.User; +import prerna.auth.utils.NativeUserSecurityUtils; import prerna.auth.utils.SecurityQueryUtils; import prerna.auth.utils.SecurityUpdateUtils; import prerna.io.connector.IConnectorIOp; @@ -95,9 +84,9 @@ public class UserResource { private static Properties socialData = null; - private static AccessToken twitToken = null; - private static AccessToken googAppToken = null; - +// private static AccessToken twitToken = null; +// private static AccessToken googAppToken = null; + // private static ArrayList userEmails = new ArrayList(); // static { // String whitelistPath = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER) + "/db/" + Constants.SECURITY_DB + "/" + Constants.AUTH_WHITELIST_FILE; @@ -133,11 +122,12 @@ public class UserResource { fis = new FileInputStream(f); socialData.load(fis); - loginTwitterApp(); - loginGoogleApp(); +// loginTwitterApp(); +// loginGoogleApp(); // also make the twit token and such - AppTokens.getInstance().setAccessToken(twitToken); - AppTokens.getInstance().setAccessToken(googAppToken); +// AppTokens.getInstance().setAccessToken(twitToken); +// AppTokens.getInstance().setAccessToken(googAppToken); + AppTokens.setSocial(socialData); } } catch (FileNotFoundException e) { e.printStackTrace(); @@ -156,92 +146,92 @@ public class UserResource { } } - private static void loginTwitterApp() throws IOException { - // getting the bearer token on twitter for app authentication is a lot simpler - // need to just combine the id and secret - // base 64 and send as authorization - - InputStream is = null; - InputStreamReader isr = null; - BufferedReader rd = null; - if(twitToken == null) { - try { - String prefix = "twitter_"; - String clientId = "***REMOVED***"; - String clientSecret = "***REMOVED***"; - if(socialData.containsKey(prefix+"client_id")) { - clientId = socialData.getProperty(prefix+"client_id"); - } - if(socialData.containsKey(prefix+"secret_key")) { - clientSecret = socialData.getProperty(prefix+"secret_key"); - } - - // make a joint string - String jointString = clientId + ":" + clientSecret; - - // encde this base 64 - String encodedJointString = new String(Base64.getEncoder().encode(jointString.getBytes())); - CloseableHttpClient httpclient = HttpClients.createDefault(); - HttpPost httppost = new HttpPost("https://api.twitter.com/oauth2/token"); - httppost.addHeader("Authorization", "Basic " + encodedJointString); - - List paramList = new ArrayList(); - paramList.add(new BasicNameValuePair("grant_type", "client_credentials")); - httppost.setEntity(new UrlEncodedFormEntity(paramList)); - - CloseableHttpResponse authResp = httpclient.execute(httppost); - - System.out.println("Response Code " + authResp.getStatusLine().getStatusCode()); - - is = authResp.getEntity().getContent(); - isr = new InputStreamReader(is); - rd = new BufferedReader(isr); - StringBuffer result = new StringBuffer(); - String line = ""; - while ((line = rd.readLine()) != null) { - result.append(line); - } - - twitToken = AbstractHttpHelper.getJAccessToken(result.toString()); - twitToken.setProvider(AuthProvider.TWITTER); - } catch(Exception ex) { - ex.printStackTrace(); - } finally { - if(is != null) { - try { - is.close(); - } catch(IOException e) { - // ignore - } - } - if(isr != null) { - try { - isr.close(); - } catch(IOException e) { - // ignore - } - } - if(rd != null) { - try { - rd.close(); - } catch(IOException e) { - // ignore - } - } - } - System.out.println("Access Token is.. " + twitToken.getAccess_token()); - } - } - - private static void loginGoogleApp() { - // nothing big here - // set the name on accesstoken - if(googAppToken == null) { - googAppToken = new AccessToken(); - googAppToken.setAccess_token(socialData.getProperty("google_maps_api")); - googAppToken.setProvider(AuthProvider.GOOGLE_MAP); - } - } +// private static void loginTwitterApp() { +// // getting the bearer token on twitter for app authentication is a lot simpler +// // need to just combine the id and secret +// // base 64 and send as authorization +// +// InputStream is = null; +// InputStreamReader isr = null; +// BufferedReader rd = null; +// if(twitToken == null) { +// try { +// String prefix = "twitter_"; +// String clientId = "***REMOVED***"; +// String clientSecret = "***REMOVED***"; +// if(socialData.containsKey(prefix+"client_id")) { +// clientId = socialData.getProperty(prefix+"client_id"); +// } +// if(socialData.containsKey(prefix+"secret_key")) { +// clientSecret = socialData.getProperty(prefix+"secret_key"); +// } +// +// // make a joint string +// String jointString = clientId + ":" + clientSecret; +// +// // encde this base 64 +// String encodedJointString = new String(Base64.getEncoder().encode(jointString.getBytes())); +// CloseableHttpClient httpclient = HttpClients.createDefault(); +// HttpPost httppost = new HttpPost("https://api.twitter.com/oauth2/token"); +// httppost.addHeader("Authorization", "Basic " + encodedJointString); +// +// List paramList = new ArrayList(); +// paramList.add(new BasicNameValuePair("grant_type", "client_credentials")); +// httppost.setEntity(new UrlEncodedFormEntity(paramList)); +// +// CloseableHttpResponse authResp = httpclient.execute(httppost); +// +// System.out.println("Response Code " + authResp.getStatusLine().getStatusCode()); +// +// is = authResp.getEntity().getContent(); +// isr = new InputStreamReader(is); +// rd = new BufferedReader(isr); +// StringBuffer result = new StringBuffer(); +// String line = ""; +// while ((line = rd.readLine()) != null) { +// result.append(line); +// } +// +// twitToken = AbstractHttpHelper.getJAccessToken(result.toString()); +// twitToken.setProvider(AuthProvider.TWITTER); +// } catch(Exception ex) { +// ex.printStackTrace(); +// } finally { +// if(is != null) { +// try { +// is.close(); +// } catch(IOException e) { +// // ignore +// } +// } +// if(isr != null) { +// try { +// isr.close(); +// } catch(IOException e) { +// // ignore +// } +// } +// if(rd != null) { +// try { +// rd.close(); +// } catch(IOException e) { +// // ignore +// } +// } +// } +// System.out.println("Access Token is.. " + twitToken.getAccess_token()); +// } +// } +// +// private static void loginGoogleApp() { +// // nothing big here +// // set the name on accesstoken +// if(googAppToken == null) { +// googAppToken = new AccessToken(); +// googAppToken.setAccess_token(socialData.getProperty("google_maps_api")); +// googAppToken.setProvider(AuthProvider.GOOGLE_MAP); +// } +// } @GET @Path("logins") @@ -295,12 +285,12 @@ private void addAccessToken(AccessToken token, HttpServletRequest request) { semossUser = (User)user; } else { semossUser = new User(); - if(twitToken != null) { - semossUser.setGlobalAccessToken(twitToken); - } - if(googAppToken != null) { - semossUser.setGlobalAccessToken(googAppToken); - } +// if(twitToken != null) { +// semossUser.setGlobalAccessToken(twitToken); +// } +// if(googAppToken != null) { +// semossUser.setGlobalAccessToken(googAppToken); +// } } semossUser.setAccessToken(token); request.getSession().setAttribute(Constants.SESSION_USER, semossUser); @@ -1369,7 +1359,7 @@ public Response createUser(@Context HttpServletRequest request) { newUser.setEmail(email); newUser.setName(name); newUser.setUsername(username); - boolean userCreated = SecurityUpdateUtils.addNativeUser(newUser, password); + boolean userCreated = NativeUserSecurityUtils.addNativeUser(newUser, password); if(userCreated){ ret.put("success", "true"); ret.put("username", username); diff --git a/src/prerna/web/conf/DBLoader.java b/src/prerna/web/conf/DBLoader.java index 3b9c2b8a2..cd0b2083e 100644 --- a/src/prerna/web/conf/DBLoader.java +++ b/src/prerna/web/conf/DBLoader.java @@ -92,12 +92,12 @@ public void contextInitialized(ServletContextEvent arg0) { DIHelper.getInstance().setLocalProperty(Constants.SECURITY_ENABLED, securityEnabled); - //Just load R right away to avoid synchronization issues - try { - RJavaTranslatorFactory.initRConnection(); - } catch(Exception e) { - e.printStackTrace(); - } +// //Just load R right away to avoid synchronization issues +// try { +// RJavaTranslatorFactory.initRConnection(); +// } catch(Exception e) { +// e.printStackTrace(); +// } // need to set the path // important for taking the image with security From 09d3937dbb0ae4a875fc0e08d6b0540faa9562f1 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 11 Sep 2018 13:25:16 +0000 Subject: [PATCH 0229/1906] UPDATE ::: Loading local master + security outside of watcher thread in new init function UPDATE ::: Switching methods to respective security utility classes git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29986 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: a1f0c075290a45febea83ae3683ace54e26c7657 --- .../web/services/AuthorizationResource.java | 76 +++++++++++-------- .../semoss/web/services/UserResource.java | 6 +- 2 files changed, 48 insertions(+), 34 deletions(-) diff --git a/src/prerna/semoss/web/services/AuthorizationResource.java b/src/prerna/semoss/web/services/AuthorizationResource.java index 614334e42..c47adb956 100644 --- a/src/prerna/semoss/web/services/AuthorizationResource.java +++ b/src/prerna/semoss/web/services/AuthorizationResource.java @@ -188,6 +188,51 @@ public Response getAllUsers(@Context HttpServletRequest request) { return WebUtility.getResponse(ret, 200); } + // TODO: why is this not /admin!!! + /** + * Edit user properties + * @param request + * @param form + * @return true if the edition was performed + */ + @POST + @Path("/editUser") + @Produces("application/json") + public Response editUser(@Context HttpServletRequest request, MultivaluedMap form) { + User user = null; + try { + user = getUser(request); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap(); + errorMap.put("error", "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + + SecurityAdminUtils adminUtils = SecurityAdminUtils.getInstance(user); + if(adminUtils == null) { + Map retMap = new Hashtable(); + retMap.put("error", "User does not have admin priviledges"); + return WebUtility.getResponse(retMap, 400); + } + + Gson gson = new Gson(); + Map userInfo = gson.fromJson(form.getFirst("user"), Map.class); + boolean ret = false; + try { + ret = adminUtils.editUser(userInfo); + } catch(IllegalArgumentException e) { + Map retMap = new Hashtable(); + retMap.put("error", e.getMessage()); + return WebUtility.getResponse(retMap, 400); + } + if(ret = false) { + Map retMap = new Hashtable(); + retMap.put("error", "Unknown error occured with updating user. Please try again."); + return WebUtility.getResponse(retMap, 400); + } + return WebUtility.getResponse(ret, 200); + } + @POST @Produces("application/json") @Path("/admin/deleteUser") @@ -467,37 +512,6 @@ public Response removeUserPermissionsbyDbId(@Context HttpServletRequest request, return WebUtility.getResponse(ret, 200); } - /** - * Edit user properties - * @param request - * @param form - * @return true if the edition was performed - */ - @POST - @Path("/editUser") - @Produces("application/json") - public Response editUser(@Context HttpServletRequest request, MultivaluedMap form) { - boolean ret = false; - Gson gson = new Gson(); - Map errorRet = new Hashtable(); - try{ - User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - String userId = user.getAccessToken(user.getLogins().get(0)).getId(); - Map userInfo = gson.fromJson(form.getFirst("user"), HashMap.class); - ret = SecurityUpdateUtils.editUser(userId, userInfo); - } catch (IllegalArgumentException e){ - e.printStackTrace(); - errorRet.put("error", e.getMessage()); - return WebUtility.getResponse(errorRet, 400); - } catch (Exception e){ - e.printStackTrace(); - errorRet.put("error", "An unexpected error happened. Please try again."); - return WebUtility.getResponse(errorRet, 500); - } - return WebUtility.getResponse(ret, 200); - } - - @POST @Produces("application/json") diff --git a/src/prerna/semoss/web/services/UserResource.java b/src/prerna/semoss/web/services/UserResource.java index fa0786918..8c695f48a 100644 --- a/src/prerna/semoss/web/services/UserResource.java +++ b/src/prerna/semoss/web/services/UserResource.java @@ -1283,13 +1283,13 @@ public Response authentication(@Context HttpServletRequest request) { String username = request.getParameter("username"); String password = request.getParameter("password"); boolean emptyCredentials = username == null || password == null || username.isEmpty() || password.isEmpty(); - boolean canLogin = !emptyCredentials && SecurityQueryUtils.logIn(username, password); + boolean canLogin = !emptyCredentials && NativeUserSecurityUtils.logIn(username, password); if(canLogin){ ret.put("success", "true"); ret.put("username", username); - String name = SecurityQueryUtils.getNameUser(username); + String name = NativeUserSecurityUtils.getNameUser(username); ret.put("name", name); - String id = SecurityQueryUtils.getUserId(username); + String id = NativeUserSecurityUtils.getUserId(username); AccessToken authToken = new AccessToken(); authToken.setProvider(AuthProvider.NATIVE); authToken.setId(id); From 8ad5e7d90f1e72ca6f448be3107e97d173528e56 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 11 Sep 2018 14:31:03 +0000 Subject: [PATCH 0230/1906] UPDATE ::: Adding file I forgot to commit to init the watchers git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29992 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 7f2c18e2a1e0ca96748077061489b0a3ad9f5d63 --- src/prerna/web/conf/DBLoader.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/prerna/web/conf/DBLoader.java b/src/prerna/web/conf/DBLoader.java index cd0b2083e..96d5c4c5d 100644 --- a/src/prerna/web/conf/DBLoader.java +++ b/src/prerna/web/conf/DBLoader.java @@ -83,6 +83,11 @@ public void contextInitialized(ServletContextEvent arg0) { String log4jConfig = DIHelper.getInstance().getProperty("LOG4J"); System.out.println("Setting log4j property: " + log4jConfig); PropertyConfigurator.configure(log4jConfig); + + // set security enabled within DIHelper first + // this is because secuirty database, on init, will + // load it as a boolean instead of us searching within DIHelper + DIHelper.getInstance().setLocalProperty(Constants.SECURITY_ENABLED, securityEnabled); //Load empty engine list into DIHelper, then load engines from db folder System.out.println("Loading engines..."); @@ -90,8 +95,6 @@ public void contextInitialized(ServletContextEvent arg0) { DIHelper.getInstance().setLocalProperty(Constants.ENGINES, engines); loadEngines(); - DIHelper.getInstance().setLocalProperty(Constants.SECURITY_ENABLED, securityEnabled); - // //Just load R right away to avoid synchronization issues // try { // RJavaTranslatorFactory.initRConnection(); @@ -118,6 +121,7 @@ public void loadEngines() { watcherInstance.setMonitor(monitor); watcherInstance.setFolderToWatch(folder); watcherInstance.setExtension(ext); + watcherInstance.init(); synchronized(monitor) { Thread thread = new Thread(watcherInstance); From 2ed7733047c103a820d3e0dd492fe9803ae28300 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 11 Sep 2018 14:53:29 +0000 Subject: [PATCH 0231/1906] UPDATE ::: Fixing retrieval of app images with parameters git-svn-id: svn://107.170.10.188:8080/Monolith/dev@29993 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 880399b4a40d3066394296abddd88527d53e70d4 --- src/prerna/semoss/web/services/AppResource.java | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/prerna/semoss/web/services/AppResource.java b/src/prerna/semoss/web/services/AppResource.java index bf4988fc8..1a053f928 100644 --- a/src/prerna/semoss/web/services/AppResource.java +++ b/src/prerna/semoss/web/services/AppResource.java @@ -125,9 +125,21 @@ private File getInsightImageFile(String app, String id, String feUrl, String par String fileLocation = ""; if(params != null && !params.isEmpty() && !params.equals("undefined")) { String encodedParams = Utility.encodeURIComponent(params); - fileLocation = baseFolder + DIR_SEPARATOR + "db" + DIR_SEPARATOR + SmssUtilities.getUniqueName(app, appId) + DIR_SEPARATOR + "version" + DIR_SEPARATOR + id + encodedParams + DIR_SEPARATOR + "image.png"; + fileLocation = baseFolder + + DIR_SEPARATOR + "db" + + DIR_SEPARATOR + SmssUtilities.getUniqueName(app, appId) + + DIR_SEPARATOR + "version" + + DIR_SEPARATOR + id + + DIR_SEPARATOR + "params" + + DIR_SEPARATOR + encodedParams + + DIR_SEPARATOR + "image.png"; } else { - fileLocation = baseFolder + DIR_SEPARATOR + "db" + DIR_SEPARATOR + SmssUtilities.getUniqueName(app, appId) + DIR_SEPARATOR + "version" + DIR_SEPARATOR + id + DIR_SEPARATOR + "image.png"; + fileLocation = baseFolder + + DIR_SEPARATOR + "db" + + DIR_SEPARATOR + SmssUtilities.getUniqueName(app, appId) + + DIR_SEPARATOR + "version" + + DIR_SEPARATOR + id + + DIR_SEPARATOR + "image.png"; } File f = new File(fileLocation); if(f.exists()) { From eaca7b91dc6233cbc47e7c4f6758623aa99e0f54 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 12 Sep 2018 12:01:00 +0000 Subject: [PATCH 0232/1906] UPDATE ::: Improving logic around uploading databases UPDATE ::: Removing unused "OVERRIDE" upload option BUGFIX ::: Fixing invalid additional entry being being added into security database git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30022 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 947690b319641d77c987d52473cf808e1e23fb42 --- src/prerna/upload/DatabaseUploader.java | 1427 +++++++++++------------ 1 file changed, 650 insertions(+), 777 deletions(-) diff --git a/src/prerna/upload/DatabaseUploader.java b/src/prerna/upload/DatabaseUploader.java index 59903cace..9c33366a2 100644 --- a/src/prerna/upload/DatabaseUploader.java +++ b/src/prerna/upload/DatabaseUploader.java @@ -4,7 +4,6 @@ import java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; -import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; import java.text.SimpleDateFormat; @@ -15,7 +14,6 @@ import java.util.Hashtable; import java.util.List; import java.util.Map; -import java.util.UUID; import java.util.Vector; import javax.servlet.http.HttpServletRequest; @@ -37,6 +35,7 @@ import prerna.auth.utils.SecurityUpdateUtils; import prerna.engine.impl.SmssUtilities; import prerna.nameserver.AddToMasterDB; +import prerna.nameserver.utility.MasterDatabaseUtility; import prerna.om.Insight; import prerna.om.InsightStore; import prerna.poi.main.CSVPropFileBuilder; @@ -116,7 +115,6 @@ private void setDefaultOptions(ImportOptions options, Map inputD ImportOptions.IMPORT_METHOD importMethod = methodString.equals("Create new database engine") ? ImportOptions.IMPORT_METHOD.CREATE_NEW : methodString.equals("addEngine") ? ImportOptions.IMPORT_METHOD.ADD_TO_EXISTING - : methodString.equals("modifyEngine") ? ImportOptions.IMPORT_METHOD.OVERRIDE : null; if(importMethod == null) { String errorMessage = "Import method \'" + methodString + "\' is not supported"; @@ -139,9 +137,9 @@ private void setDefaultOptions(ImportOptions options, Map inputD } if(importMethod == ImportOptions.IMPORT_METHOD.ADD_TO_EXISTING) { options.setEngineID(dbName); + options.setDbName(MasterDatabaseUtility.getEngineAliasForId(dbName)); } else { options.setDbName(Utility.makeAlphaNumeric(dbName)); - options.setEngineID(UUID.randomUUID().toString()); } // determine the db type @@ -195,7 +193,6 @@ private void setDefaultOptions(ImportOptions options, MultivaluedMap form) { } } } -// return Response.status(200).entity(WebUtility.getSO(invalidHeadersMap)).build(); return WebUtility.getResponse(invalidHeadersMap, 200); } else if(type.equals("EXCEL")) { @@ -382,10 +383,8 @@ public Response checkUserDefinedHeaders(MultivaluedMap form) { // even if it is empty, we need to store it since the FE does this based on indices invalidHeadersList.add(invalidHeadersMap); } -// return Response.status(200).entity(WebUtility.getSO(invalidHeadersList)).build(); return WebUtility.getResponse(invalidHeadersList, 200); } else { -// return Response.status(400).entity("Format does not conform to checking headers").build(); return WebUtility.getResponse("Format does not conform to checking headers", 400); } } @@ -436,7 +435,6 @@ public Response uploadCsvFileAndPredictMetamodel(@Context HttpServletRequest req } } - for(int i = 0; i < files.length; i++) { // this is the MM info for one of the files within the metaModelData list Map fileMetaModelData = new HashMap(); @@ -509,7 +507,6 @@ public Response uploadCsvFileAndPredictMetamodel(@Context HttpServletRequest req // grab the error thrown and send it to the FE HashMap errorMap = new HashMap(); errorMap.put("errorMessage", e.getMessage()); -// return Response.status(400).entity(WebUtility.getSO(errorMap)).build(); return WebUtility.getResponse(errorMap, 400); } @@ -535,18 +532,6 @@ public Response uploadCSVFile(MultivaluedMap form, @Context Http // can only load flat files as RDBMS options.setImportType(ImportOptions.IMPORT_TYPE.CSV); - // open refine logic - Object obj = form.get("cleanedFiles"); - if(obj != null) { - String cleanedFileName = processOpenRefine(options.getDbName(), (String) obj); - if(cleanedFileName.startsWith("Error")) { - Map errorHash = new HashMap(); - errorHash.put("errorMessage", "Could not write the cleaned data to file. Please check application file-upload path."); - return Response.status(400).entity(gson.toJson(errorHash)).build(); - } - form.putSingle("file", cleanedFileName); - } - // set the files String files = form.getFirst("file"); if(files == null || files.trim().isEmpty()) { @@ -618,32 +603,61 @@ public Response uploadCSVFile(MultivaluedMap form, @Context Http options.setMetamodelArray(propHashArr); ////////////////////// end logic to process metamodel for csv flat table ////////////////////// - // add engine owner for permissions - if(this.securityEnabled) { - User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - if(user == null) { - Map errorHash = new HashMap(); - errorHash.put("errorMessage", "User must be signed into an account in order to create a database"); - return Response.status(400).entity(gson.toJson(errorHash)).build(); - } - - DB_TYPE dbType = options.getDbType(); - if(dbType == DB_TYPE.RDBMS) { - addEngineOwner(options.getEngineID(), options.getDbName(), "H2_DB", "", user); - } else if(dbType == DB_TYPE.TINKER) { - addEngineOwner(options.getEngineID(), options.getDbName(), "TINKER", "", user); - } else { - addEngineOwner(options.getEngineID(), options.getDbName(), "RDF", "", user); - } - } - // run the import ImportDataProcessor importer = new ImportDataProcessor(); + // the reactors handle all the security! :) String appId = reactorImport(options, request); if (appId != null) { options.setEngineID(appId); } else { + // old way... i believe this shouldn't be invoked anymore... importer.runProcessor(options); + + // add engine owner for permissions + // the + if(this.securityEnabled) { + User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); + if(user == null) { + Map errorHash = new HashMap(); + errorHash.put("errorMessage", "User must be signed into an account in order to create a database"); + return Response.status(400).entity(gson.toJson(errorHash)).build(); + } + + DB_TYPE dbType = options.getDbType(); + if(dbType == DB_TYPE.RDBMS) { + addEngineOwner(options.getEngineID(), options.getDbName(), "H2_DB", "", user); + } else if(dbType == DB_TYPE.TINKER) { + addEngineOwner(options.getEngineID(), options.getDbName(), "TINKER", "", user); + } else { + addEngineOwner(options.getEngineID(), options.getDbName(), "RDF", "", user); + } + } + + // for the above case + // the reactor does this already + try { + Date currDate = Calendar.getInstance().getTime(); + SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmmssZ"); + String dateName = sdf.format(currDate); + + String dbName = options.getDbName(); + String[] fileNames = options.getFileLocations().split(";"); + String dbLocation = SmssUtilities.getUniqueName(Utility.cleanString(dbName, true).toString(), options.getEngineID()); + for(int i = 0; i < propFileArr.length; i++) { + String fileName = new File(fileNames[i]).getName().replace(".csv", ""); + FileUtils.writeStringToFile(new File( + DIHelper.getInstance().getProperty("BaseFolder") + .concat(File.separator).concat("db").concat(File.separator) + .concat(dbLocation).concat(File.separator) + .concat(dbName.toString()).concat("_").concat(fileName) + .concat("_").concat(dateName).concat("_PROP.prop")), propFileArr[i]); + } + } catch (IOException e) { + e.printStackTrace(); + Map errorHash = new HashMap(); + errorHash.put("errorMessage", "Failure to write CSV Prop File based on user-defined metamodel."); + return Response.status(400).entity(gson.toJson(errorHash)).build(); + } } } catch (IOException e) { e.printStackTrace(); @@ -663,293 +677,107 @@ public Response uploadCSVFile(MultivaluedMap form, @Context Http } } - try { - Date currDate = Calendar.getInstance().getTime(); - SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmmssZ"); - String dateName = sdf.format(currDate); - - String dbName = options.getDbName(); - String[] fileNames = options.getFileLocations().split(";"); - String dbLocation = SmssUtilities.getUniqueName(Utility.cleanString(dbName, true).toString(), options.getEngineID()); - for(int i = 0; i < propFileArr.length; i++) { - String fileName = new File(fileNames[i]).getName().replace(".csv", ""); - FileUtils.writeStringToFile(new File( - DIHelper.getInstance().getProperty("BaseFolder") - .concat(File.separator).concat("db").concat(File.separator) - .concat(dbLocation).concat(File.separator) - .concat(dbName.toString()).concat("_").concat(fileName) - .concat("_").concat(dateName).concat("_PROP.prop")), propFileArr[i]); - } - } catch (IOException e) { - e.printStackTrace(); - Map errorHash = new HashMap(); - errorHash.put("errorMessage", "Failure to write CSV Prop File based on user-defined metamodel."); - return Response.status(400).entity(gson.toJson(errorHash)).build(); - } - String appId = options.getEngineID(); User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); Map retMap = UploadUtilities.getAppReturnData(user, appId); return Response.status(200).entity(gson.toJson(retMap)).build(); } -// @POST -// @Path("/csv/flat") -// @Produces("application/json") -// /** -// * The process flow for loading a flat file based on drag/drop -// * Since the user confirms what type of datatypes they want for each column -// * The file has already been loaded onto the server -// * @param form Form object containing all the information regarding the load -// * @param request -// * @return -// */ -// public Response uploadFlatCsvFile(MultivaluedMap form, @Context HttpServletRequest request) { -// Gson gson = new Gson(); -// System.out.println(form); -// -// ImportOptions options = null; -// try { -// options = new ImportOptions(); -// setDefaultOptions(options, form); -// // can only load flat files as RDBMS -// options.setDbType(ImportOptions.DB_TYPE.RDBMS); -// options.setRDBMSDriverType(SQLQueryUtil.DB_TYPE.H2_DB); -// options.setImportType(ImportOptions.IMPORT_TYPE.CSV_FLAT_LOAD); -// -// // set the files -// String files = form.getFirst("file"); -// if(files == null || files.trim().isEmpty()) { -// Map errorHash = new HashMap(); -// errorHash.put("errorMessage", "No files have been identified to upload"); -// return Response.status(400).entity(gson.toJson(errorHash)).build(); -// } -// options.setFileLocation(files); -// -// // see if user also manually changed some the headers -// String newHeadersStr = form.getFirst("newHeaders"); -// System.out.println("new headers is " + newHeadersStr); -// if(newHeadersStr != null && newHeadersStr.equalsIgnoreCase("undefined")) -// newHeadersStr = null; -// if(newHeadersStr != null) { -// Map> newHeaders = -// gson.fromJson(newHeadersStr, new TypeToken>>() {}.getType()); -// options.setCsvNewHeaders(newHeaders); -// } -// -// // this should always be present now since we dont want to predict types twice on the BE -// // get the data types and set them in the options -// String headerDataTypesStr = form.getFirst("headerData"); -// if(headerDataTypesStr != null) { -// List> headerDataTypes = gson.fromJson(headerDataTypesStr, new TypeToken>>() {}.getType()); -// options.setCsvDataTypeMap(headerDataTypes); -// -// // track GA data -// String tableName = form.getFirst("dbName"); -// GATracker.getInstance().trackCsvUpload(files, tableName, headerDataTypes); -// } -// // add engine owner for permissions -// if(this.securityEnabled) { -// Object user = request.getSession().getAttribute(Constants.SESSION_USER); -// if(user != null && !((User) user).getId().equals(Constants.ANONYMOUS_USER_ID)) { -// addEngineOwner(options.getDbName(), ((User) user).getId()); -// } else { -// Map errorHash = new HashMap(); -// errorHash.put("errorMessage", "Please log in to upload data."); -// return Response.status(400).entity(gson.toJson(errorHash)).build(); -// } -// } -// -// ImportDataProcessor importer = new ImportDataProcessor(); -// importer.runProcessor(options); -// } catch (IOException e) { -// e.printStackTrace(); -// Map errorHash = new HashMap(); -// errorHash.put("errorMessage", e.getMessage()); -// return Response.status(400).entity(gson.toJson(errorHash)).build(); -// } catch(Exception e) { -// e.printStackTrace(); -// Map errorHash = new HashMap(); -// errorHash.put("errorMessage", e.getMessage()); -// return Response.status(400).entity(gson.toJson(errorHash)).build(); -// } finally { -// // we can't really use the options object for this :/ -// String files = form.getFirst("file"); -// if(files != null && !files.isEmpty()) { -// deleteFilesFromServer(files.split(";")); -// } -// String questionFile = form.getFirst("questionFile"); -// if(questionFile != null && !questionFile.isEmpty()) { -// deleteFilesFromServer(new String[]{questionFile}); -// } -// } -// -// String outputText = "Flat database loading was a success."; -// return Response.status(200).entity(gson.toJson(outputText)).build(); -// } - ////////////////////////////////////////////// END CSV UPLOADING ////////////////////////////////////////////////////////// ////////////////////////////////////////////// START EXCEL UPLOADING ////////////////////////////////////////////////////////// private String reactorImport(ImportOptions options, HttpServletRequest request) { // get upload inputs - DB_TYPE importDBType = options.getDbType(); IMPORT_METHOD importType = options.getImportMethod(); - String fileLocations = options.getFileLocations(); String dbName = options.getDbName(); - // return appId - String appId = null; + String appId = options.getEngineID(); // create each specific reactor for upload type IReactor reactor = getImportReactor(options); // if the reactor is supported, get the rest of the upload inputs if (reactor != null) { - // create new metamodels for the reactor + // create new metamodels for the reactor // index based for each file List> newMetamodelList = createNewMetamodel(options); - // if importing multiple csvs add to existing - String[] csvFiles = fileLocations.split(";"); - // set up insight to run reactor - reactor.In(); - // make an insight to set - // so we can pass the user - + // if importing multiple files add to existing + String[] inputFiles = fileLocations.split(";"); - // if create new - if (importType == IMPORT_METHOD.CREATE_NEW) { - for (int i = 0; i < csvFiles.length; i++) { - - String csvFileLocation = csvFiles[i]; - csvFileLocation = csvFileLocation.replace("\\\\", "/"); - - Insight dummyIn = new Insight(); - InsightStore.getInstance().put(dummyIn); + for (int i = 0; i < inputFiles.length; i++) { + String fileLocation = inputFiles[i]; + fileLocation = fileLocation.replace("\\\\", "/"); + + Insight dummyIn = new Insight(); + InsightStore.getInstance().put(dummyIn); + User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); + dummyIn.setUser(user); - // TODO do we need this? - // InsightStore.getInstance().addToSessionHash(session.getId(), - // dummyIn.getInsightId()); - // dummyIn.getVarStore().put(JobReactor.SESSION_KEY, new - // NounMetadata(session.getId(), - // PixelDataType.CONST_STRING)); - // dummyIn.setUser(user); - if (this.securityEnabled) { - User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - dummyIn.setUser(user); - } - reactor.setInsight(dummyIn); - PixelPlanner planner = new PixelPlanner(); - planner.setVarStore(dummyIn.getVarStore()); - reactor.setPixelPlanner(planner); - // if adding multiple csvs to an app - GenRowStruct grs = new GenRowStruct(); - if (appId != null) { - grs = new GenRowStruct(); - grs.add(new NounMetadata(appId, PixelDataType.CONST_STRING)); - reactor.getNounStore().addNoun(ReactorKeysEnum.APP.getKey(), grs); - // add to existing - grs = new GenRowStruct(); - grs.add(new NounMetadata(true, PixelDataType.BOOLEAN)); - reactor.getNounStore().addNoun(ReactorKeysEnum.EXISTING.getKey(), grs); - } else { - // add app name - grs = new GenRowStruct(); - grs.add(new NounMetadata(dbName, PixelDataType.CONST_STRING)); - reactor.getNounStore().addNoun(ReactorKeysEnum.APP.getKey(), grs); - } - - // add metamodel - grs = new GenRowStruct(); - grs.add(new NounMetadata(newMetamodelList.get(i), PixelDataType.MAP)); - reactor.getNounStore().addNoun(ReactorKeysEnum.METAMODEL.getKey(), grs); - - // add file path - grs = new GenRowStruct(); - grs.add(new NounMetadata(csvFileLocation, PixelDataType.CONST_STRING)); - reactor.getNounStore().addNoun(ReactorKeysEnum.FILE_PATH.getKey(), grs); - - // execute! - NounMetadata response = reactor.execute(); - if (i == 0) { - // need to keep app id to override - Map retMap = (Map) response.getValue(); - appId = retMap.get("app_id"); - } - reactor = getImportReactor(options); + reactor.setInsight(dummyIn); + PixelPlanner planner = new PixelPlanner(); + planner.setVarStore(dummyIn.getVarStore()); + reactor.setPixelPlanner(planner); + + // need to determine if we are doing CREATE_NEW or ADD_TO_EXISTING + GenRowStruct grs = new GenRowStruct(); + if (i == 0 && importType == IMPORT_METHOD.CREATE_NEW) { + // add app name + grs.add(new NounMetadata(dbName, PixelDataType.CONST_STRING)); + } else { + GenRowStruct existingGrs = new GenRowStruct(); + existingGrs.add(new NounMetadata(true, PixelDataType.BOOLEAN)); + reactor.getNounStore().addNoun(ReactorKeysEnum.EXISTING.getKey(), existingGrs); + + // we are adding to an existing app at this point + // since even if it is a "CREATE_NEW", we run the reactor a different time + // so the second file is an "ADD_TO_EXISTING" + grs.add(new NounMetadata(appId, PixelDataType.CONST_STRING)); } - } else if(importType == IMPORT_METHOD.ADD_TO_EXISTING) { - for (int i = 0; i < csvFiles.length; i++) { - String csvFileLocation = csvFiles[i]; - - Insight dummyIn = new Insight(); - InsightStore.getInstance().put(dummyIn); - // TODO do we need this? - // InsightStore.getInstance().addToSessionHash(session.getId(), - // dummyIn.getInsightId()); - // dummyIn.getVarStore().put(JobReactor.SESSION_KEY, new - // NounMetadata(session.getId(), - // PixelDataType.CONST_STRING)); - // dummyIn.setUser(user); - if (this.securityEnabled) { - User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - dummyIn.setUser(user); - } - reactor.setInsight(dummyIn); - PixelPlanner planner = new PixelPlanner(); - planner.setVarStore(dummyIn.getVarStore()); - reactor.setPixelPlanner(planner); - // if adding multiple csvs to an app - GenRowStruct grs = new GenRowStruct(); - if (appId != null) { - grs = new GenRowStruct(); - grs.add(new NounMetadata(appId, PixelDataType.CONST_STRING)); - reactor.getNounStore().addNoun(ReactorKeysEnum.APP.getKey(), grs); - - } else { - grs = new GenRowStruct(); - grs.add(new NounMetadata(options.getDbName(), PixelDataType.CONST_STRING)); - reactor.getNounStore().addNoun(ReactorKeysEnum.APP.getKey(), grs); - } - // add to existing - grs = new GenRowStruct(); - grs.add(new NounMetadata(true, PixelDataType.BOOLEAN)); - reactor.getNounStore().addNoun(ReactorKeysEnum.EXISTING.getKey(), grs); - - // add metamodel - grs = new GenRowStruct(); - grs.add(new NounMetadata(newMetamodelList.get(i), PixelDataType.MAP)); - reactor.getNounStore().addNoun(ReactorKeysEnum.METAMODEL.getKey(), grs); - - // add file path - grs = new GenRowStruct(); - grs.add(new NounMetadata(csvFileLocation, PixelDataType.CONST_STRING)); - reactor.getNounStore().addNoun(ReactorKeysEnum.FILE_PATH.getKey(), grs); - - // execute! - NounMetadata response = reactor.execute(); - if (i == 0) { - // need to keep app id to override - Map retMap = (Map) response.getValue(); - appId = retMap.get("app_id"); - } + reactor.getNounStore().addNoun(ReactorKeysEnum.APP.getKey(), grs); + + // add metamodel + grs = new GenRowStruct(); + grs.add(new NounMetadata(newMetamodelList.get(i), PixelDataType.MAP)); + reactor.getNounStore().addNoun(ReactorKeysEnum.METAMODEL.getKey(), grs); + + // add file path + grs = new GenRowStruct(); + grs.add(new NounMetadata(fileLocation, PixelDataType.CONST_STRING)); + reactor.getNounStore().addNoun(ReactorKeysEnum.FILE_PATH.getKey(), grs); + + // execute! + NounMetadata response = reactor.execute(); + // get the app id + // if we CREATE_NEW -> this is a new id + // if ADD_TO_EXISTING -> it is the same value + Map retMap = (Map) response.getValue(); + appId = retMap.get("app_id"); + + // get a base new reactor if we have more files to process + if( (i+1) < inputFiles.length) { reactor = getImportReactor(options); } - } } + + // return the app id to send to FE return appId; } + /** + * Get the correct type of reactor based on the import type + * @param options + * @return + */ private IReactor getImportReactor(ImportOptions options) { DB_TYPE importDBType = options.getDbType(); IMPORT_METHOD importType = options.getImportMethod(); IReactor reactor = null; - if (importDBType == DB_TYPE.RDBMS - && (importType == IMPORT_METHOD.CREATE_NEW || importType == IMPORT_METHOD.ADD_TO_EXISTING)) { + // either RDBMS, RDF, or Tinker + if (importDBType == DB_TYPE.RDBMS && (importType == IMPORT_METHOD.CREATE_NEW || importType == IMPORT_METHOD.ADD_TO_EXISTING)) { reactor = new RdbmsCsvUploadReactor(); - } else if (importDBType == DB_TYPE.RDF - && (importType == IMPORT_METHOD.CREATE_NEW || importType == IMPORT_METHOD.ADD_TO_EXISTING)) { + + } else if (importDBType == DB_TYPE.RDF && (importType == IMPORT_METHOD.CREATE_NEW || importType == IMPORT_METHOD.ADD_TO_EXISTING)) { reactor = new RdfCsvUploadReactor(); String baseURI = options.getBaseUrl(); GenRowStruct grs = new GenRowStruct(); @@ -957,16 +785,18 @@ private IReactor getImportReactor(ImportOptions options) { grs.add(new NounMetadata(baseURI, PixelDataType.CONST_STRING)); reactor.getNounStore().addNoun(UploadInputUtility.CUSTOM_BASE_URI, grs); - } else if (importDBType == DB_TYPE.TINKER - && (importType == IMPORT_METHOD.CREATE_NEW || importType == IMPORT_METHOD.ADD_TO_EXISTING)) { - + } else if (importDBType == DB_TYPE.TINKER && (importType == IMPORT_METHOD.CREATE_NEW || importType == IMPORT_METHOD.ADD_TO_EXISTING)) { reactor = new TinkerCsvUploadReactor(); GenRowStruct grs = new GenRowStruct(); grs = new GenRowStruct(); grs.add(new NounMetadata(options.getTinkerDriverType().toString(), PixelDataType.CONST_STRING)); reactor.getNounStore().addNoun("tinkerDriver", grs); - } + + if(reactor != null) { + reactor.In(); + } + return reactor; } @@ -1083,29 +913,6 @@ public Response uploadExcelFile(@Context HttpServletRequest request) { } preProcessor.clear(); -// XLFileHelper helper = new XLFileHelper(); -// helper.parse(files[i]); -// -// // store the suggested data types -// String[] sheetNames = helper.getTables(); -// Map> dataTypes = new Hashtable>(); -// Map> additionalDataTypes = new Hashtable>(); -// -// for(String sheetName : sheetNames) { -// Map[] predictionMaps = FileHelperUtil.generateDataTypeMapsFromPrediction(helper.getHeaders(sheetName), helper.predictTypes(sheetName)); -// Map sheetDataMap = predictionMaps[0]; -// Map additionalTypesMap = predictionMaps[1]; -// -// dataTypes.put(sheetName, sheetDataMap); -// additionalDataTypes.put(sheetName, additionalTypesMap); -// } -// fileMetaModelData.put("dataTypes", dataTypes); -// fileMetaModelData.put("additionalDataTypes", additionalDataTypes); -// -// // store auto modified header names -// Map> fileHeaderMods = helper.getChangedHeaders(); -// fileMetaModelData.put("headerModifications", fileHeaderMods); - // add the info to the metamodel data to send metaModelData.add(fileMetaModelData); } @@ -1120,43 +927,30 @@ public Response uploadExcelFile(@Context HttpServletRequest request) { // store the info returnObj.put("metaModelData", metaModelData); - return Response.status(200).entity(gson.toJson(returnObj)).build(); } - @POST - @Path("/excel/processUpload") + //TODO: this path should be excel/uploadPOI + //TODO: cannot make this change without changing the path above + @Path("/excel/upload") @Produces("application/json") - public Response processExcelFile(@Context HttpServletRequest request) + public Response uploadExcelPOIFormat(@Context HttpServletRequest request) { - Gson gson = new Gson(); List fileItems = processRequest(request); // collect all of the data input on the form Hashtable inputData = getInputData(fileItems); System.out.println(inputData); + Gson gson = new Gson(); ImportOptions options = null; - String[] propFileArr = null; try { // load as many default options as possible options = new ImportOptions(); // now just load the rest as usual setDefaultOptions(options, inputData); // set the import type - options.setImportType(ImportOptions.IMPORT_TYPE.EXCEL); - - // open refine logic - Object obj = inputData.get("cleanedFiles"); - if(obj != null) { - String cleanedFileName = processOpenRefine(options.getDbName(), (String) obj); - if(cleanedFileName.startsWith("Error")) { - Map errorHash = new HashMap(); - errorHash.put("errorMessage", "Could not write the cleaned data to file. Please check application file-upload path."); - return Response.status(400).entity(gson.toJson(errorHash)).build(); - } - inputData.put("file", cleanedFileName); - } + options.setImportType(ImportOptions.IMPORT_TYPE.EXCEL_POI); // only default options not set are the files String files = inputData.get("file"); @@ -1167,25 +961,326 @@ public Response processExcelFile(@Context HttpServletRequest request) } options.setFileLocation(files); - ////////////////////// begin logic to process metamodel for excel flat table rdf ////////////////////// - List allFileData = gson.fromJson(inputData.get("fileInfoArray"), List.class); - int size = allFileData.size(); - - Hashtable[] propHashArr = new Hashtable[size]; - propFileArr = new String[size]; - boolean allEmpty = true; - for(int i = 0; i < size; i++) { - Hashtable itemForFile = gson.fromJson(allFileData.get(i), Hashtable.class); - ExcelPropFileBuilder propWriter = new ExcelPropFileBuilder(); + // add engine owner for permissions + if(this.securityEnabled) { + User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); + if(user == null) { + Map errorHash = new HashMap(); + errorHash.put("errorMessage", "User must be signed into an account in order to create a database"); + return Response.status(400).entity(gson.toJson(errorHash)).build(); + } + addEngineOwner(options.getEngineID(), options.getDbName(), "RDF", "", user); + } - Hashtable allSheetInfo = gson.fromJson(itemForFile.get("sheetInfo"), Hashtable.class); - for(String sheet : allSheetInfo.keySet()) { - Hashtable sheetInfo = gson.fromJson(allSheetInfo.get(sheet), Hashtable.class); + // run the processor + ImportDataProcessor importer = new ImportDataProcessor(); + importer.runProcessor(options); + } catch (IOException e) { + e.printStackTrace(); + Map errorHash = new HashMap(); + errorHash.put("errorMessage", e.getMessage()); + return Response.status(400).entity(gson.toJson(errorHash)).build(); + } catch(Exception e) { + e.printStackTrace(); + Map errorHash = new HashMap(); + errorHash.put("errorMessage", e.getMessage()); + return Response.status(400).entity(gson.toJson(errorHash)).build(); + } finally { + deleteFilesFromServer(inputData.get("file").toString().split(";")); + String questionFile = inputData.get("questionFile"); + if(questionFile != null && !questionFile.isEmpty()) { + deleteFilesFromServer(new String[]{questionFile}); + } + } - List rel = gson.fromJson(sheetInfo.get("rowsRelationship"), List.class); - List prop = gson.fromJson(sheetInfo.get("rowsProperty"), List.class); - if((rel != null &&!rel.isEmpty()) || (prop != null && !prop.isEmpty()) ) { - allEmpty = false; + String appId = options.getEngineID(); + User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); + Map retMap = UploadUtilities.getAppReturnData(user, appId); + return Response.status(200).entity(gson.toJson(retMap)).build(); + } + + ////////////////////////////////////////////// END EXCEL UPLOADING ////////////////////////////////////////////////////////// + + + @POST + @Path("/rdbms/getMetadata2") + @Produces("application/json") + public Response getExistingRDBMSMetadata(@Context HttpServletRequest request, MultivaluedMap form) { + Gson gson = new Gson(); + ImportRDBMSProcessor importer = new ImportRDBMSProcessor(); + + String driver = form.getFirst("driver"); + String hostname = form.getFirst("hostname"); + String port = form.getFirst("port"); + String username = form.getFirst("username"); + String password = form.getFirst("password"); + String schema = form.getFirst("schema"); + String additionalProperties = form.getFirst("additionalParams"); + + Map ret = new HashMap(); + try { + ret = importer.getSchemaDetails(driver, hostname, port, username, password, schema, additionalProperties); + } catch(Exception e) { + e.printStackTrace(); + if(e.getMessage() != null) { + ret.put("errorMessage", e.getMessage()); + } else { + ret.put("errorMessage", "Unexpected error determining metadata"); + } + return Response.status(400).entity(gson.toJson(ret)).build(); + } + + return Response.status(200).entity(gson.toJson(ret)).build(); + } + + @POST + @Path("/rdbms/connect") + @Produces("application/json") + public Response connectExistingRDBMS(@Context HttpServletRequest request, MultivaluedMap form) { + Gson gson = new Gson(); + HashMap ret = new HashMap(1); + Map metamodel = new HashMap(); + HashMap details = gson.fromJson(form.getFirst("details"), new TypeToken>() {}.getType()); + HashMap metamodelData = gson.fromJson(gson.toJson(details.get("metamodelData")), new TypeToken>() {}.getType()); + ArrayList nodes = gson.fromJson(gson.toJson(metamodelData.get("nodes")), new TypeToken>() {}.getType()); + ArrayList relationships = gson.fromJson(gson.toJson(metamodelData.get("relationships")), new TypeToken>() {}.getType()); + // reformat metamodel for new reactor + HashMap> nodesAndProps = new HashMap>(nodes.size()); + ArrayList> nodeRelationships = new ArrayList<>(relationships.size()); + for(Object o: nodes) { + ArrayList props = new ArrayList(); + HashMap nodeHash = gson.fromJson(gson.toJson(o), new TypeToken>() {}.getType()); + ArrayList properties = gson.fromJson(gson.toJson(nodeHash.get("prop")), new TypeToken>() {}.getType()); + for(String prop : properties) { + props.add(prop); + } + nodesAndProps.put(nodeHash.get("node") + "." + nodeHash.get("primaryKey"), props); // Table1.idTable1 -> [prop1, prop2, ...] + } + metamodel.put(Constants.NODE_PROP, nodesAndProps); + for(Object o: relationships) { + HashMap relationship = gson.fromJson(gson.toJson(o), new TypeToken>() {}.getType()); + String fromTable = relationship.get("sub"); + String relName = relationship.get("pred"); + String toTable = relationship.get("obj"); + Map relMap = new HashMap<>(); + relMap.put(Constants.FROM_TABLE, fromTable); + relMap.put(Constants.REL_NAME, relName); + relMap.put(Constants.TO_TABLE, toTable); + nodeRelationships.add(relMap); + } + metamodel.put(Constants.RELATION, nodeRelationships); + + HashMap databaseOptions = gson.fromJson(gson.toJson(details.get("databaseOptions")), new TypeToken>() {}.getType()); + HashMap options = gson.fromJson(gson.toJson(details.get("options")), new TypeToken>() {}.getType()); + options.put("dbName", Utility.makeAlphaNumeric(databaseOptions.get("databaseName"))); + + // mocking inputs until FE makes full pixel call + RdbmsExternalUploadReactor reactor = new RdbmsExternalUploadReactor(); + reactor.In(); + // make an insight to set + // so we can pass the user + Insight dummyIn = new Insight(); + InsightStore.getInstance().put(dummyIn); + User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); + dummyIn.setUser(user); + + reactor.setInsight(dummyIn); + PixelPlanner planner = new PixelPlanner(); + planner.setVarStore(dummyIn.getVarStore()); + reactor.setPixelPlanner(planner); + // add app name + GenRowStruct grs1 = new GenRowStruct(); + grs1.add(new NounMetadata(Utility.makeAlphaNumeric(databaseOptions.get("databaseName")), PixelDataType.CONST_STRING)); + reactor.getNounStore().addNoun(ReactorKeysEnum.APP.getKey(), grs1); + // add db driver + GenRowStruct grs2 = new GenRowStruct(); + grs2.add(new NounMetadata(options.get("driver"), PixelDataType.CONST_STRING)); + reactor.getNounStore().addNoun(ReactorKeysEnum.DB_DRIVER_KEY.getKey(), grs2); + // add host + GenRowStruct grs3 = new GenRowStruct(); + grs3.add(new NounMetadata(options.get("hostname"), PixelDataType.CONST_STRING)); + reactor.getNounStore().addNoun(ReactorKeysEnum.HOST.getKey(), grs3); + // add port + GenRowStruct grs4 = new GenRowStruct(); + grs4.add(new NounMetadata(options.get("port"), PixelDataType.CONST_STRING)); + reactor.getNounStore().addNoun(ReactorKeysEnum.PORT.getKey(), grs4); + // add schema + GenRowStruct grs5 = new GenRowStruct(); + grs5.add(new NounMetadata(options.get("schema"), PixelDataType.CONST_STRING)); + reactor.getNounStore().addNoun(ReactorKeysEnum.SCHEMA.getKey(), grs5); + // add username + GenRowStruct grs6 = new GenRowStruct(); + grs6.add(new NounMetadata(options.get("username"), PixelDataType.CONST_STRING)); + reactor.getNounStore().addNoun(ReactorKeysEnum.USERNAME.getKey(), grs6); + // add password + GenRowStruct grs7 = new GenRowStruct(); + grs7.add(new NounMetadata(options.get("password"), PixelDataType.CONST_STRING)); + reactor.getNounStore().addNoun(ReactorKeysEnum.PASSWORD.getKey(), grs7); + // add additional paras + GenRowStruct grs8 = new GenRowStruct(); + grs8.add(new NounMetadata(options.get("additionalParams"), PixelDataType.CONST_STRING)); + reactor.getNounStore().addNoun(ReactorKeysEnum.ADDITIONAL_CONNECTION_PARAMS_KEY.getKey(), grs8); + // add metamodel + // additional paras + GenRowStruct grs9 = new GenRowStruct(); + grs9.add(new NounMetadata(metamodel, PixelDataType.MAP)); + reactor.getNounStore().addNoun(ReactorKeysEnum.METAMODEL.getKey(), grs9); + + // execute! + try { + reactor.execute(); + ret.put("success", true); + return Response.status(200).entity(gson.toJson(ret)).build(); + } catch(Exception e) { + ret.put("errorMessage", e.getMessage()); + return Response.status(400).entity(gson.toJson(ret)).build(); + } + + } + + @POST + @Path("/rdbms/test") + @Produces("application/json") + public Response testExistingRDBMSConnection(@Context HttpServletRequest request, MultivaluedMap form) { + Gson gson = new Gson(); + String driver = form.getFirst("driver"); + String hostname = form.getFirst("hostname"); + String port = form.getFirst("port"); + String username = form.getFirst("username"); + String password = form.getFirst("password"); + String schema = form.getFirst("schema"); + String additionalProperties = form.getFirst("additionalParams"); + HashMap ret = new HashMap(); + + ImportRDBMSProcessor importer = new ImportRDBMSProcessor(); + String test = importer.checkConnectionParams(driver, hostname, port, username, password, schema, additionalProperties); + if(Boolean.parseBoolean(test)) { + ret.put("success", Boolean.parseBoolean(test)); + return Response.status(200).entity(gson.toJson(ret)).build(); + } else { + ret.put("error", test); + return Response.status(400).entity(gson.toJson(ret)).build(); + } + } + + public void addEngineOwner(String engineId, String engineName, String engineType, String engineCost, User user) { + List logins = user.getLogins(); + for(AuthProvider ap : logins) { + SecurityUpdateUtils.addEngineOwner(engineId, user.getAccessToken(ap).getId()); + } + } + + @POST + @Path("/json/uploadXrayConfig") + @Produces("application/json") + /* + * This method is used for uploading x-ray configuration + * uploads a json file and returns a string of the parsed json + * and deletes the file. + */ + public Response uploadXrayConfig(@Context HttpServletRequest request) { + Gson gson = new Gson(); + + //process request + List fileItems = processRequest(request); + String cleanName = fileItems.get(0).getName(); + // collect all of the data input on the form + Hashtable inputData = getInputData(fileItems); + + // objects to store data + // master object to send to FE + Map returnObj = new HashMap<>(2); + // this will store the MM info for all the files + //returnObj.put("cleanName", cleanName); + + try { + // get the files + String[] files = inputData.get("file").split(";"); + + for(int i = 0; i < files.length; i++) { + + // store the file location on server so FE can send that back into actual upload routine + String filePath = files[i]; + + BufferedReader br = new BufferedReader(new FileReader(filePath)); + Map xray = gson.fromJson(br, Map.class); + + //.json file + //add json to local master + String jsonStringEscaped = gson.toJson(xray); + AddToMasterDB lm = new AddToMasterDB(); + lm.addXrayConfig(jsonStringEscaped, cleanName.replace(".xray", "")); + } + } catch(Exception e) { + e.printStackTrace(); + // grab the error thrown and send it to the FE + HashMap errorMap = new HashMap(); + errorMap.put("errorMessage", e.getMessage()); + return WebUtility.getResponse(errorMap, 400); + } + + return Response.status(200).entity(gson.toJson(returnObj)).build(); + } + + + + + + + /* + * THESE ARE JUST NOT REALLY USED ... + */ + + + @POST + @Path("/excel/processUpload") + @Produces("application/json") + public Response processExcelFile(@Context HttpServletRequest request) + { + Gson gson = new Gson(); + List fileItems = processRequest(request); + // collect all of the data input on the form + Hashtable inputData = getInputData(fileItems); + System.out.println(inputData); + + ImportOptions options = null; + String[] propFileArr = null; + try { + // load as many default options as possible + options = new ImportOptions(); + // now just load the rest as usual + setDefaultOptions(options, inputData); + // set the import type + options.setImportType(ImportOptions.IMPORT_TYPE.EXCEL); + + // only default options not set are the files + String files = inputData.get("file"); + if(files == null || files.trim().isEmpty()) { + Map errorHash = new HashMap(); + errorHash.put("errorMessage", "No files have been identified to upload"); + return Response.status(400).entity(gson.toJson(errorHash)).build(); + } + options.setFileLocation(files); + + ////////////////////// begin logic to process metamodel for excel flat table rdf ////////////////////// + List allFileData = gson.fromJson(inputData.get("fileInfoArray"), List.class); + int size = allFileData.size(); + + Hashtable[] propHashArr = new Hashtable[size]; + propFileArr = new String[size]; + boolean allEmpty = true; + for(int i = 0; i < size; i++) { + Hashtable itemForFile = gson.fromJson(allFileData.get(i), Hashtable.class); + ExcelPropFileBuilder propWriter = new ExcelPropFileBuilder(); + + Hashtable allSheetInfo = gson.fromJson(itemForFile.get("sheetInfo"), Hashtable.class); + for(String sheet : allSheetInfo.keySet()) { + Hashtable sheetInfo = gson.fromJson(allSheetInfo.get(sheet), Hashtable.class); + + List rel = gson.fromJson(sheetInfo.get("rowsRelationship"), List.class); + List prop = gson.fromJson(sheetInfo.get("rowsProperty"), List.class); + if((rel != null &&!rel.isEmpty()) || (prop != null && !prop.isEmpty()) ) { + allEmpty = false; } if(rel != null) { @@ -1284,37 +1379,71 @@ public Response processExcelFile(@Context HttpServletRequest request) Map retMap = UploadUtilities.getAppReturnData(user, appId); return Response.status(200).entity(gson.toJson(retMap)).build(); } - + @POST - //TODO: this path should be excel/uploadPOI - //TODO: cannot make this change without changing the path above - @Path("/excel/upload") + @Path("/nlp/upload") @Produces("application/json") - public Response uploadExcelPOIFormat(@Context HttpServletRequest request) - { + public Response uploadNLPFile(@Context HttpServletRequest request) { List fileItems = processRequest(request); // collect all of the data input on the form Hashtable inputData = getInputData(fileItems); System.out.println(inputData); Gson gson = new Gson(); + // we need to keep track of which NLP items loaded are files verses websites + // we need this so we can delete files after upload is done + String uploadFiles = ""; + String file = ""; ImportOptions options = null; try { - // load as many default options as possible options = new ImportOptions(); - // now just load the rest as usual + // set the default options setDefaultOptions(options, inputData); - // set the import type - options.setImportType(ImportOptions.IMPORT_TYPE.EXCEL_POI); + // can only store as RDF + options.setDbType(ImportOptions.DB_TYPE.RDF); + // set the type to be nlp + options.setImportType(ImportOptions.IMPORT_TYPE.NLP); // only default options not set are the files - String files = inputData.get("file"); - if(files == null || files.trim().isEmpty()) { + if(inputData.get("file") != null && !inputData.get("file").toString().isEmpty()) { + file = inputData.get("file").toString(); + uploadFiles = uploadFiles.concat(file); + } + if(inputData.get("nlptext") != null && !inputData.get("nlptext").toString().isEmpty()) { + String inputText = filePath + System.getProperty("file.separator") + "Text_Input.txt"; + PrintWriter writer = null; + try { + writer = new PrintWriter(inputText); + writer.write(inputData.get("nlptext").toString()); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } finally { + if(writer != null) { + writer.close(); + } + } + if(uploadFiles.isEmpty()) { + uploadFiles = uploadFiles.concat(inputText); + file = file.concat(inputText); + } else { + uploadFiles = uploadFiles.concat(";").concat(inputText); + file = file.concat(":").concat(inputText); + } + } + if(inputData.get("nlphttpurl") != null && !inputData.get("nlphttpurl").toString().isEmpty()) { + if(uploadFiles.isEmpty()) { + uploadFiles = uploadFiles.concat(inputData.get("nlphttpurl").toString()); + } else { + uploadFiles = uploadFiles.concat(";").concat(inputData.get("nlphttpurl").toString()); + } + } + // set the files + if(uploadFiles.trim().isEmpty()) { Map errorHash = new HashMap(); errorHash.put("errorMessage", "No files have been identified to upload"); return Response.status(400).entity(gson.toJson(errorHash)).build(); } - options.setFileLocation(files); + options.setFileLocation(uploadFiles); // add engine owner for permissions if(this.securityEnabled) { @@ -1327,7 +1456,7 @@ public Response uploadExcelPOIFormat(@Context HttpServletRequest request) addEngineOwner(options.getEngineID(), options.getDbName(), "RDF", "", user); } - // run the processor + // run the importer ImportDataProcessor importer = new ImportDataProcessor(); importer.runProcessor(options); } catch (IOException e) { @@ -1341,21 +1470,32 @@ public Response uploadExcelPOIFormat(@Context HttpServletRequest request) errorHash.put("errorMessage", e.getMessage()); return Response.status(400).entity(gson.toJson(errorHash)).build(); } finally { - deleteFilesFromServer(inputData.get("file").toString().split(";")); + if(file != null && !file.isEmpty()) { + deleteFilesFromServer(file.split(";")); + } String questionFile = inputData.get("questionFile"); if(questionFile != null && !questionFile.isEmpty()) { deleteFilesFromServer(new String[]{questionFile}); - } + } } - String appId = options.getEngineID(); - User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - Map retMap = UploadUtilities.getAppReturnData(user, appId); - return Response.status(200).entity(gson.toJson(retMap)).build(); + String outputText = "NLP Loading was a success."; + return Response.status(200).entity(gson.toJson(outputText)).build(); } + + ///////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////////////////////////// + + /* + * METHODS PREVIOUSLY USED BUT REPLACED BY PIXEL REACTORS + */ + + // @POST -// @Path("/excel/flat") +// @Path("/csv/flat") // @Produces("application/json") // /** // * The process flow for loading a flat file based on drag/drop @@ -1365,7 +1505,7 @@ public Response uploadExcelPOIFormat(@Context HttpServletRequest request) // * @param request // * @return // */ -// public Response uploadFlatExcelFile(MultivaluedMap form, @Context HttpServletRequest request) { +// public Response uploadFlatCsvFile(MultivaluedMap form, @Context HttpServletRequest request) { // Gson gson = new Gson(); // System.out.println(form); // @@ -1376,7 +1516,7 @@ public Response uploadExcelPOIFormat(@Context HttpServletRequest request) // // can only load flat files as RDBMS // options.setDbType(ImportOptions.DB_TYPE.RDBMS); // options.setRDBMSDriverType(SQLQueryUtil.DB_TYPE.H2_DB); -// options.setImportType(ImportOptions.IMPORT_TYPE.EXCEL_FLAT_UPLOAD); +// options.setImportType(ImportOptions.IMPORT_TYPE.CSV_FLAT_LOAD); // // // set the files // String files = form.getFirst("file"); @@ -1389,26 +1529,26 @@ public Response uploadExcelPOIFormat(@Context HttpServletRequest request) // // // see if user also manually changed some the headers // String newHeadersStr = form.getFirst("newHeaders"); +// System.out.println("new headers is " + newHeadersStr); +// if(newHeadersStr != null && newHeadersStr.equalsIgnoreCase("undefined")) +// newHeadersStr = null; // if(newHeadersStr != null) { -// List>> newHeaders = -// gson.fromJson(newHeadersStr, new TypeToken>>>() {}.getType()); -// options.setExcelNewHeaders(newHeaders); +// Map> newHeaders = +// gson.fromJson(newHeadersStr, new TypeToken>>() {}.getType()); +// options.setCsvNewHeaders(newHeaders); // } // // // this should always be present now since we dont want to predict types twice on the BE // // get the data types and set them in the options // String headerDataTypesStr = form.getFirst("headerData"); // if(headerDataTypesStr != null) { -// List>> headerDataTypes = -// gson.fromJson(headerDataTypesStr, new TypeToken>>>() {}.getType()); -// options.setExcelDataTypeMap(headerDataTypes); +// List> headerDataTypes = gson.fromJson(headerDataTypesStr, new TypeToken>>() {}.getType()); +// options.setCsvDataTypeMap(headerDataTypes); // // // track GA data -// String dbName = form.getFirst("dbName"); -// String fileName = files.substring(files.lastIndexOf("\\") + 1, files.lastIndexOf(".")); -// GATracker.getInstance().trackExcelUpload(dbName, fileName, headerDataTypes); +// String tableName = form.getFirst("dbName"); +// GATracker.getInstance().trackCsvUpload(files, tableName, headerDataTypes); // } -// // // add engine owner for permissions // if(this.securityEnabled) { // Object user = request.getSession().getAttribute(Constants.SESSION_USER); @@ -1448,113 +1588,125 @@ public Response uploadExcelPOIFormat(@Context HttpServletRequest request) // String outputText = "Flat database loading was a success."; // return Response.status(200).entity(gson.toJson(outputText)).build(); // } - - ////////////////////////////////////////////// END EXCEL UPLOADING ////////////////////////////////////////////////////////// - - - @POST - @Path("/nlp/upload") - @Produces("application/json") - public Response uploadNLPFile(@Context HttpServletRequest request) { - List fileItems = processRequest(request); - // collect all of the data input on the form - Hashtable inputData = getInputData(fileItems); - System.out.println(inputData); - - Gson gson = new Gson(); - // we need to keep track of which NLP items loaded are files verses websites - // we need this so we can delete files after upload is done - String uploadFiles = ""; - String file = ""; - ImportOptions options = null; - try { - options = new ImportOptions(); - // set the default options - setDefaultOptions(options, inputData); - // can only store as RDF - options.setDbType(ImportOptions.DB_TYPE.RDF); - // set the type to be nlp - options.setImportType(ImportOptions.IMPORT_TYPE.NLP); - - // only default options not set are the files - if(inputData.get("file") != null && !inputData.get("file").toString().isEmpty()) { - file = inputData.get("file").toString(); - uploadFiles = uploadFiles.concat(file); - } - if(inputData.get("nlptext") != null && !inputData.get("nlptext").toString().isEmpty()) { - String inputText = filePath + System.getProperty("file.separator") + "Text_Input.txt"; - PrintWriter writer = null; - try { - writer = new PrintWriter(inputText); - writer.write(inputData.get("nlptext").toString()); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } finally { - if(writer != null) { - writer.close(); - } - } - if(uploadFiles.isEmpty()) { - uploadFiles = uploadFiles.concat(inputText); - file = file.concat(inputText); - } else { - uploadFiles = uploadFiles.concat(";").concat(inputText); - file = file.concat(":").concat(inputText); - } - } - if(inputData.get("nlphttpurl") != null && !inputData.get("nlphttpurl").toString().isEmpty()) { - if(uploadFiles.isEmpty()) { - uploadFiles = uploadFiles.concat(inputData.get("nlphttpurl").toString()); - } else { - uploadFiles = uploadFiles.concat(";").concat(inputData.get("nlphttpurl").toString()); - } - } - // set the files - if(uploadFiles.trim().isEmpty()) { - Map errorHash = new HashMap(); - errorHash.put("errorMessage", "No files have been identified to upload"); - return Response.status(400).entity(gson.toJson(errorHash)).build(); - } - options.setFileLocation(uploadFiles); - - // add engine owner for permissions - if(this.securityEnabled) { - User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - if(user == null) { - Map errorHash = new HashMap(); - errorHash.put("errorMessage", "User must be signed into an account in order to create a database"); - return Response.status(400).entity(gson.toJson(errorHash)).build(); - } - addEngineOwner(options.getEngineID(), options.getDbName(), "RDF", "", user); - } - - // run the importer - ImportDataProcessor importer = new ImportDataProcessor(); - importer.runProcessor(options); - } catch (IOException e) { - e.printStackTrace(); - Map errorHash = new HashMap(); - errorHash.put("errorMessage", e.getMessage()); - return Response.status(400).entity(gson.toJson(errorHash)).build(); - } catch(Exception e) { - e.printStackTrace(); - Map errorHash = new HashMap(); - errorHash.put("errorMessage", e.getMessage()); - return Response.status(400).entity(gson.toJson(errorHash)).build(); - } finally { - if(file != null && !file.isEmpty()) { - deleteFilesFromServer(file.split(";")); - } - String questionFile = inputData.get("questionFile"); - if(questionFile != null && !questionFile.isEmpty()) { - deleteFilesFromServer(new String[]{questionFile}); - } - } - - String outputText = "NLP Loading was a success."; - return Response.status(200).entity(gson.toJson(outputText)).build(); - } - +// +// @POST +// @Path("/excel/flat") +// @Produces("application/json") +// /** +// * The process flow for loading a flat file based on drag/drop +// * Since the user confirms what type of datatypes they want for each column +// * The file has already been loaded onto the server +// * @param form Form object containing all the information regarding the load +// * @param request +// * @return +// */ +// public Response uploadFlatExcelFile(MultivaluedMap form, @Context HttpServletRequest request) { +// Gson gson = new Gson(); +// System.out.println(form); +// +// ImportOptions options = null; +// try { +// options = new ImportOptions(); +// setDefaultOptions(options, form); +// // can only load flat files as RDBMS +// options.setDbType(ImportOptions.DB_TYPE.RDBMS); +// options.setRDBMSDriverType(SQLQueryUtil.DB_TYPE.H2_DB); +// options.setImportType(ImportOptions.IMPORT_TYPE.EXCEL_FLAT_UPLOAD); +// +// // set the files +// String files = form.getFirst("file"); +// if(files == null || files.trim().isEmpty()) { +// Map errorHash = new HashMap(); +// errorHash.put("errorMessage", "No files have been identified to upload"); +// return Response.status(400).entity(gson.toJson(errorHash)).build(); +// } +// options.setFileLocation(files); +// +// // see if user also manually changed some the headers +// String newHeadersStr = form.getFirst("newHeaders"); +// if(newHeadersStr != null) { +// List>> newHeaders = +// gson.fromJson(newHeadersStr, new TypeToken>>>() {}.getType()); +// options.setExcelNewHeaders(newHeaders); +// } +// +// // this should always be present now since we dont want to predict types twice on the BE +// // get the data types and set them in the options +// String headerDataTypesStr = form.getFirst("headerData"); +// if(headerDataTypesStr != null) { +// List>> headerDataTypes = +// gson.fromJson(headerDataTypesStr, new TypeToken>>>() {}.getType()); +// options.setExcelDataTypeMap(headerDataTypes); +// +// // track GA data +// String dbName = form.getFirst("dbName"); +// String fileName = files.substring(files.lastIndexOf("\\") + 1, files.lastIndexOf(".")); +// GATracker.getInstance().trackExcelUpload(dbName, fileName, headerDataTypes); +// } +// +// // add engine owner for permissions +// if(this.securityEnabled) { +// Object user = request.getSession().getAttribute(Constants.SESSION_USER); +// if(user != null && !((User) user).getId().equals(Constants.ANONYMOUS_USER_ID)) { +// addEngineOwner(options.getDbName(), ((User) user).getId()); +// } else { +// Map errorHash = new HashMap(); +// errorHash.put("errorMessage", "Please log in to upload data."); +// return Response.status(400).entity(gson.toJson(errorHash)).build(); +// } +// } +// +// ImportDataProcessor importer = new ImportDataProcessor(); +// importer.runProcessor(options); +// } catch (IOException e) { +// e.printStackTrace(); +// Map errorHash = new HashMap(); +// errorHash.put("errorMessage", e.getMessage()); +// return Response.status(400).entity(gson.toJson(errorHash)).build(); +// } catch(Exception e) { +// e.printStackTrace(); +// Map errorHash = new HashMap(); +// errorHash.put("errorMessage", e.getMessage()); +// return Response.status(400).entity(gson.toJson(errorHash)).build(); +// } finally { +// // we can't really use the options object for this :/ +// String files = form.getFirst("file"); +// if(files != null && !files.isEmpty()) { +// deleteFilesFromServer(files.split(";")); +// } +// String questionFile = form.getFirst("questionFile"); +// if(questionFile != null && !questionFile.isEmpty()) { +// deleteFilesFromServer(new String[]{questionFile}); +// } +// } +// +// String outputText = "Flat database loading was a success."; +// return Response.status(200).entity(gson.toJson(outputText)).build(); +// } +// +// // TODO: refactor this into setDefaultOptions +// private ImportOptions setupImportOptionsForExternalConnection(HashMap options, HashMap externalMetamodel) { +// ImportOptions importOptions = new ImportOptions(); +// importOptions.setBaseFolder(DIHelper.getInstance().getProperty("BaseFolder")); +// importOptions.setDbType(ImportOptions.DB_TYPE.RDBMS); +// importOptions.setImportMethod(ImportOptions.IMPORT_METHOD.CONNECT_TO_EXISTING_RDBMS); +// importOptions.setImportType(ImportOptions.IMPORT_TYPE.EXTERNAL_RDBMS); +// importOptions.setAutoLoad(autoLoad); +// importOptions.setAllowDuplicates(true); +// importOptions.setDbName(options.get("dbName")); +// importOptions.setRDBMSDriverType(SQLQueryUtil.DB_TYPE.valueOf(options.get("driver"))); +// //importOptions.setRDBMSDriverType(SQLQueryUtil.DB_TYPE.DB2); +// importOptions.setHost(options.get("hostname")); +// importOptions.setPort(options.get("port")); +// importOptions.setSchema(options.get("schema")); +// importOptions.setUsername(options.get("username")); +// importOptions.setPassword(options.get("password")); +// importOptions.setAdditionalJDBCProperties(options.get("additionalParams")); +// importOptions.setExternalMetamodel(externalMetamodel); +// +// return importOptions; +// } +// // @GET // @Path("/solr/ping") // @Produces("applicaiton/json") @@ -1641,287 +1793,8 @@ public Response uploadNLPFile(@Context HttpServletRequest request) { // } // } - @POST - @Path("/rdbms/getMetadata2") - @Produces("application/json") - public Response getExistingRDBMSMetadata2(@Context HttpServletRequest request, MultivaluedMap form) { - Gson gson = new Gson(); - ImportRDBMSProcessor importer = new ImportRDBMSProcessor(); - - String driver = form.getFirst("driver"); - String hostname = form.getFirst("hostname"); - String port = form.getFirst("port"); - String username = form.getFirst("username"); - String password = form.getFirst("password"); - String schema = form.getFirst("schema"); - String additionalProperties = form.getFirst("additionalParams"); - - Map ret = new HashMap(); - try { - ret = importer.getSchemaDetails(driver, hostname, port, username, password, schema, additionalProperties); - } catch(Exception e) { - e.printStackTrace(); - if(e.getMessage() != null) { - ret.put("errorMessage", e.getMessage()); - } else { - ret.put("errorMessage", "Unexpected error determining metadata"); - } - return Response.status(400).entity(gson.toJson(ret)).build(); - } - - return Response.status(200).entity(gson.toJson(ret)).build(); - } - - @POST - @Path("/rdbms/connect") - @Produces("application/json") - public Response connectExistingRDBMS(@Context HttpServletRequest request, MultivaluedMap form) { - Gson gson = new Gson(); - HashMap ret = new HashMap(1); - Map metamodel = new HashMap(); - HashMap details = gson.fromJson(form.getFirst("details"), new TypeToken>() {}.getType()); - HashMap metamodelData = gson.fromJson(gson.toJson(details.get("metamodelData")), new TypeToken>() {}.getType()); - ArrayList nodes = gson.fromJson(gson.toJson(metamodelData.get("nodes")), new TypeToken>() {}.getType()); - ArrayList relationships = gson.fromJson(gson.toJson(metamodelData.get("relationships")), new TypeToken>() {}.getType()); - // reformat metamodel for new reactor - HashMap> nodesAndProps = new HashMap>(nodes.size()); - ArrayList> nodeRelationships = new ArrayList<>(relationships.size()); - for(Object o: nodes) { - ArrayList props = new ArrayList(); - HashMap nodeHash = gson.fromJson(gson.toJson(o), new TypeToken>() {}.getType()); - ArrayList properties = gson.fromJson(gson.toJson(nodeHash.get("prop")), new TypeToken>() {}.getType()); - for(String prop : properties) { - props.add(prop); - } - nodesAndProps.put(nodeHash.get("node") + "." + nodeHash.get("primaryKey"), props); // Table1.idTable1 -> [prop1, prop2, ...] - } - metamodel.put(Constants.NODE_PROP, nodesAndProps); - for(Object o: relationships) { - HashMap relationship = gson.fromJson(gson.toJson(o), new TypeToken>() {}.getType()); - String fromTable = relationship.get("sub"); - String relName = relationship.get("pred"); - String toTable = relationship.get("obj"); - Map relMap = new HashMap<>(); - relMap.put(Constants.FROM_TABLE, fromTable); - relMap.put(Constants.REL_NAME, relName); - relMap.put(Constants.TO_TABLE, toTable); - nodeRelationships.add(relMap); - } - metamodel.put(Constants.RELATION, nodeRelationships); - - HashMap databaseOptions = gson.fromJson(gson.toJson(details.get("databaseOptions")), new TypeToken>() {}.getType()); - HashMap options = gson.fromJson(gson.toJson(details.get("options")), new TypeToken>() {}.getType()); - options.put("dbName", Utility.makeAlphaNumeric(databaseOptions.get("databaseName"))); - - boolean success = true; - - // mocking inputs until FE makes full pixel call - RdbmsExternalUploadReactor reactor = new RdbmsExternalUploadReactor(); - reactor.In(); - // make an insight to set - // so we can pass the user - Insight dummyIn = new Insight(); - InsightStore.getInstance().put(dummyIn); - //TODO do we need this? - // InsightStore.getInstance().addToSessionHash(session.getId(), - // dummyIn.getInsightId()); - // dummyIn.getVarStore().put(JobReactor.SESSION_KEY, new - // NounMetadata(session.getId(), PixelDataType.CONST_STRING)); - // dummyIn.setUser(user); - if (this.securityEnabled) { - User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - dummyIn.setUser(user); - } - reactor.setInsight(dummyIn); - PixelPlanner planner = new PixelPlanner(); - planner.setVarStore(dummyIn.getVarStore()); - reactor.setPixelPlanner(planner); - // add app name - GenRowStruct grs1 = new GenRowStruct(); - grs1.add(new NounMetadata(Utility.makeAlphaNumeric(databaseOptions.get("databaseName")), - PixelDataType.CONST_STRING)); - reactor.getNounStore().addNoun(ReactorKeysEnum.APP.getKey(), grs1); - // add db driver - GenRowStruct grs2 = new GenRowStruct(); - grs2.add(new NounMetadata(options.get("driver"), PixelDataType.CONST_STRING)); - reactor.getNounStore().addNoun(ReactorKeysEnum.DB_DRIVER_KEY.getKey(), grs2); - // add host - GenRowStruct grs3 = new GenRowStruct(); - grs3.add(new NounMetadata(options.get("hostname"), PixelDataType.CONST_STRING)); - reactor.getNounStore().addNoun(ReactorKeysEnum.HOST.getKey(), grs3); - // add port - GenRowStruct grs4 = new GenRowStruct(); - grs4.add(new NounMetadata(options.get("port"), PixelDataType.CONST_STRING)); - reactor.getNounStore().addNoun(ReactorKeysEnum.PORT.getKey(), grs4); - // add schema - GenRowStruct grs5 = new GenRowStruct(); - grs5.add(new NounMetadata(options.get("schema"), PixelDataType.CONST_STRING)); - reactor.getNounStore().addNoun(ReactorKeysEnum.SCHEMA.getKey(), grs5); - // add username - GenRowStruct grs6 = new GenRowStruct(); - grs6.add(new NounMetadata(options.get("username"), PixelDataType.CONST_STRING)); - reactor.getNounStore().addNoun(ReactorKeysEnum.USERNAME.getKey(), grs6); - // add password - GenRowStruct grs7 = new GenRowStruct(); - grs7.add(new NounMetadata(options.get("password"), PixelDataType.CONST_STRING)); - reactor.getNounStore().addNoun(ReactorKeysEnum.PASSWORD.getKey(), grs7); - // add additional paras - GenRowStruct grs8 = new GenRowStruct(); - grs8.add(new NounMetadata(options.get("additionalParams"), PixelDataType.CONST_STRING)); - reactor.getNounStore().addNoun(ReactorKeysEnum.ADDITIONAL_CONNECTION_PARAMS_KEY.getKey(), grs8); - // add metamodel - // additional paras - GenRowStruct grs9 = new GenRowStruct(); - grs9.add(new NounMetadata(metamodel, PixelDataType.MAP)); - reactor.getNounStore().addNoun(ReactorKeysEnum.METAMODEL.getKey(), grs9); - - // execute! - reactor.execute(); - - ret.put("success", success); - if(success) { - return Response.status(200).entity(gson.toJson(ret)).build(); - } else { - return Response.status(400).entity(gson.toJson(ret)).build(); - } - } - // TODO: refactor this into setDefaultOptions - private ImportOptions setupImportOptionsForExternalConnection(HashMap options, HashMap externalMetamodel) { - ImportOptions importOptions = new ImportOptions(); - importOptions.setBaseFolder(DIHelper.getInstance().getProperty("BaseFolder")); - importOptions.setDbType(ImportOptions.DB_TYPE.RDBMS); - importOptions.setImportMethod(ImportOptions.IMPORT_METHOD.CONNECT_TO_EXISTING_RDBMS); - importOptions.setImportType(ImportOptions.IMPORT_TYPE.EXTERNAL_RDBMS); - importOptions.setAutoLoad(autoLoad); - importOptions.setAllowDuplicates(true); - importOptions.setDbName(options.get("dbName")); - importOptions.setRDBMSDriverType(SQLQueryUtil.DB_TYPE.valueOf(options.get("driver"))); - //importOptions.setRDBMSDriverType(SQLQueryUtil.DB_TYPE.DB2); - importOptions.setHost(options.get("hostname")); - importOptions.setPort(options.get("port")); - importOptions.setSchema(options.get("schema")); - importOptions.setUsername(options.get("username")); - importOptions.setPassword(options.get("password")); - importOptions.setAdditionalJDBCProperties(options.get("additionalParams")); - importOptions.setExternalMetamodel(externalMetamodel); - - return importOptions; - } - - @POST - @Path("/rdbms/test") - @Produces("application/json") - public Response testExistingRDBMSConnection(@Context HttpServletRequest request, MultivaluedMap form) { - Gson gson = new Gson(); - String driver = form.getFirst("driver"); - String hostname = form.getFirst("hostname"); - String port = form.getFirst("port"); - String username = form.getFirst("username"); - String password = form.getFirst("password"); - String schema = form.getFirst("schema"); - String additionalProperties = form.getFirst("additionalParams"); - HashMap ret = new HashMap(); - - ImportRDBMSProcessor importer = new ImportRDBMSProcessor(); - String test = importer.checkConnectionParams(driver, hostname, port, username, password, schema, additionalProperties); - if(Boolean.parseBoolean(test)) { - ret.put("success", Boolean.parseBoolean(test)); - return Response.status(200).entity(gson.toJson(ret)).build(); - } else { - ret.put("error", test); - return Response.status(400).entity(gson.toJson(ret)).build(); - } - } - - /** - * Writes OpenRefine-cleaned values to CSV file to be processed by ImportDataProcessor. - * - * @param cleanedValues Cleaned data returned from OpenRefine - * @return Name of file on file system the cleaned data was written to - */ - private String processOpenRefine(String dbName, String cleanedValues) { - FileWriter fw = null; - String filename = this.filePath + System.getProperty("file.separator") + dbName + "_Cleaned.csv"; - try { - fw = new FileWriter(filename); - fw.append(cleanedValues); - fw.flush(); - } catch (IOException e) { - return "Error: Could not write cleaned values."; - } finally { - try { - if(fw != null) { - fw.close(); - } - } catch (IOException e) { - e.printStackTrace(); - } - } - - return filename; - } - - public void addEngineOwner(String engineId, String engineName, String engineType, String engineCost, User user) { - List logins = user.getLogins(); - for(AuthProvider ap : logins) { - SecurityUpdateUtils.addEngineOwner(engineId, user.getAccessToken(ap).getId()); - } - } - - @POST - @Path("/json/uploadXrayConfig") - @Produces("application/json") - /* - * This method is used for uploading x-ray configuration - * uploads a json file and returns a string of the parsed json - * and deletes the file. - */ - public Response uploadXrayConfig(@Context HttpServletRequest request) { - Gson gson = new Gson(); - - //process request - List fileItems = processRequest(request); - String cleanName = fileItems.get(0).getName(); - // collect all of the data input on the form - Hashtable inputData = getInputData(fileItems); - - // objects to store data - // master object to send to FE - Map returnObj = new HashMap<>(2); - // this will store the MM info for all the files - //returnObj.put("cleanName", cleanName); - - try { - // get the files - String[] files = inputData.get("file").split(";"); - for(int i = 0; i < files.length; i++) { - - // store the file location on server so FE can send that back into actual upload routine - String filePath = files[i]; - String file = filePath.substring(filePath.lastIndexOf("\\") + 1, filePath.lastIndexOf(".")); - - BufferedReader br = new BufferedReader(new FileReader(filePath)); - Map xray = gson.fromJson(br, Map.class); - - //.json file - //add json to local master - String jsonStringEscaped = gson.toJson(xray); - AddToMasterDB lm = new AddToMasterDB(); - lm.addXrayConfig(jsonStringEscaped, cleanName.replace(".xray", "")); - - - } - } catch(Exception e) { - e.printStackTrace(); - // grab the error thrown and send it to the FE - HashMap errorMap = new HashMap(); - errorMap.put("errorMessage", e.getMessage()); - return WebUtility.getResponse(errorMap, 400); - } - - return Response.status(200).entity(gson.toJson(returnObj)).build(); - } - + + } From c0539822e7db41f9acd58bd78c838e9c8d8538ce Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 14 Sep 2018 16:43:12 +0000 Subject: [PATCH 0233/1906] BUGFIX ::: Fixing poi import to new database git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30075 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: a8d48e77bb4fa96b70e6cf2f6d9c8d8d44dd2253 --- src/prerna/upload/DatabaseUploader.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/prerna/upload/DatabaseUploader.java b/src/prerna/upload/DatabaseUploader.java index 9c33366a2..b416b3be9 100644 --- a/src/prerna/upload/DatabaseUploader.java +++ b/src/prerna/upload/DatabaseUploader.java @@ -14,6 +14,7 @@ import java.util.Hashtable; import java.util.List; import java.util.Map; +import java.util.UUID; import java.util.Vector; import javax.servlet.http.HttpServletRequest; @@ -139,6 +140,8 @@ private void setDefaultOptions(ImportOptions options, Map inputD options.setEngineID(dbName); options.setDbName(MasterDatabaseUtility.getEngineAliasForId(dbName)); } else { + // make a new id + options.setEngineID(UUID.randomUUID().toString()); options.setDbName(Utility.makeAlphaNumeric(dbName)); } @@ -219,6 +222,8 @@ private void setDefaultOptions(ImportOptions options, MultivaluedMap Date: Mon, 17 Sep 2018 14:01:55 +0000 Subject: [PATCH 0234/1906] UPDATE ::: Sending back ordered list for systems git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30088 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: d6895e820f8a7bd0ef2b84913078e7039050eadf --- src/prerna/semoss/web/form/FormResource.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/prerna/semoss/web/form/FormResource.java b/src/prerna/semoss/web/form/FormResource.java index dbb271e37..78c0d123f 100644 --- a/src/prerna/semoss/web/form/FormResource.java +++ b/src/prerna/semoss/web/form/FormResource.java @@ -4,6 +4,7 @@ import java.util.HashMap; import java.util.Hashtable; import java.util.Map; +import java.util.TreeMap; import javax.naming.InvalidNameException; import javax.servlet.http.HttpServletRequest; @@ -167,7 +168,7 @@ public Response getUserInstanceAuth(@Context HttpServletRequest request) throws return WebUtility.getResponse(err, 400); } - Map userAccessableInstances = new HashMap(); + Map userAccessableInstances = new TreeMap(); // map to store the valid instances for the given user String query = "SELECT INSTANCE_NAME, IS_SYS_ADMIN FROM FORMS_USER_ACCESS WHERE USER_ID = '" + cacId + "';"; From ce3c7b8bc4f8896c1d236856c6e74579ce48d5a9 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 18 Sep 2018 21:45:14 +0000 Subject: [PATCH 0235/1906] UPDATE ::: Adding CDSE and Innowake POM to work properly by extending Monolith_Dev UPDATE ::: Monolith to also output its classes as a jar so other apps can extend from it UPDATE ::: Pushing proper login screen to cdse + innowake git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30136 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 5cbdacff1f4b8a98348f7f576ebabb627661bf2f --- pom.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pom.xml b/pom.xml index b7c9b714f..1d52a1cbd 100644 --- a/pom.xml +++ b/pom.xml @@ -73,6 +73,7 @@ WebContent/WEB-INF/web.xml true + true ${basedir}/WebContent index.html, @@ -118,6 +119,7 @@ WebContent/WEB-INF/web.xml true + true ${basedir}/WebContent index.html, From b4dd854d19815bfaf64a3c42754eff7e11133bbe Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 19 Sep 2018 16:47:55 +0000 Subject: [PATCH 0236/1906] UPDATE ::: Fixing order of filters to work for forms app when CAC is present git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30139 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: a123bfc251d0f0cd9b3a824f4e831bcd8d187a54 --- WebContent/WEB-INF/web.xml | 54 ++++------- src/prerna/web/conf/CACFilter.java | 25 ++--- src/prerna/web/conf/NoUserExistsFilter.java | 76 +++++++++++++++ ...Filter.java => NoUserInSessionFilter.java} | 93 ++++++------------- .../web/conf/UserRestrictionFilter.java | 64 ------------- 5 files changed, 129 insertions(+), 183 deletions(-) create mode 100644 src/prerna/web/conf/NoUserExistsFilter.java rename src/prerna/web/conf/{NoUserFilter.java => NoUserInSessionFilter.java} (50%) delete mode 100644 src/prerna/web/conf/UserRestrictionFilter.java diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index 1ecb43e7e..8ab223ed7 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -1,36 +1,17 @@ - Monolith_Dev + Monolith index.html - - NoUserFilter - prerna.web.conf.NoUserFilter + NoUserExistsFilter + prerna.web.conf.NoUserExistsFilter - NoUserFilter - /api/* - - - AdminStartupFilter - prerna.web.conf.AdminStartupFilter - - - AdminStartupFilter - /adminconfig/* - - --> - - - - - UserDBInsightFilter - prerna.web.conf.UserDBInsightFilter + AdminStartupFilter + prerna.web.conf.AdminStartupFilter - - UserDBInsightFilter - /api/* + + AdminStartupFilter + /adminconfig/* - --> diff --git a/src/prerna/web/conf/CACFilter.java b/src/prerna/web/conf/CACFilter.java index 32612c3ee..ad5ba53a7 100644 --- a/src/prerna/web/conf/CACFilter.java +++ b/src/prerna/web/conf/CACFilter.java @@ -17,7 +17,6 @@ import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.apache.log4j.LogManager; @@ -32,7 +31,7 @@ public class CACFilter implements Filter { private static final Logger LOGGER = LogManager.getLogger(CACFilter.class.getName()); - + @Override public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { X509Certificate[] certs = (X509Certificate[]) arg0.getAttribute("javax.servlet.request.X509Certificate"); @@ -40,7 +39,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 User user = null; AccessToken token = null; - + if(certs != null) { user = (User) session.getAttribute(Constants.SESSION_USER); if(user == null) { @@ -87,7 +86,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 // now set the other properties token.setToken_type(cert.getIssuerDN().getName()); token.setExpires_in((int) cert.getNotAfter().getTime()); - + // try to get the email try { EMAIL_LOOP : for(List altNames : cert.getSubjectAlternativeNames()) { @@ -105,8 +104,8 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 } catch (CertificateParsingException e) { e.printStackTrace(); } - - + + break CERT_LOOP; } else { continue; @@ -126,23 +125,13 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 LOGGER.info("Valid request coming from user " + token.getName()); user.setAccessToken(token); session.setAttribute(Constants.SESSION_USER, user); - + // add the user if they do not exist SecurityUpdateUtils.addOAuthUser(token); } } } - - if(session.getAttribute(Constants.SESSION_USER) == null) { - ((HttpServletResponse) arg1).setStatus(302); - - String redirectUrl = ((HttpServletRequest) arg0).getHeader("referer"); - redirectUrl = redirectUrl + "#!/login"; - ((HttpServletResponse) arg1).setHeader("redirect", redirectUrl); - ((HttpServletResponse) arg1).sendError(302, "Need to redirect to " + redirectUrl); - return; - } - + arg2.doFilter(arg0, arg1); } diff --git a/src/prerna/web/conf/NoUserExistsFilter.java b/src/prerna/web/conf/NoUserExistsFilter.java new file mode 100644 index 000000000..146501d00 --- /dev/null +++ b/src/prerna/web/conf/NoUserExistsFilter.java @@ -0,0 +1,76 @@ +package prerna.web.conf; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import prerna.engine.api.IEngine; +import prerna.engine.api.IRawSelectWrapper; +import prerna.rdf.engine.wrappers.WrapperManager; +import prerna.semoss.web.services.AdminConfigService; +import prerna.util.Constants; +import prerna.util.Utility; + +public class NoUserExistsFilter implements Filter { + + @Override + public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { + ServletContext context = arg0.getServletContext(); + // this will be the full path of the request + // like http://localhost:8080/Monolith_Dev/api/engine/runPixel + String fullUrl = ((HttpServletRequest) arg0).getRequestURL().toString(); + + boolean security = Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED)); + if(security) { + IEngine engine = Utility.getEngine(Constants.SECURITY_DB); + String q = "SELECT * FROM USER LIMIT 1"; + IRawSelectWrapper wrapper = WrapperManager.getInstance().getRawWrapper(engine, q); + try { + boolean hasUser = wrapper.hasNext(); + + // no users at all registered, we need to send to the admin page + if(!hasUser) { + + // we need to store information in the session + // so that we can properly come back to the referer once an admin has been added + String referer = ((HttpServletRequest) arg0).getHeader("referer"); + referer = referer + "#!/login"; + ((HttpServletRequest) arg0).getSession(true).setAttribute(AdminConfigService.ADMIN_REDIRECT_KEY, referer); + + // this will be the deployment name of the app + String contextPath = context.getContextPath(); + + // we redirect to the index.html page where we have pushed the admin page + String redirectUrl = fullUrl.substring(0, fullUrl.indexOf(contextPath) + contextPath.length()); + ((HttpServletResponse) arg1).setHeader("redirect", redirectUrl); + ((HttpServletResponse) arg1).sendError(302, "Need to redirect to " + redirectUrl); + return; + } + } finally { + wrapper.cleanUp(); + } + } + + arg2.doFilter(arg0, arg1); + } + + @Override + public void destroy() { + // TODO Auto-generated method stub + + } + + @Override + public void init(FilterConfig arg0) throws ServletException { + // TODO Auto-generated method stub + + } +} diff --git a/src/prerna/web/conf/NoUserFilter.java b/src/prerna/web/conf/NoUserInSessionFilter.java similarity index 50% rename from src/prerna/web/conf/NoUserFilter.java rename to src/prerna/web/conf/NoUserInSessionFilter.java index b3b808ced..fd80dd6a6 100644 --- a/src/prerna/web/conf/NoUserFilter.java +++ b/src/prerna/web/conf/NoUserInSessionFilter.java @@ -17,14 +17,9 @@ import prerna.auth.AuthProvider; import prerna.auth.User; -import prerna.engine.api.IEngine; -import prerna.engine.api.IRawSelectWrapper; -import prerna.rdf.engine.wrappers.WrapperManager; -import prerna.semoss.web.services.AdminConfigService; import prerna.util.Constants; -import prerna.util.Utility; -public class NoUserFilter implements Filter { +public class NoUserInSessionFilter implements Filter { private static List ignoreDueToFE = new Vector(); static { @@ -39,96 +34,68 @@ public class NoUserFilter implements Filter { ignoreDueToFE.add("auth/login/" + v.toString().toLowerCase()); } } - + @Override public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { ServletContext context = arg0.getServletContext(); // this will be the full path of the request // like http://localhost:8080/Monolith_Dev/api/engine/runPixel String fullUrl = ((HttpServletRequest) arg0).getRequestURL().toString(); - + boolean security = Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED)); if(security) { - IEngine engine = Utility.getEngine(Constants.SECURITY_DB); - String q = "SELECT * FROM USER LIMIT 1"; - IRawSelectWrapper wrapper = WrapperManager.getInstance().getRawWrapper(engine, q); - try { - boolean hasUser = wrapper.hasNext(); - - // no users at all registered, we need to send to the admin page - if(!hasUser) { - - // we need to store information in the session - // so that we can properly come back to the referer once an admin has been added - String referer = ((HttpServletRequest) arg0).getHeader("referer"); - referer = referer + "#!/login"; - ((HttpServletRequest) arg0).getSession(true).setAttribute(AdminConfigService.ADMIN_REDIRECT_KEY, referer); - - // this will be the deployment name of the app - String contextPath = context.getContextPath(); - - // we redirect to the index.html page where we have pushed the admin page - String redirectUrl = fullUrl.substring(0, fullUrl.indexOf(contextPath) + contextPath.length()); + // REALLY DISLIKE THIS CHECK!!! + if(!isIgnored(fullUrl)) { + // due to FE being annoying + // we need to push a response for this one end point + // since security is embedded w/ normal semoss and not standalone + + HttpSession session = ((HttpServletRequest) arg0).getSession(true); + // users are registered but dont know who this specific user is + // take them to the login page + if(session.getAttribute("user") == null) { + session.setAttribute("user", true); + ((HttpServletResponse) arg1).setStatus(302); + + String redirectUrl = ((HttpServletRequest) arg0).getHeader("referer"); + redirectUrl = redirectUrl + "#!/login"; ((HttpServletResponse) arg1).setHeader("redirect", redirectUrl); ((HttpServletResponse) arg1).sendError(302, "Need to redirect to " + redirectUrl); return; } - - // REALLY DISLIKE THIS CHECK!!! - else if(!isIgnored(fullUrl)) { - // due to FE being annoying - // we need to push a response for this one end point - // since security is embedded w/ normal semoss and not standalone - - HttpSession session = ((HttpServletRequest) arg0).getSession(true); - // users are registered but dont know who this specific user is - // take them to the login page - if(session.getAttribute("user") == null) { - session.setAttribute("user", true); + + // have the user redirect value + // need to make sure no one did any funny business and doesn't have an actual user object + else { + User user = (User) session.getAttribute(Constants.SESSION_USER); + if(user == null || user.getLogins().isEmpty()) { ((HttpServletResponse) arg1).setStatus(302); - + String redirectUrl = ((HttpServletRequest) arg0).getHeader("referer"); redirectUrl = redirectUrl + "#!/login"; ((HttpServletResponse) arg1).setHeader("redirect", redirectUrl); ((HttpServletResponse) arg1).sendError(302, "Need to redirect to " + redirectUrl); return; } - - // have the user redirect value - // need to make sure no one did any funny business and doesn't have an actual user object - else { - User user = (User) session.getAttribute(Constants.SESSION_USER); - if(user == null || user.getLogins().isEmpty()) { - ((HttpServletResponse) arg1).setStatus(302); - - String redirectUrl = ((HttpServletRequest) arg0).getHeader("referer"); - redirectUrl = redirectUrl + "#!/login"; - ((HttpServletResponse) arg1).setHeader("redirect", redirectUrl); - ((HttpServletResponse) arg1).sendError(302, "Need to redirect to " + redirectUrl); - return; - } - } } - } finally { - wrapper.cleanUp(); } } - + arg2.doFilter(arg0, arg1); } - + @Override public void destroy() { // TODO Auto-generated method stub - + } @Override public void init(FilterConfig arg0) throws ServletException { // TODO Auto-generated method stub - + } - + /** * Due to how the FE security is set up * Need to ignore some URLs :( diff --git a/src/prerna/web/conf/UserRestrictionFilter.java b/src/prerna/web/conf/UserRestrictionFilter.java deleted file mode 100644 index f2f2e62cd..000000000 --- a/src/prerna/web/conf/UserRestrictionFilter.java +++ /dev/null @@ -1,64 +0,0 @@ -package prerna.web.conf; - -import java.io.IOException; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; - -import prerna.auth.AccessToken; -import prerna.auth.User; -import prerna.auth.utils.SecurityQueryUtils; -import prerna.util.Constants; - -public class UserRestrictionFilter implements Filter { - - @Override - public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { - HttpSession session = ((HttpServletRequest)arg0).getSession(false); - - if(session == null) { - //TODO: need to redirect! - return; - } - - Object user = session.getAttribute(Constants.SESSION_USER); - if(user == null) { - //TODO: need to redirect! - return; - } - - User semossUser = (User) user; - if(!semossUser.isLoggedIn()) { - //TODO: need to redirect! - return; - } - - AccessToken token = semossUser.getAccessToken(semossUser.getLogins().get(0)); - String userId = token.getId(); - if(!SecurityQueryUtils.userExists(userId)) { - //TODO: need to redirect! - return; - } - - arg2.doFilter(arg0, arg1); - } - - @Override - public void destroy() { - // TODO Auto-generated method stub - - } - - @Override - public void init(FilterConfig arg0) throws ServletException { - // TODO Auto-generated method stub - - } - -} From a37cd9dae12aab624c01a2f673693cea0adba8a5 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 19 Sep 2018 17:04:54 +0000 Subject: [PATCH 0237/1906] UPDATE ::: simplifying the no user in session class git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30140 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: b4f59ed86c2ed289f65172558f2fe8608145e27b --- src/prerna/web/conf/CACFilter.java | 1 - .../web/conf/NoUserInSessionFilter.java | 21 ++----------------- 2 files changed, 2 insertions(+), 20 deletions(-) diff --git a/src/prerna/web/conf/CACFilter.java b/src/prerna/web/conf/CACFilter.java index ad5ba53a7..3943687c2 100644 --- a/src/prerna/web/conf/CACFilter.java +++ b/src/prerna/web/conf/CACFilter.java @@ -105,7 +105,6 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 e.printStackTrace(); } - break CERT_LOOP; } else { continue; diff --git a/src/prerna/web/conf/NoUserInSessionFilter.java b/src/prerna/web/conf/NoUserInSessionFilter.java index fd80dd6a6..815d35ec9 100644 --- a/src/prerna/web/conf/NoUserInSessionFilter.java +++ b/src/prerna/web/conf/NoUserInSessionFilter.java @@ -51,10 +51,8 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 // since security is embedded w/ normal semoss and not standalone HttpSession session = ((HttpServletRequest) arg0).getSession(true); - // users are registered but dont know who this specific user is - // take them to the login page - if(session.getAttribute("user") == null) { - session.setAttribute("user", true); + User user = (User) session.getAttribute(Constants.SESSION_USER); + if(user == null || user.getLogins().isEmpty()) { ((HttpServletResponse) arg1).setStatus(302); String redirectUrl = ((HttpServletRequest) arg0).getHeader("referer"); @@ -63,21 +61,6 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 ((HttpServletResponse) arg1).sendError(302, "Need to redirect to " + redirectUrl); return; } - - // have the user redirect value - // need to make sure no one did any funny business and doesn't have an actual user object - else { - User user = (User) session.getAttribute(Constants.SESSION_USER); - if(user == null || user.getLogins().isEmpty()) { - ((HttpServletResponse) arg1).setStatus(302); - - String redirectUrl = ((HttpServletRequest) arg0).getHeader("referer"); - redirectUrl = redirectUrl + "#!/login"; - ((HttpServletResponse) arg1).setHeader("redirect", redirectUrl); - ((HttpServletResponse) arg1).sendError(302, "Need to redirect to " + redirectUrl); - return; - } - } } } From 675cbf46d46c37af340f2c8c0ae70a5ff4c6eb33 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 19 Sep 2018 19:22:51 +0000 Subject: [PATCH 0238/1906] UPDATE ::: Setting logic in web.xml to be able to toggle if CACFilter should auto-add the user that is coming in into the user table git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30142 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 4728fba5af49520330a68c1ee2bda997d4e4fb65 --- WebContent/WEB-INF/web.xml | 6 +++++- src/prerna/web/conf/CACFilter.java | 27 ++++++++++++++++++++++++--- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index 8ab223ed7..23f4e817e 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -1,6 +1,6 @@ - Monolith + Monolith_Dev index.html @@ -17,6 +17,10 @@ CACFilter prerna.web.conf.CACFilter + + autoAdd + true + CACFilter diff --git a/src/prerna/web/conf/CACFilter.java b/src/prerna/web/conf/CACFilter.java index 3943687c2..f501c82f2 100644 --- a/src/prerna/web/conf/CACFilter.java +++ b/src/prerna/web/conf/CACFilter.java @@ -3,6 +3,7 @@ import java.io.IOException; import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; +import java.util.Enumeration; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -13,6 +14,7 @@ import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; +import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; @@ -31,9 +33,15 @@ public class CACFilter implements Filter { private static final Logger LOGGER = LogManager.getLogger(CACFilter.class.getName()); + private static final String AUTO_ADD = "autoAdd"; + private static Boolean autoAdd = null; + private FilterConfig filterConfig; + @Override public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { + setInitParams(arg0); + X509Certificate[] certs = (X509Certificate[]) arg0.getAttribute("javax.servlet.request.X509Certificate"); HttpSession session = ((HttpServletRequest)arg0).getSession(true); @@ -126,7 +134,9 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 session.setAttribute(Constants.SESSION_USER, user); // add the user if they do not exist - SecurityUpdateUtils.addOAuthUser(token); + if(CACFilter.autoAdd) { + SecurityUpdateUtils.addOAuthUser(token); + } } } } @@ -142,8 +152,19 @@ public void destroy() { @Override public void init(FilterConfig arg0) throws ServletException { - // TODO Auto-generated method stub - + this.filterConfig = arg0; + } + + private void setInitParams(ServletRequest arg0) { + if(CACFilter.autoAdd == null) { + String autoAddStr = this.filterConfig.getInitParameter(AUTO_ADD); + if(autoAddStr != null) { + CACFilter.autoAdd = Boolean.parseBoolean(autoAddStr); + } else { + // Default value is true + CACFilter.autoAdd = true; + } + } } } From 0c09205cd2706eb2df26ff63e21b5d0bcc58c1a0 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 19 Sep 2018 19:47:24 +0000 Subject: [PATCH 0239/1906] UPDATE ::: Code clean up around user filtering UPDATE ::: Adding filter to be enabled that will inhibit any new user from getting access to enter the app git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30143 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: ae8ab85ca0f2d1225a46ffb3a6231455187bb29c --- WebContent/WEB-INF/web.xml | 13 ++- src/prerna/web/conf/NoUserExistsFilter.java | 7 +- .../web/conf/NoUserInSessionFilter.java | 11 +-- src/prerna/web/conf/UserExistsFilter.java | 89 +++++++++++++++++++ 4 files changed, 111 insertions(+), 9 deletions(-) create mode 100644 src/prerna/web/conf/UserExistsFilter.java diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index 23f4e817e..c8eb6a579 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -19,7 +19,7 @@ prerna.web.conf.CACFilter autoAdd - true + false @@ -43,6 +43,17 @@ AdminStartupFilter /adminconfig/* + + From 7bb1c4dff40d39c563bf86db6372939c44e5171a Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 21 Sep 2018 20:19:35 +0000 Subject: [PATCH 0242/1906] UPDATE ::: Making fields protected to be extended in other projects git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30163 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 20c01e86a8c193281c40b04f8d8b93ae79e23e68 --- src/prerna/semoss/web/services/NameServer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prerna/semoss/web/services/NameServer.java b/src/prerna/semoss/web/services/NameServer.java index e1be26344..5ed29904f 100644 --- a/src/prerna/semoss/web/services/NameServer.java +++ b/src/prerna/semoss/web/services/NameServer.java @@ -105,7 +105,7 @@ public class NameServer { @Context - private ServletContext context; + protected ServletContext context; @GET @Path("/sessionTimeout") From 561dde9ffd97694003ab672e0f44e53318215c0c Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 25 Sep 2018 20:10:32 +0000 Subject: [PATCH 0243/1906] UPDATE ::: Forgot to commit update for making variable protected to extend in innowake git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30190 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 56df0da1ea7e811296f8e25f46b872b4b7cdb47e --- src/prerna/semoss/web/services/AppResource.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/prerna/semoss/web/services/AppResource.java b/src/prerna/semoss/web/services/AppResource.java index 1a053f928..f926f156b 100644 --- a/src/prerna/semoss/web/services/AppResource.java +++ b/src/prerna/semoss/web/services/AppResource.java @@ -37,7 +37,7 @@ @Path("/app-{appName}") public class AppResource { - private static final String DIR_SEPARATOR = java.nio.file.FileSystems.getDefault().getSeparator(); + protected static final String DIR_SEPARATOR = java.nio.file.FileSystems.getDefault().getSeparator(); @GET @Path("/appImage/download") @@ -59,7 +59,7 @@ public Response downloadAppImage(@Context HttpServletRequest request, @PathParam * @param app * @return */ - private File getAppImageFile(String app) { + protected File getAppImageFile(String app) { String appId = MasterDatabaseUtility.testEngineIdIfAlias(app); String propFileLoc = DIHelper.getInstance().getProperty(appId + "_" + Constants.STORE); if(propFileLoc == null && !app.equals("NEWSEMOSSAPP")) { @@ -199,7 +199,7 @@ private File findImageFile(String baseDir) { * Close a file stream * @param fis */ - private void closeStream(FileInputStream fis) { + protected void closeStream(FileInputStream fis) { if(fis != null) { try { fis.close(); From 8a24399163f413b4b5fe1f9dc93014ab50207177 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 26 Sep 2018 13:25:57 +0000 Subject: [PATCH 0244/1906] UPDATE ::: Defining specific image tags so it works on firefox git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30202 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: db181ff9cba966dd37f1755877e352df9f6f28e0 --- src/prerna/semoss/web/services/NameServer.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/prerna/semoss/web/services/NameServer.java b/src/prerna/semoss/web/services/NameServer.java index 5ed29904f..18cc10e7b 100644 --- a/src/prerna/semoss/web/services/NameServer.java +++ b/src/prerna/semoss/web/services/NameServer.java @@ -288,7 +288,7 @@ public Response downloadFile(@QueryParam("insightId") String insightId, @QueryPa @GET @Path("/appImage") - @Produces("image/*") + @Produces({"image/jpeg", "image/png"}) public Response getAppImage(@Context HttpServletRequest request, @QueryParam("app") String app) { AppResource r = new AppResource(); return r.downloadAppImage(request, app); @@ -296,7 +296,7 @@ public Response getAppImage(@Context HttpServletRequest request, @QueryParam("ap @GET @Path("/insightImage") - @Produces("image/*") + @Produces({"image/jpeg", "image/png"}) public Response getInsightImage(@Context HttpServletRequest request, @QueryParam("app") String app, @QueryParam("rdbmsId") String insightId, @QueryParam("params") String params) { AppResource r = new AppResource(); return r.downloadInsightImage(request, app, insightId, params); From b587bc6cf14c65330ff9ae24481a6e490be3dfc3 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 26 Sep 2018 21:32:30 +0000 Subject: [PATCH 0245/1906] UPDATE ::: Extending app resource doesn't work for @Path requests unless the methods override git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30209 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 6ed1f957b2b1f3d3d1ac8cfd05c0fe2c94a21721 --- src/prerna/semoss/web/services/AppResource.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prerna/semoss/web/services/AppResource.java b/src/prerna/semoss/web/services/AppResource.java index f926f156b..bc10ee490 100644 --- a/src/prerna/semoss/web/services/AppResource.java +++ b/src/prerna/semoss/web/services/AppResource.java @@ -37,7 +37,7 @@ @Path("/app-{appName}") public class AppResource { - protected static final String DIR_SEPARATOR = java.nio.file.FileSystems.getDefault().getSeparator(); + private static final String DIR_SEPARATOR = java.nio.file.FileSystems.getDefault().getSeparator(); @GET @Path("/appImage/download") From 51e8a46740a18d80db014e07d5847bb991b7b3a6 Mon Sep 17 00:00:00 2001 From: tbanach Date: Thu, 27 Sep 2018 13:41:13 +0000 Subject: [PATCH 0246/1906] UPDATE ::: pom dependency for Azure. REQUIREMENT ::: maven update git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30215 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 4a20a5aa4cb7faf4b0b2aaf162951743479b733e --- pom.xml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1d52a1cbd..3f96eb948 100644 --- a/pom.xml +++ b/pom.xml @@ -2864,6 +2864,17 @@ * - + + + com.microsoft.azure + azure-storage + 8.0.0 + + + * + * + + + \ No newline at end of file From e3c332aa2fbca6fe9c1ba190b48fc2db55ef2223 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 27 Sep 2018 16:35:25 +0000 Subject: [PATCH 0247/1906] UPDATE ::: Improving upload speed of files UPDATE ::: Improving metamodelcreator to only run necessary operations based on mode UPDATE ::: Not parsing null/empty string values UPDATE ::: CSVFileHelper looping through correct number of rows for predictions of types git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30223 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: ddb8646cb2260cd9f356bd29c101ab7c0a608e08 --- src/prerna/upload/Uploader.java | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/prerna/upload/Uploader.java b/src/prerna/upload/Uploader.java index ff67e31fe..b42352ced 100644 --- a/src/prerna/upload/Uploader.java +++ b/src/prerna/upload/Uploader.java @@ -126,8 +126,11 @@ protected List processRequest(@Context HttpServletRequest request) { // maximum file size to be uploaded. upload.setSizeMax(maxFileSize); +// long start = System.currentTimeMillis(); // Parse the request to get file items fileItems = upload.parseRequest(request); +// long end = System.currentTimeMillis(); +// System.out.println("Time to create temp = " + (end - start) + "ms"); } catch (FileUploadException e) { e.printStackTrace(); } catch (Exception e) { @@ -151,7 +154,10 @@ protected Hashtable getInputData(List fileItems) // Get the uploaded file parameters String fieldName = fi.getFieldName(); String fileName = fi.getName(); - String value = fi.getString(); + // keep this null + // dont want to grab the contents of the file + // and push to a string + String value = null; if (!fi.isFormField()) { if(fileName.equals("")) { continue; @@ -164,7 +170,11 @@ protected Hashtable getInputData(List fileItems) String modifiedDate = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_SSSS").format(date); value = this.filePath + fileName.substring(fileName.lastIndexOf(DIR_SEPARATOR) + 1, fileName.lastIndexOf(".")).trim().replace(" ", "_") + "_____UNIQUE" + modifiedDate + fileName.substring(fileName.lastIndexOf(".")); file = new File(value); + +// long start = System.currentTimeMillis(); writeFile(fi, file); +// long end = System.currentTimeMillis(); +// System.out.println("Time to write file = " + (end - start) + "ms"); LOGGER.info("File item is the actual data. Saved Filename: " + fileName + " to "+ file); } } @@ -172,8 +182,10 @@ protected Hashtable getInputData(List fileItems) LOGGER.info("File item type is " + fi.getFieldName() + fi.getString()); } //need to handle multiple files getting selected for upload - if(inputData.get(fieldName) != null) - { + if(value == null) { + value = fi.getString(); + } + if(inputData.get(fieldName) != null) { value = inputData.get(fieldName) + ";" + value; } inputData.put(fieldName, value); From a1b412f79521e7ddfff95b88da3335f6caa701b0 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 1 Oct 2018 14:23:08 +0000 Subject: [PATCH 0248/1906] UPDATE ::: Increasing timeout value to 2 hrs git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30236 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 8c01b80a2f5c6a3aae40ad11faba3a278cc5bd40 --- WebContent/WEB-INF/web.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index 74015cc9c..a83ce31ae 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -171,6 +171,6 @@ prerna.web.conf.UserDBLoader - 30 + 120 \ No newline at end of file From e94be8e00a42848cd8495cd38b7427865d7e2db6 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 1 Oct 2018 16:52:01 +0000 Subject: [PATCH 0249/1906] UPDATE ::: Adding new boolean to determine if application is running locally on laptop to improve file upload performance UPDATE ::: Adding new config resource to send back options around the application - if r is enabled, security enabled, session timeout, and if local deployment git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30240 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 888f5308f3138f598d2437c324fe16f75ded3bb0 --- .../semoss/web/app/MonolithApplication.java | 2 + .../services/ServerConfigurationResource.java | 69 +++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 src/prerna/semoss/web/services/ServerConfigurationResource.java diff --git a/src/prerna/semoss/web/app/MonolithApplication.java b/src/prerna/semoss/web/app/MonolithApplication.java index afd00c790..4779aa99b 100644 --- a/src/prerna/semoss/web/app/MonolithApplication.java +++ b/src/prerna/semoss/web/app/MonolithApplication.java @@ -36,6 +36,7 @@ import prerna.semoss.web.services.AppResource; import prerna.semoss.web.services.AuthorizationResource; import prerna.semoss.web.services.NameServer; +import prerna.semoss.web.services.ServerConfigurationResource; import prerna.semoss.web.services.UserResource; public class MonolithApplication extends Application { @@ -48,6 +49,7 @@ public MonolithApplication() { singletons.add(new AppResource()); singletons.add(new AuthorizationResource()); singletons.add(new FormResource()); + singletons.add(new ServerConfigurationResource()); } @Override diff --git a/src/prerna/semoss/web/services/ServerConfigurationResource.java b/src/prerna/semoss/web/services/ServerConfigurationResource.java new file mode 100644 index 000000000..ff9748b71 --- /dev/null +++ b/src/prerna/semoss/web/services/ServerConfigurationResource.java @@ -0,0 +1,69 @@ +package prerna.semoss.web.services; + +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.Response; + +import prerna.auth.utils.AbstractSecurityUtils; +import prerna.util.Constants; +import prerna.util.DIHelper; +import prerna.web.services.util.WebUtility; + +@Path("/config") +public class ServerConfigurationResource { + + private static Map config = null; + + /** + * Generate the configuration options for this instance + * Only need to make this once + * @param request + * @return + */ + private static Map getConfig(@Context HttpServletRequest request) { + if(config == null) { + // make thread safe + synchronized(ServerConfigurationResource.class) { + if(config == null) { + config = new HashMap(); + // session timeout + config.put("timeout", (double) request.getSession().getMaxInactiveInterval() / 60); + + // r enabled + boolean useR = true; + String useRStr = DIHelper.getInstance().getProperty(Constants.USE_R); + if(useRStr != null) { + useR = Boolean.parseBoolean(useRStr); + } + config.put("r", useR); + + // security enabled + config.put("security", AbstractSecurityUtils.securityEnabled()); + + // local mode + boolean localMode = false; + String localModeStr = DIHelper.getInstance().getProperty(Constants.LOCAL_DEPLOYMENT); + if(localModeStr != null) { + localMode = Boolean.parseBoolean(localModeStr); + } + config.put("localDeployment", localMode); + } + } + } + return config; + } + + @GET + @Path("/") + @Produces("application/json") + public Response getTimeoutValue(@Context HttpServletRequest request) { + return WebUtility.getResponse(getConfig(request), 200); + } + +} From 0ac7f4280af9c7242955ca9f92f85d58d63f7221 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 1 Oct 2018 18:34:40 +0000 Subject: [PATCH 0250/1906] UPDATE ::: When no user is logged in, completely remove the user object from session UPDATE ::: Checking to make sure if user object is there that there is also a login UPDATE ::: Printing out error in job thread when a pixel error occurs git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30241 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 50e819de86edd13dd418786d4c7f66673496d2f0 --- src/prerna/semoss/web/services/UserResource.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/prerna/semoss/web/services/UserResource.java b/src/prerna/semoss/web/services/UserResource.java index 8c695f48a..7840efcf4 100644 --- a/src/prerna/semoss/web/services/UserResource.java +++ b/src/prerna/semoss/web/services/UserResource.java @@ -265,7 +265,11 @@ public Response logout(@PathParam("provider") String provider, @Context HttpServ } else { User thisUser = (User) request.getSession().getAttribute(Constants.SESSION_USER); removed = thisUser.dropAccessToken(provider.toUpperCase()); - request.getSession().setAttribute(Constants.SESSION_USER, thisUser); + if(thisUser.getLogins().isEmpty()) { + request.getSession().removeAttribute(Constants.SESSION_USER); + } else { + request.getSession().setAttribute(Constants.SESSION_USER, thisUser); + } } Map ret = new Hashtable(); From 28ff43dd086b4cf876a3b3e3fc179c1623b07ccb Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 1 Oct 2018 19:46:53 +0000 Subject: [PATCH 0251/1906] UPDATE ::: Allowing config to pass even without user in session git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30243 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 3811302017e8163eeb9b0a6ab28100a6721595f9 --- src/prerna/web/conf/NoUserInSessionFilter.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/prerna/web/conf/NoUserInSessionFilter.java b/src/prerna/web/conf/NoUserInSessionFilter.java index f0cf91954..9b6425d49 100644 --- a/src/prerna/web/conf/NoUserInSessionFilter.java +++ b/src/prerna/web/conf/NoUserInSessionFilter.java @@ -23,6 +23,7 @@ public class NoUserInSessionFilter implements Filter { protected static List ignoreDueToFE = new Vector(); static { + ignoreDueToFE.add("config"); ignoreDueToFE.add("authorization/securityEnabled"); ignoreDueToFE.add("auth/isUserRegistrationOn"); ignoreDueToFE.add("auth/logins"); From 1822f51a3e71d5fc3679bb1a456948ed15e2180c Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 2 Oct 2018 16:51:03 +0000 Subject: [PATCH 0252/1906] UPDATE ::: Having social properties be consistent UPDATE ::: Adding rest endpoint to get all social properties data grouped by provider UPDATE ::: Starting to add rest endpoint to modify social properties as admin or when no security UPDATE ::: Cleaning basic logs when starting R / querying frame REQUIREMENT ::: Please update your social.properties -> onedrive_login to ms_login, git_* to github_*, reg_allowed to native_registration REQUIREMENT ::: Requires FE update as well as endpoints have changed git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30258 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: d09f8c07026b41d187e666adaf724fb6da115b9a --- .../semoss/web/services/UserResource.java | 131 ++++++++++++------ 1 file changed, 91 insertions(+), 40 deletions(-) diff --git a/src/prerna/semoss/web/services/UserResource.java b/src/prerna/semoss/web/services/UserResource.java index 7840efcf4..8175a8752 100644 --- a/src/prerna/semoss/web/services/UserResource.java +++ b/src/prerna/semoss/web/services/UserResource.java @@ -39,6 +39,8 @@ import java.util.List; import java.util.Map; import java.util.Properties; +import java.util.Set; +import java.util.TreeMap; import java.util.UUID; import javax.servlet.http.HttpServletRequest; @@ -61,6 +63,7 @@ import prerna.auth.AppTokens; import prerna.auth.AuthProvider; import prerna.auth.User; +import prerna.auth.utils.AbstractSecurityUtils; import prerna.auth.utils.NativeUserSecurityUtils; import prerna.auth.utils.SecurityQueryUtils; import prerna.auth.utils.SecurityUpdateUtils; @@ -430,7 +433,7 @@ public Response userinfoDropbox(@Context HttpServletRequest request) { */ @GET @Produces("application/json") - @Path("/userinfo/git") + @Path("/userinfo/github") public Response userinfoGithub(@Context HttpServletRequest request) { Map ret = new Hashtable(); User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); @@ -444,7 +447,7 @@ public Response userinfoGithub(@Context HttpServletRequest request) { ret.put("ERROR", "Log into your Github account"); return WebUtility.getResponse(ret, 200); } else { - AccessToken gitToken = user.getAccessToken(AuthProvider.GIT); + AccessToken gitToken = user.getAccessToken(AuthProvider.GITHUB); accessString=gitToken.getAccess_token(); } } catch (Exception e) { @@ -485,7 +488,7 @@ public Response loginSF(@Context HttpServletRequest request, @Context HttpServle String queryString = request.getQueryString(); if(queryString != null && queryString.contains("code=")) { - if(userObj == null || userObj.getAccessToken(AuthProvider.SALESFORCE) == null) { + if(userObj == null || userObj.getAccessToken(AuthProvider.SF) == null) { String[] outputs = AbstractHttpHelper.getCodes(queryString); String prefix = "sf_"; @@ -505,7 +508,7 @@ public Response loginSF(@Context HttpServletRequest request, @Context HttpServle String url = "https://login.salesforce.com/services/oauth2/token"; AccessToken accessToken = AbstractHttpHelper.getAccessToken(url, params, true, true); - accessToken.setProvider(AuthProvider.SALESFORCE); + accessToken.setProvider(AuthProvider.SF); addAccessToken(accessToken, request); System.out.println("Access Token is.. " + accessToken.getAccess_token()); @@ -517,12 +520,12 @@ public Response loginSF(@Context HttpServletRequest request, @Context HttpServle return WebUtility.getResponse(ret, 200); } } - else if(userObj == null || userObj.getAccessToken(AuthProvider.SALESFORCE) == null) { + else if(userObj == null || userObj.getAccessToken(AuthProvider.SF) == null) { // not authenticated response.setStatus(302); response.sendRedirect(getSFRedirect(request)); } - else if(userObj != null && userObj.getAccessToken(AuthProvider.SALESFORCE) != null) { + else if(userObj != null && userObj.getAccessToken(AuthProvider.SF) != null) { ret.put("success", true); return WebUtility.getResponse(ret, 200); } @@ -551,8 +554,8 @@ private String getSFRedirect(HttpServletRequest request) throws UnsupportedEncod */ @GET @Produces("application/json") - @Path("/login/git") - public Response loginGit(@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException { + @Path("/login/github") + public Response loginGithub(@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException { /* * Try to log in the user * If they are not logged in @@ -564,10 +567,10 @@ public Response loginGit(@Context HttpServletRequest request, @Context HttpServl String queryString = request.getQueryString(); if(queryString != null && queryString.contains("code=")) { - if(userObj == null || userObj.getAccessToken(AuthProvider.GIT) == null) { + if(userObj == null || userObj.getAccessToken(AuthProvider.GITHUB) == null) { String [] outputs = AbstractHttpHelper.getCodes(queryString); - String prefix = "git_"; + String prefix = "github_"; String clientId = socialData.getProperty(prefix+"client_id"); String clientSecret = socialData.getProperty(prefix+"secret_key"); String redirectUri = socialData.getProperty(prefix+"redirect_uri"); @@ -590,7 +593,7 @@ public Response loginGit(@Context HttpServletRequest request, @Context HttpServl response.sendRedirect(getGoogleRedirect(request)); return null; } - accessToken.setProvider(AuthProvider.GIT); + accessToken.setProvider(AuthProvider.GITHUB); // add specific Git values GHMyself myGit = GitHub.connectUsingOAuth(accessToken.getAccess_token()).getMyself(); @@ -610,13 +613,13 @@ public Response loginGit(@Context HttpServletRequest request, @Context HttpServl return WebUtility.getResponse(ret, 200); } } - else if(userObj == null || userObj.getAccessToken(AuthProvider.GIT) == null) { + else if(userObj == null || userObj.getAccessToken(AuthProvider.GITHUB) == null) { // not authenticated response.setStatus(302); response.sendRedirect(getGitRedirect(request)); } // else if user object is there and git is there - else if(userObj != null && userObj.getAccessToken(AuthProvider.GIT) != null) + else if(userObj != null && userObj.getAccessToken(AuthProvider.GITHUB) != null) { ret.put("success", true); return WebUtility.getResponse(ret, 200); @@ -1163,7 +1166,7 @@ public Response loginTwitter(@Context HttpServletRequest request, @Context HttpS if(queryString != null && queryString.contains("code=")) { - if(userObj == null || ((User)userObj).getAccessToken(AuthProvider.GIT) == null) + if(userObj == null || ((User)userObj).getAccessToken(AuthProvider.GITHUB) == null) { String [] outputs = AbstractHttpHelper.getCodes(queryString); @@ -1186,7 +1189,7 @@ public Response loginTwitter(@Context HttpServletRequest request, @Context HttpS String url = "https://github.com/login/oauth/access_token"; AccessToken accessToken = AbstractHttpHelper.getAccessToken(url, params, false, true); - accessToken.setProvider(AuthProvider.GIT); + accessToken.setProvider(AuthProvider.GITHUB); addAccessToken(accessToken, request); System.out.println("Access Token is.. " + accessToken.getAccess_token()); @@ -1204,7 +1207,7 @@ public Response loginTwitter(@Context HttpServletRequest request, @Context HttpS } } - else if(userObj == null || ((User)userObj).getAccessToken(AuthProvider.GIT) == null) + else if(userObj == null || ((User)userObj).getAccessToken(AuthProvider.GITHUB) == null) { // not authenticated @@ -1383,18 +1386,77 @@ public Response createUser(@Context HttpServletRequest request) { } } + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + + /* + * Setting / Getting Information from the social properties + * That is needed by the FE + */ + @GET @Produces("application/json") - @Path("/isUserRegistrationOn/") - public Response isUserRegistrationOn(@Context HttpServletRequest request) throws IOException { - boolean reg_allowed = Boolean.parseBoolean(socialData.getProperty("reg_allowed")); - return WebUtility.getResponse(reg_allowed, 200); + @Path("/loginsAllowed/") + public Response loginsAllowed(@Context HttpServletRequest request) throws IOException { + boolean nativeLogin = Boolean.parseBoolean(socialData.getProperty("native_login")); + boolean githubLogin = Boolean.parseBoolean(socialData.getProperty("github_login")); + boolean googleLogin = Boolean.parseBoolean(socialData.getProperty("google_login")); + boolean onedriveLogin = Boolean.parseBoolean(socialData.getProperty("ms_login")); + boolean dropboxLogin = Boolean.parseBoolean(socialData.getProperty("dropbox_login")); + boolean cacLogin = Boolean.parseBoolean(socialData.getProperty("cac_login")); + boolean registration = Boolean.parseBoolean(socialData.getProperty("native_registration")); + Map logins = new HashMap<>(); + logins.put("native", nativeLogin); + logins.put("google", googleLogin); + logins.put("github", githubLogin); + logins.put("ms", onedriveLogin); + logins.put("dropbox", dropboxLogin); + logins.put("cac", cacLogin); + logins.put("registration", registration); + return WebUtility.getResponse(logins, 200); + } + + @GET + @Produces("application/json") + @Path("/loginProperties/") + public Response loginProperties(@Context HttpServletRequest request) throws IOException { + if(AbstractSecurityUtils.securityEnabled()) { + User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); + if(user == null) { + return WebUtility.getResponse("No user defined to access properties. Please login as an admin", 400); + } + if(SecurityQueryUtils.userIsAdmin(user)){ + return WebUtility.getResponse("User is not an admin and does not have access. Please login as an admin", 400); + } + } + + // you have access - lets send all the info + + Map> loginApps = new TreeMap>(); + + Set propSet = socialData.stringPropertyNames(); + for(String prop : propSet) { + String[] split = prop.toString().split("_", 2); + String type = split[0]; + String type_key = split[1]; + + if(!loginApps.containsKey(type)) { + loginApps.put(type, new TreeMap()); + } + + loginApps.get(type).put(type_key, socialData.getProperty(prop).toString()); + } + + return WebUtility.getResponse(loginApps, 200); } @POST @Produces("application/json") - @Path("/setUserRegistration/") - public Response setUserRegistration(@Context HttpServletRequest request) throws IOException { + @Path("/modifyLoginProperties/{provider}") + public Response modifyLoginProperties(@Context HttpServletRequest request) throws IOException { OutputStream output = null; Hashtable errorRet = new Hashtable(); try { @@ -1402,8 +1464,8 @@ public Response setUserRegistration(@Context HttpServletRequest request) throws if(SecurityQueryUtils.userIsAdmin(user)){ String user_reg = request.getParameter("user_reg"); PropertiesConfiguration config = new PropertiesConfiguration(DIHelper.getInstance().getProperty("SOCIAL")); - socialData.setProperty("reg_allowed", user_reg); - config.setProperty("reg_allowed", user_reg); + socialData.setProperty("native_registration", user_reg); + config.setProperty("native_registration", user_reg); config.save(); } else { errorRet.put("error", "User is not allowed to perform this action."); @@ -1423,22 +1485,11 @@ public Response setUserRegistration(@Context HttpServletRequest request) throws @GET @Produces("application/json") - @Path("/loginProperties/") - public Response loginProperties(@Context HttpServletRequest request) throws IOException { - boolean nativeLogin = Boolean.parseBoolean(socialData.getProperty("native_login")); - boolean githubLogin = Boolean.parseBoolean(socialData.getProperty("github_login")); - boolean googleLogin = Boolean.parseBoolean(socialData.getProperty("google_login")); - boolean onedriveLogin = Boolean.parseBoolean(socialData.getProperty("onedrive_login")); - boolean dropboxLogin = Boolean.parseBoolean(socialData.getProperty("dropbox_login")); - boolean cacLogin = Boolean.parseBoolean(socialData.getProperty("cac_login")); - Map logins = new HashMap<>(); - logins.put("native", nativeLogin); - logins.put("google", googleLogin); - logins.put("github", githubLogin); - logins.put("onedrive", onedriveLogin); - logins.put("dropbox", dropboxLogin); - logins.put("cac", cacLogin); - return WebUtility.getResponse(logins, 200); + @Path("/isUserRegistrationOn/") + @Deprecated + public Response isUserRegistrationOn(@Context HttpServletRequest request) throws IOException { + boolean registration = Boolean.parseBoolean(socialData.getProperty("native_registration")); + return WebUtility.getResponse(registration, 200); } } From 0044d19fd37036ab86cd11f054987cfe11123d32 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 2 Oct 2018 17:14:56 +0000 Subject: [PATCH 0253/1906] UPDATE ::: Modifying to allow loginsAllowed instead of old rest endpoint git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30259 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: f8da746556c28e9b85e0487bf56ccfd7514b3acc --- src/prerna/web/conf/NoUserInSessionFilter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prerna/web/conf/NoUserInSessionFilter.java b/src/prerna/web/conf/NoUserInSessionFilter.java index 9b6425d49..c8a2a0d6a 100644 --- a/src/prerna/web/conf/NoUserInSessionFilter.java +++ b/src/prerna/web/conf/NoUserInSessionFilter.java @@ -27,7 +27,7 @@ public class NoUserInSessionFilter implements Filter { ignoreDueToFE.add("authorization/securityEnabled"); ignoreDueToFE.add("auth/isUserRegistrationOn"); ignoreDueToFE.add("auth/logins"); - ignoreDueToFE.add("auth/loginProperties"); + ignoreDueToFE.add("auth/loginsAllowed"); ignoreDueToFE.add("auth/login"); ignoreDueToFE.add("auth/createUser"); for(AuthProvider v : AuthProvider.values()) { From b56d596082dc5e35233c0744c088c3e3a7888236 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 2 Oct 2018 17:22:09 +0000 Subject: [PATCH 0254/1906] UPDATE ::: Adding method to update the social properties BUGFIX ::: Fixing prefix to github instead of git git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30260 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 4791d32892dbd7c502ba8c7ee4e05ad429859f2a --- .../semoss/web/services/UserResource.java | 60 ++++++++++++------- 1 file changed, 39 insertions(+), 21 deletions(-) diff --git a/src/prerna/semoss/web/services/UserResource.java b/src/prerna/semoss/web/services/UserResource.java index 8175a8752..bf5fc7be4 100644 --- a/src/prerna/semoss/web/services/UserResource.java +++ b/src/prerna/semoss/web/services/UserResource.java @@ -31,7 +31,6 @@ import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; -import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.HashMap; @@ -52,12 +51,17 @@ import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.Context; +import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; +import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.PropertiesConfiguration; import org.kohsuke.github.GHMyself; import org.kohsuke.github.GitHub; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; + import jodd.util.URLDecoder; import prerna.auth.AccessToken; import prerna.auth.AppTokens; @@ -628,7 +632,7 @@ else if(userObj != null && userObj.getAccessToken(AuthProvider.GITHUB) != null) } private String getGitRedirect(HttpServletRequest request) throws UnsupportedEncodingException { - String prefix = "git_"; + String prefix = "github_"; String clientId = socialData.getProperty(prefix+"client_id"); String redirectUri = socialData.getProperty(prefix+"redirect_uri"); String scope = socialData.getProperty(prefix+"scope"); @@ -1456,30 +1460,44 @@ public Response loginProperties(@Context HttpServletRequest request) throws IOEx @POST @Produces("application/json") @Path("/modifyLoginProperties/{provider}") - public Response modifyLoginProperties(@Context HttpServletRequest request) throws IOException { - OutputStream output = null; - Hashtable errorRet = new Hashtable(); - try { + public synchronized Response modifyLoginProperties(@PathParam("provider") String provider, MultivaluedMap form, @Context HttpServletRequest request) throws IOException { + if(AbstractSecurityUtils.securityEnabled()) { User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); + if(user == null) { + return WebUtility.getResponse("No user defined to access properties. Please login as an admin", 400); + } if(SecurityQueryUtils.userIsAdmin(user)){ - String user_reg = request.getParameter("user_reg"); - PropertiesConfiguration config = new PropertiesConfiguration(DIHelper.getInstance().getProperty("SOCIAL")); - socialData.setProperty("native_registration", user_reg); - config.setProperty("native_registration", user_reg); - config.save(); - } else { - errorRet.put("error", "User is not allowed to perform this action."); - return WebUtility.getResponse(errorRet, 500); + return WebUtility.getResponse("User is not an admin and does not have access. Please login as an admin", 400); } - } catch (Exception e) { - e.printStackTrace(); - errorRet.put("error", "An unexpected error happened. Please try again."); + } + + Gson gson = new Gson(); + String modStr = form.getFirst("modifications"); + Map mods = gson.fromJson(modStr, new TypeToken>() {}.getType()); + + PropertiesConfiguration config = null; + try { + config = new PropertiesConfiguration(DIHelper.getInstance().getProperty("SOCIAL")); + } catch (ConfigurationException e1) { + e1.printStackTrace(); + Hashtable errorRet = new Hashtable(); + errorRet.put("error", "An unexpected error happened trying to access the properties. Please try again or reach out to server admin."); return WebUtility.getResponse(errorRet, 500); - } finally { - if (output != null) { - output.close(); - } } + + for(String mod : mods.keySet()) { + config.setProperty(provider + "_" + mod, mods.get(mod)); + } + + try { + config.save(); + } catch (ConfigurationException e1) { + e1.printStackTrace(); + Hashtable errorRet = new Hashtable(); + errorRet.put("error", "An unexpected error happened when saving the new login properties. Please try again or reach out to server admin."); + return WebUtility.getResponse(errorRet, 500); + } + return WebUtility.getResponse(true, 200); } From f02125bb1acd44f7462524477f4eb333203e6a65 Mon Sep 17 00:00:00 2001 From: tbanach Date: Tue, 2 Oct 2018 17:47:56 +0000 Subject: [PATCH 0255/1906] UPDATE ::: Service for REST wrappers git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30265 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 49fe3a9b66fb8fa5fb1c99196e1e3cc8aa087125 --- .../cluster/RawSelectWrapperService.java | 414 ++++++++++++++++++ .../semoss/web/app/MonolithApplication.java | 2 + src/prerna/web/conf/UserDBLoader.java | 4 +- 3 files changed, 418 insertions(+), 2 deletions(-) create mode 100644 src/prerna/cluster/RawSelectWrapperService.java diff --git a/src/prerna/cluster/RawSelectWrapperService.java b/src/prerna/cluster/RawSelectWrapperService.java new file mode 100644 index 000000000..151050526 --- /dev/null +++ b/src/prerna/cluster/RawSelectWrapperService.java @@ -0,0 +1,414 @@ +package prerna.cluster; + +import java.util.Hashtable; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.Response; + +import prerna.algorithm.api.SemossDataType; +import prerna.engine.api.IEngine; +import prerna.engine.api.IHeadersDataRow; +import prerna.engine.api.IRawSelectWrapper; +import prerna.rdf.engine.wrappers.WrapperManager; +import prerna.util.Utility; +import prerna.web.services.util.WebUtility; + +@Path("/cluster") +public class RawSelectWrapperService implements IRawSelectWrapper { + + public static final String APP_ID = "appId"; + public static final String WRAPPER_ID = "wrapperId"; + public static final String QUERY = "query"; + + ////////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////// Code for managing active wrappers ///////////////////////// + + /** + * Make this a concurrent hash map, since it can be accessed concurrently by incoming requests. + */ + private Map activeWrappers = new ConcurrentHashMap<>(); + + /** + * Gets the wrapper when the query is not applicable. + * + * @param appId + * @param wrapperId + * @return + */ + private IRawSelectWrapper getRawSelectWrapper(String appId, String wrapperId) { + return getRawSelectWrapper(appId, wrapperId, null); + } + + /** + * If the wrapper has already been activated, then return the existing + * wrapper. Else create it and add it to the active wrappers map. + * + * @param appId + * @param wrapperId + * @param query + * @return + */ + private IRawSelectWrapper getRawSelectWrapper(String appId, String wrapperId, String query) { + String wrapperKey = wrapperId + "@" + appId; + if (activeWrappers.containsKey(wrapperKey)) { + return activeWrappers.get(wrapperKey); + } else { + IEngine engine = getEngine(appId); + IRawSelectWrapper wrapper = WrapperManager.getInstance().getRawWrapper(engine, query); + activeWrappers.put(wrapperKey, wrapper); + return wrapper; + } + } + + /** + * Removes the wrapper and returns true if it was actually removed, false if + * it was not present. + * + * @param appId + * @param wrapperId + * @return + */ + private boolean removeRawSelectWrapper(String appId, String wrapperId) { + String wrapperKey = wrapperId + "@" + appId; + if (activeWrappers.containsKey(wrapperKey)) { + activeWrappers.remove(wrapperKey); + return true; + } else { + return false; + } + } + + ////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////// Util methods ///////////////////////////////////////// + + private IEngine getEngine(String appId) { + IEngine engine = null; + if (appId.endsWith("_InsightsRDBMS")) { + String parentAppId = appId.replace("_InsightsRDBMS", ""); + IEngine parentEngine = Utility.getEngine(parentAppId); + engine = parentEngine.getInsightDatabase(); + } else { + engine = Utility.getEngine(appId); + } + return engine; + } + + @POST + @Produces("application/json") + @Path("/alive") + public Response alive(@Context HttpServletRequest request) { + return WebUtility.getResponse(true, 200); + } + + ////////////////////////////////////////////////////////////////////////////////////////// + ///////////////////////// Code for mirroring wrapper functionality /////////////////////// + + @Override + public void execute() { + throw new IllegalStateException("Only overriding this method for reference."); + } + + /** + * Execute requires appId, wrapperId, and query + * @param request + * @return + */ + @POST + @Produces("application/json") + @Path("/execute") + public Response execute(@Context HttpServletRequest request) { + + // Grab parameters + String appId = request.getParameter(APP_ID); + String wrapperId = request.getParameter(WRAPPER_ID); + String query = request.getParameter(QUERY); + + // Perform action + IRawSelectWrapper wrapper = getRawSelectWrapper(appId, wrapperId, query); + wrapper.execute(); + Hashtable ret = new Hashtable(); + + // Set return values + ret.put("success", true); + ret.put("appId", appId); + ret.put("wrapperId", wrapperId); + ret.put("query", query); + ret.put("action", "execute"); + return WebUtility.getResponse(ret, 200); + } + + @Override + public void setQuery(String query) { + throw new IllegalStateException("Only overriding this method for reference."); + } + + /** + * Set query requires appId, wrapperId, and query + * @param request + * @return + */ + @POST + @Produces("application/json") + @Path("/setQuery") + public Response setQuery(@Context HttpServletRequest request) { + + // Grab parameters + String appId = request.getParameter(APP_ID); + String wrapperId = request.getParameter(WRAPPER_ID); + String query = request.getParameter(QUERY); + + // Perform action + IRawSelectWrapper wrapper = getRawSelectWrapper(appId, wrapperId, query); + wrapper.setQuery(query); + + // Set return values + Hashtable ret = new Hashtable(); + ret.put("success", true); + ret.put("appId", appId); + ret.put("wrapperId", wrapperId); + ret.put("query", query); + ret.put("action", "setQuery"); + return WebUtility.getResponse(ret, 200); + } + + @Override + public void cleanUp() { + throw new IllegalStateException("Only overriding this method for reference."); + } + + /** + * Clean up requires appId and wrapperId + * @param request + * @return + */ + @POST + @Produces("application/json") + @Path("/cleanUp") + public Response cleanUp(@Context HttpServletRequest request) { + + // Grab parameters + String appId = request.getParameter(APP_ID); + String wrapperId = request.getParameter(WRAPPER_ID); + + // Perform action + IRawSelectWrapper wrapper = getRawSelectWrapper(appId, wrapperId); + wrapper.cleanUp(); + boolean removed = removeRawSelectWrapper(appId, wrapperId); // Also remove from active list + + // Set return values + Hashtable ret = new Hashtable(); + ret.put("success", true); + ret.put("appId", appId); + ret.put("wrapperId", wrapperId); + ret.put("action", "cleanUp"); + ret.put("removed", removed); + return WebUtility.getResponse(ret, 200); + } + + @Override + public void setEngine(IEngine engine) { + throw new IllegalStateException("Only overriding this method for reference."); + } + + /** + * Set engine requires appId and wrapperId + * @param request + * @return + */ + @POST + @Produces("application/json") + @Path("/setEngine") + public Response setEngine(@Context HttpServletRequest request) { + + // Grab parameters + String appId = request.getParameter(APP_ID); + String wrapperId = request.getParameter(WRAPPER_ID); + + // Perform action + IRawSelectWrapper wrapper = getRawSelectWrapper(appId, wrapperId); + IEngine engine = getEngine(appId); + wrapper.setEngine(engine); + + // Set return values + Hashtable ret = new Hashtable(); + ret.put("success", true); + ret.put("appId", appId); + ret.put("wrapperId", wrapperId); + ret.put("action", "setEngine"); + return WebUtility.getResponse(ret, 200); + } + + @Override + public boolean hasNext() { + throw new IllegalStateException("Only overriding this method for reference."); + } + + /** + * Has next requires appId and wrapperId + * @param request + * @return + */ + @POST + @Produces("application/json") + @Path("/hasNext") + public Response hasNext(@Context HttpServletRequest request) { + + // Grab parameters + String appId = request.getParameter(APP_ID); + String wrapperId = request.getParameter(WRAPPER_ID); + + // Perform action + IRawSelectWrapper wrapper = getRawSelectWrapper(appId, wrapperId); + boolean hasNext = wrapper.hasNext(); + + // Set return values + return WebUtility.getResponse(hasNext, 200); + } + + @Override + public IHeadersDataRow next() { + throw new IllegalStateException("Only overriding this method for reference."); + } + + /** + * Next requires appId and wrapperId + * @param request + * @return + */ + @POST + @Produces("application/json") + @Path("/next") + public Response next(@Context HttpServletRequest request) { + + // Grab parameters + String appId = request.getParameter(APP_ID); + String wrapperId = request.getParameter(WRAPPER_ID); + + // Perform action + IRawSelectWrapper wrapper = getRawSelectWrapper(appId, wrapperId); + IHeadersDataRow nextRow = wrapper.next(); + + // Set return values + return WebUtility.getResponse(nextRow, 200); + } + + @Override + public String[] getHeaders() { + throw new IllegalStateException("Only overriding this method for reference."); + } + + /** + * Get headers requires appId and wrapperId + * @param request + * @return + */ + @POST + @Produces("application/json") + @Path("/getHeaders") + public Response getHeaders(@Context HttpServletRequest request) { + + // Grab parameters + String appId = request.getParameter(APP_ID); + String wrapperId = request.getParameter(WRAPPER_ID); + + // Perform action + IRawSelectWrapper wrapper = getRawSelectWrapper(appId, wrapperId); + String[] headers = wrapper.getHeaders(); + + // Set return values + return WebUtility.getResponse(headers, 200); + } + + @Override + public SemossDataType[] getTypes() { + throw new IllegalStateException("Only overriding this method for reference."); + } + + /** + * Get types requires appId and wrapperId + * @param request + * @return + */ + @POST + @Produces("application/json") + @Path("/getTypes") + public Response getTypes(@Context HttpServletRequest request) { + + // Grab parameters + String appId = request.getParameter(APP_ID); + String wrapperId = request.getParameter(WRAPPER_ID); + + // Perform action + IRawSelectWrapper wrapper = getRawSelectWrapper(appId, wrapperId); + SemossDataType[] types = wrapper.getTypes(); + + // Set return values + return WebUtility.getResponse(types, 200); + } + + @Override + public long getNumRecords() { + throw new IllegalStateException("Only overriding this method for reference."); + } + + /** + * Get num records requires appId and wrapperId + * @param request + * @return + */ + @POST + @Produces("application/json") + @Path("/getNumRecords") + public Response getNumRecords(@Context HttpServletRequest request) { + + // Grab parameters + String appId = request.getParameter(APP_ID); + String wrapperId = request.getParameter(WRAPPER_ID); + + // Perform action + IRawSelectWrapper wrapper = getRawSelectWrapper(appId, wrapperId); + long numRecords = wrapper.getNumRecords(); + + // Set return values + return WebUtility.getResponse(numRecords, 200); + } + + @Override + public void reset() { + throw new IllegalStateException("Only overriding this method for reference."); + } + + /** + * Reset requires appId and wrapperId + * @param request + * @return + */ + @POST + @Produces("application/json") + @Path("/reset") + public Response reset(@Context HttpServletRequest request) { + + // Grab parameters + String appId = request.getParameter(APP_ID); + String wrapperId = request.getParameter(WRAPPER_ID); + + // Perform action + IRawSelectWrapper wrapper = getRawSelectWrapper(appId, wrapperId); + wrapper.reset(); + + // Set return values + Hashtable ret = new Hashtable(); + ret.put("success", true); + ret.put("appId", appId); + ret.put("wrapperId", wrapperId); + ret.put("action", "reset"); + return WebUtility.getResponse(ret, 200); + } + +} diff --git a/src/prerna/semoss/web/app/MonolithApplication.java b/src/prerna/semoss/web/app/MonolithApplication.java index 4779aa99b..b886041e7 100644 --- a/src/prerna/semoss/web/app/MonolithApplication.java +++ b/src/prerna/semoss/web/app/MonolithApplication.java @@ -32,6 +32,7 @@ import javax.ws.rs.core.Application; +import prerna.cluster.RawSelectWrapperService; import prerna.semoss.web.form.FormResource; import prerna.semoss.web.services.AppResource; import prerna.semoss.web.services.AuthorizationResource; @@ -50,6 +51,7 @@ public MonolithApplication() { singletons.add(new AuthorizationResource()); singletons.add(new FormResource()); singletons.add(new ServerConfigurationResource()); + singletons.add(new RawSelectWrapperService()); } @Override diff --git a/src/prerna/web/conf/UserDBLoader.java b/src/prerna/web/conf/UserDBLoader.java index 5d9a5ea9b..932c1de83 100644 --- a/src/prerna/web/conf/UserDBLoader.java +++ b/src/prerna/web/conf/UserDBLoader.java @@ -63,7 +63,7 @@ private void publish() { // we are in business ZKClient client = ZKClient.getInstance(); - client.publishDB(client.host); + client.publishContainer(client.host); } // else // nothing to do proceed @@ -81,7 +81,7 @@ private void unpublish() ZKClient client = ZKClient.getInstance(); client.zkClient = null; client = ZKClient.getInstance(); - client.deleteDB(client.host); + client.deleteContainer(client.host); } // else // nothing to do proceed From 9f301b46e134bde0c059733bbd74c3f3962f1501 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 2 Oct 2018 18:17:44 +0000 Subject: [PATCH 0256/1906] UPDATE ::: Cleaning up code as a result of configuration details consolidation git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30271 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 7e65be666a5cc9d52c3a01acebc8bdad486714cb --- .../semoss/web/services/AuthorizationResource.java | 3 +++ src/prerna/semoss/web/services/NameServer.java | 7 ------- src/prerna/semoss/web/services/UserResource.java | 10 ---------- src/prerna/web/conf/NoUserInSessionFilter.java | 2 -- 4 files changed, 3 insertions(+), 19 deletions(-) diff --git a/src/prerna/semoss/web/services/AuthorizationResource.java b/src/prerna/semoss/web/services/AuthorizationResource.java index c47adb956..e575cf15c 100644 --- a/src/prerna/semoss/web/services/AuthorizationResource.java +++ b/src/prerna/semoss/web/services/AuthorizationResource.java @@ -84,10 +84,13 @@ private User getUser(@Context HttpServletRequest request) throws IllegalAccessEx /** * Check if the security is enabled in the application. * @return true or false + * @deprecated >>>> REPLACED WITH /config endpoint + * THIS IS STILL CALLED IN PLAYSHEETS SO NOT REMOVING */ @GET @Produces("application/json") @Path("securityEnabled") + @Deprecated public StreamingOutput isSecurityEnabled(@Context ServletContext context) { return WebUtility.getSO(AbstractSecurityUtils.securityEnabled()); } diff --git a/src/prerna/semoss/web/services/NameServer.java b/src/prerna/semoss/web/services/NameServer.java index 18cc10e7b..412beba96 100644 --- a/src/prerna/semoss/web/services/NameServer.java +++ b/src/prerna/semoss/web/services/NameServer.java @@ -107,13 +107,6 @@ public class NameServer { @Context protected ServletContext context; - @GET - @Path("/sessionTimeout") - @Produces("application/json") - public Response getTimeoutValue(@Context HttpServletRequest request) { - return WebUtility.getResponse((double) request.getSession().getMaxInactiveInterval() / 60, 200); - } - // uploader functionality @Path("/uploadDatabase") public Uploader uploadDatabase(@Context HttpServletRequest request) { diff --git a/src/prerna/semoss/web/services/UserResource.java b/src/prerna/semoss/web/services/UserResource.java index bf5fc7be4..ff09b8497 100644 --- a/src/prerna/semoss/web/services/UserResource.java +++ b/src/prerna/semoss/web/services/UserResource.java @@ -1500,14 +1500,4 @@ public synchronized Response modifyLoginProperties(@PathParam("provider") String return WebUtility.getResponse(true, 200); } - - @GET - @Produces("application/json") - @Path("/isUserRegistrationOn/") - @Deprecated - public Response isUserRegistrationOn(@Context HttpServletRequest request) throws IOException { - boolean registration = Boolean.parseBoolean(socialData.getProperty("native_registration")); - return WebUtility.getResponse(registration, 200); - } - } diff --git a/src/prerna/web/conf/NoUserInSessionFilter.java b/src/prerna/web/conf/NoUserInSessionFilter.java index c8a2a0d6a..004384112 100644 --- a/src/prerna/web/conf/NoUserInSessionFilter.java +++ b/src/prerna/web/conf/NoUserInSessionFilter.java @@ -24,8 +24,6 @@ public class NoUserInSessionFilter implements Filter { protected static List ignoreDueToFE = new Vector(); static { ignoreDueToFE.add("config"); - ignoreDueToFE.add("authorization/securityEnabled"); - ignoreDueToFE.add("auth/isUserRegistrationOn"); ignoreDueToFE.add("auth/logins"); ignoreDueToFE.add("auth/loginsAllowed"); ignoreDueToFE.add("auth/login"); From c30c21cbc3a16e5aa26421eccd7925f98da5473b Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 2 Oct 2018 18:26:08 +0000 Subject: [PATCH 0257/1906] UPDATE ::: Redirect the FE when the logout is called and no user is logged in with security enabled git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30273 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 8519476a4c81163de88de4fe73eeb3c75a96ae91 --- src/prerna/semoss/web/services/UserResource.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/prerna/semoss/web/services/UserResource.java b/src/prerna/semoss/web/services/UserResource.java index ff09b8497..7bba3f931 100644 --- a/src/prerna/semoss/web/services/UserResource.java +++ b/src/prerna/semoss/web/services/UserResource.java @@ -263,7 +263,7 @@ public Response getAllLogins(@Context HttpServletRequest request) { @GET @Produces("application/json") @Path("/logout/{provider}") - public Response logout(@PathParam("provider") String provider, @Context HttpServletRequest request) throws IOException { + public Response logout(@PathParam("provider") String provider, @Context HttpServletRequest request, @Context HttpServletResponse repsonse) throws IOException { boolean removed = false; if(provider.equalsIgnoreCase("ALL")) { // remove the user from session call it a day @@ -274,6 +274,17 @@ public Response logout(@PathParam("provider") String provider, @Context HttpServ removed = thisUser.dropAccessToken(provider.toUpperCase()); if(thisUser.getLogins().isEmpty()) { request.getSession().removeAttribute(Constants.SESSION_USER); + + if(AbstractSecurityUtils.securityEnabled()) { + // well, you have logged out and we always require a login + // so i will redirect you + repsonse.setStatus(302); + String redirectUrl = request.getHeader("referer"); + redirectUrl = redirectUrl + "#!/login"; + ((HttpServletResponse) repsonse).setHeader("redirect", redirectUrl); + ((HttpServletResponse) repsonse).sendError(302, "Need to redirect to " + redirectUrl); + return null; + } } else { request.getSession().setAttribute(Constants.SESSION_USER, thisUser); } From 5954e8b5021dd02e97408f6eea7ae86d59df3bd3 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 3 Oct 2018 18:59:39 +0000 Subject: [PATCH 0258/1906] UPDATE ::: Adding static boolean to limit security db querying constantly git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30280 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 039d383bb5c874ce27f674776d7262c791b42376 --- src/prerna/web/conf/NoUserExistsFilter.java | 63 ++++++++++++--------- 1 file changed, 37 insertions(+), 26 deletions(-) diff --git a/src/prerna/web/conf/NoUserExistsFilter.java b/src/prerna/web/conf/NoUserExistsFilter.java index 3db629765..7d74e6b28 100644 --- a/src/prerna/web/conf/NoUserExistsFilter.java +++ b/src/prerna/web/conf/NoUserExistsFilter.java @@ -21,42 +21,53 @@ public class NoUserExistsFilter implements Filter { + private static boolean userDefined = false; + @Override public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { ServletContext context = arg0.getServletContext(); boolean security = Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED)); if(security) { - IEngine engine = Utility.getEngine(Constants.SECURITY_DB); - String q = "SELECT * FROM USER LIMIT 1"; - IRawSelectWrapper wrapper = WrapperManager.getInstance().getRawWrapper(engine, q); - try { - boolean hasUser = wrapper.hasNext(); + + // i do not want to run this query for every single call + // just gets annoying + if(!NoUserExistsFilter.userDefined) { - // no users at all registered, we need to send to the admin page - if(!hasUser) { - - // we need to store information in the session - // so that we can properly come back to the referer once an admin has been added - String referer = ((HttpServletRequest) arg0).getHeader("referer"); - referer = referer + "#!/login"; - ((HttpServletRequest) arg0).getSession(true).setAttribute(AdminConfigService.ADMIN_REDIRECT_KEY, referer); - - // this will be the deployment name of the app - String contextPath = context.getContextPath(); + IEngine engine = Utility.getEngine(Constants.SECURITY_DB); + String q = "SELECT * FROM USER LIMIT 1"; + IRawSelectWrapper wrapper = WrapperManager.getInstance().getRawWrapper(engine, q); + try { + boolean hasUser = wrapper.hasNext(); - // this will be the full path of the request - // like http://localhost:8080/Monolith_Dev/api/engine/runPixel - String fullUrl = ((HttpServletRequest) arg0).getRequestURL().toString(); + // no users at all registered, we need to send to the admin page + if(!hasUser) { + + // we need to store information in the session + // so that we can properly come back to the referer once an admin has been added + String referer = ((HttpServletRequest) arg0).getHeader("referer"); + referer = referer + "#!/login"; + ((HttpServletRequest) arg0).getSession(true).setAttribute(AdminConfigService.ADMIN_REDIRECT_KEY, referer); - // we redirect to the index.html page where we have pushed the admin page - String redirectUrl = fullUrl.substring(0, fullUrl.indexOf(contextPath) + contextPath.length()); - ((HttpServletResponse) arg1).setHeader("redirect", redirectUrl); - ((HttpServletResponse) arg1).sendError(302, "Need to redirect to " + redirectUrl); - return; + // this will be the deployment name of the app + String contextPath = context.getContextPath(); + + // this will be the full path of the request + // like http://localhost:8080/Monolith_Dev/api/engine/runPixel + String fullUrl = ((HttpServletRequest) arg0).getRequestURL().toString(); + + // we redirect to the index.html page where we have pushed the admin page + String redirectUrl = fullUrl.substring(0, fullUrl.indexOf(contextPath) + contextPath.length()); + ((HttpServletResponse) arg1).setHeader("redirect", redirectUrl); + ((HttpServletResponse) arg1).sendError(302, "Need to redirect to " + redirectUrl); + return; + } else { + // set boolean so we dont keep querying all the time + NoUserExistsFilter.userDefined = true; + } + } finally { + wrapper.cleanUp(); } - } finally { - wrapper.cleanUp(); } } From 8628f5c46e1b770f142b94b2a85c74803ba2f4fe Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 3 Oct 2018 20:52:35 +0000 Subject: [PATCH 0259/1906] UPDATE ::: Updating using all signed in users to for settings tab git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30284 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 110fdebe27fe69470d619bf8e4442e71c51cf9e8 --- .../web/services/AuthorizationResource.java | 61 ++++++++----------- 1 file changed, 25 insertions(+), 36 deletions(-) diff --git a/src/prerna/semoss/web/services/AuthorizationResource.java b/src/prerna/semoss/web/services/AuthorizationResource.java index e575cf15c..b05df62d7 100644 --- a/src/prerna/semoss/web/services/AuthorizationResource.java +++ b/src/prerna/semoss/web/services/AuthorizationResource.java @@ -118,29 +118,17 @@ public StreamingOutput searchForUser(@Context HttpServletRequest request, @Query @GET @Produces("application/json") @Path("getDatabases") - public Response getDatabases(@Context HttpServletRequest request) { - Hashtable errorRet = new Hashtable(); - List> ret = new ArrayList<>(); - HttpSession session = request.getSession(false); - if(session == null){ + public Response getUserDatabaseSettings(@Context HttpServletRequest request) { + User user = null; + try { + user = getUser(request); + } catch (IllegalAccessException e) { Map errorMap = new HashMap(); errorMap.put("error", "User session is invalid"); return WebUtility.getResponse(errorMap, 401); } - try{ - User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - String userId = user.getAccessToken(user.getLogins().get(0)).getId();; - ret = SecurityQueryUtils.getUserDatabases(userId, false); - return WebUtility.getResponse(ret, 200); - } catch (IllegalArgumentException e){ - e.printStackTrace(); - errorRet.put("error", e.getMessage()); - return WebUtility.getResponse(errorRet, 500); - } catch (Exception e){ - e.printStackTrace(); - errorRet.put("error", "An unexpected error happened. Please try again."); - return WebUtility.getResponse(errorRet, 500); - } + + return WebUtility.getResponse(SecurityQueryUtils.getAllUserDatabaseSettings(user), 200); } ////////////////////////////////////////////// @@ -187,7 +175,7 @@ public Response getAllUsers(@Context HttpServletRequest request) { return WebUtility.getResponse(retMap, 400); } - List> ret = adminUtils.getAllUsers(user); + List> ret = adminUtils.getAllUsers(); return WebUtility.getResponse(ret, 200); } @@ -279,23 +267,24 @@ public Response deleteUser(@Context HttpServletRequest request, MultivaluedMap errorRet = new Hashtable(); - List> ret = new ArrayList<>(); - try{ - User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - String userId = user.getAccessToken(user.getLogins().get(0)).getId(); - ret = SecurityQueryUtils.getUserDatabases(userId, true); - return WebUtility.getResponse(ret, 200); - } catch (IllegalArgumentException e){ - e.printStackTrace(); - errorRet.put("error", e.getMessage()); - return WebUtility.getResponse(errorRet, 500); - } catch (Exception e){ - e.printStackTrace(); - errorRet.put("error", "An unexpected error happened. Please try again."); - return WebUtility.getResponse(errorRet, 500); + public Response getAdminDatabaseSettings(@Context HttpServletRequest request) { + User user = null; + try { + user = getUser(request); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap(); + errorMap.put("error", "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + + SecurityAdminUtils adminUtils = SecurityAdminUtils.getInstance(user); + if(adminUtils == null) { + Map retMap = new Hashtable(); + retMap.put("error", "User does not have admin priviledges"); + return WebUtility.getResponse(retMap, 400); } + + return WebUtility.getResponse(adminUtils.getAllUserDatabaseSettings(), 200); } From 4e175515f22792b061cc838fd9623b4f338dda19 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 4 Oct 2018 12:13:37 +0000 Subject: [PATCH 0260/1906] UPDATE ::: Shifting services package structure for local vs. rest git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30294 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: eb6d93df0ee45ec4005b244d07eddf8217a4c78b --- src/prerna/auth/CACReader.java | 15 +++++-- .../semoss/web/app/AdminApplication.java | 2 +- .../semoss/web/app/MonolithApplication.java | 10 ++--- .../{ => config}/AdminConfigService.java | 2 +- .../ServerConfigurationResource.java | 3 +- .../web/services/{ => local}/AppResource.java | 40 ++++++++++++++++++- .../{ => local}/AuthorizationResource.java | 2 +- .../{ => local}/DataframeResource.java | 3 +- .../services/{ => local}/EngineResource.java | 3 +- .../web/services/{ => local}/NameServer.java | 4 +- .../services/{ => local}/UserResource.java | 2 +- .../{ => remote}/CentralNameServer.java | 4 +- .../{ => remote}/EngineRemoteResource.java | 2 +- 13 files changed, 71 insertions(+), 21 deletions(-) rename src/prerna/semoss/web/services/{ => config}/AdminConfigService.java (94%) rename src/prerna/semoss/web/services/{ => config}/ServerConfigurationResource.java (90%) rename src/prerna/semoss/web/services/{ => local}/AppResource.java (81%) rename src/prerna/semoss/web/services/{ => local}/AuthorizationResource.java (97%) rename src/prerna/semoss/web/services/{ => local}/DataframeResource.java (96%) rename src/prerna/semoss/web/services/{ => local}/EngineResource.java (96%) rename src/prerna/semoss/web/services/{ => local}/NameServer.java (97%) rename src/prerna/semoss/web/services/{ => local}/UserResource.java (97%) rename src/prerna/semoss/web/services/{ => remote}/CentralNameServer.java (94%) rename src/prerna/semoss/web/services/{ => remote}/EngineRemoteResource.java (96%) diff --git a/src/prerna/auth/CACReader.java b/src/prerna/auth/CACReader.java index a5b9dd8d4..cbc577469 100644 --- a/src/prerna/auth/CACReader.java +++ b/src/prerna/auth/CACReader.java @@ -17,12 +17,15 @@ import javax.smartcardio.CardTerminal; import javax.smartcardio.TerminalFactory; +import prerna.test.TestUtilityMethods; import prerna.util.DIHelper; import sun.security.pkcs11.SunPKCS11; public class CACReader { public static void main(String[] args) { + TestUtilityMethods.loadDIHelper("C:\\workspace\\Semoss_Dev\\RDF_Map.prop"); + try { BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); System.out.print("Enter PIN: "); @@ -68,17 +71,21 @@ public String getCACName(String pin) { X509Certificate cert0 = (X509Certificate) keyStore.getCertificate(alias.toString()); System.out.println("I am: " + cert0.getSubjectDN().getName()); System.out.println(cert0.getIssuerDN().getName()); + for(List x : cert0.getSubjectAlternativeNames()) { + for(Object x2 : x) { + System.out.println(">>>> " + x2 + " , " + x2.getClass().getName() ); + } + } - X509Certificate cert = (X509Certificate) keyStore.getCertificate(alias.toString()); - - String dn = cert.getSubjectX500Principal().getName(); + String dn = cert0.getSubjectX500Principal().getName(); LdapName ldapDN = new LdapName(dn); for(Rdn rdn: ldapDN.getRdns()) { if(rdn.getType().equals("CN")) { ret = rdn.getValue().toString(); - System.out.println(rdn.getType() + " -> " + rdn.getValue() + "\n"); + System.out.println(rdn.getType() + " -> " + rdn.getValue()); } } + System.out.println(""); } catch (Exception e) { e.printStackTrace(); } diff --git a/src/prerna/semoss/web/app/AdminApplication.java b/src/prerna/semoss/web/app/AdminApplication.java index 817a704d7..acde501fb 100644 --- a/src/prerna/semoss/web/app/AdminApplication.java +++ b/src/prerna/semoss/web/app/AdminApplication.java @@ -32,7 +32,7 @@ import javax.ws.rs.core.Application; -import prerna.semoss.web.services.AdminConfigService; +import prerna.semoss.web.services.config.AdminConfigService; public class AdminApplication extends Application { diff --git a/src/prerna/semoss/web/app/MonolithApplication.java b/src/prerna/semoss/web/app/MonolithApplication.java index b886041e7..484ac1897 100644 --- a/src/prerna/semoss/web/app/MonolithApplication.java +++ b/src/prerna/semoss/web/app/MonolithApplication.java @@ -34,11 +34,11 @@ import prerna.cluster.RawSelectWrapperService; import prerna.semoss.web.form.FormResource; -import prerna.semoss.web.services.AppResource; -import prerna.semoss.web.services.AuthorizationResource; -import prerna.semoss.web.services.NameServer; -import prerna.semoss.web.services.ServerConfigurationResource; -import prerna.semoss.web.services.UserResource; +import prerna.semoss.web.services.config.ServerConfigurationResource; +import prerna.semoss.web.services.local.AppResource; +import prerna.semoss.web.services.local.AuthorizationResource; +import prerna.semoss.web.services.local.NameServer; +import prerna.semoss.web.services.local.UserResource; public class MonolithApplication extends Application { diff --git a/src/prerna/semoss/web/services/AdminConfigService.java b/src/prerna/semoss/web/services/config/AdminConfigService.java similarity index 94% rename from src/prerna/semoss/web/services/AdminConfigService.java rename to src/prerna/semoss/web/services/config/AdminConfigService.java index 8ab043b5f..d9213966f 100644 --- a/src/prerna/semoss/web/services/AdminConfigService.java +++ b/src/prerna/semoss/web/services/config/AdminConfigService.java @@ -1,4 +1,4 @@ -package prerna.semoss.web.services; +package prerna.semoss.web.services.config; import java.io.IOException; diff --git a/src/prerna/semoss/web/services/ServerConfigurationResource.java b/src/prerna/semoss/web/services/config/ServerConfigurationResource.java similarity index 90% rename from src/prerna/semoss/web/services/ServerConfigurationResource.java rename to src/prerna/semoss/web/services/config/ServerConfigurationResource.java index ff9748b71..0f71f3b2d 100644 --- a/src/prerna/semoss/web/services/ServerConfigurationResource.java +++ b/src/prerna/semoss/web/services/config/ServerConfigurationResource.java @@ -1,4 +1,4 @@ -package prerna.semoss.web.services; +package prerna.semoss.web.services.config; import java.util.HashMap; import java.util.Map; @@ -11,6 +11,7 @@ import javax.ws.rs.core.Response; import prerna.auth.utils.AbstractSecurityUtils; +import prerna.semoss.web.services.config.ServerConfigurationResource; import prerna.util.Constants; import prerna.util.DIHelper; import prerna.web.services.util.WebUtility; diff --git a/src/prerna/semoss/web/services/AppResource.java b/src/prerna/semoss/web/services/local/AppResource.java similarity index 81% rename from src/prerna/semoss/web/services/AppResource.java rename to src/prerna/semoss/web/services/local/AppResource.java index bc10ee490..2a951afb9 100644 --- a/src/prerna/semoss/web/services/AppResource.java +++ b/src/prerna/semoss/web/services/local/AppResource.java @@ -1,4 +1,4 @@ -package prerna.semoss.web.services; +package prerna.semoss.web.services.local; import java.io.File; import java.io.FileFilter; @@ -24,7 +24,10 @@ import org.apache.commons.io.IOUtils; import org.apache.commons.io.filefilter.WildcardFileFilter; +import prerna.auth.User; import prerna.auth.utils.AbstractSecurityUtils; +import prerna.auth.utils.SecurityQueryUtils; +import prerna.engine.api.IEngine; import prerna.engine.impl.SmssUtilities; import prerna.nameserver.utility.MasterDatabaseUtility; import prerna.sablecc2.reactor.utils.ImageCaptureReactor; @@ -39,6 +42,39 @@ public class AppResource { private static final String DIR_SEPARATOR = java.nio.file.FileSystems.getDefault().getSeparator(); + /** + * Utility method to get the app only if person has access to it + * @param user + * @param appId + * @return + * @throws IllegalAccessException + */ + private IEngine getApp(User user, String appId) throws IllegalAccessException { + if(AbstractSecurityUtils.securityEnabled()) { + appId = SecurityQueryUtils.testUserEngineIdForAlias(user, appId); + if(!SecurityQueryUtils.getUserEngineIds(user).contains(appId)) { + throw new IllegalAccessException("App " + appId + " does not exist or user does not have access to database"); + } + } else { + appId = MasterDatabaseUtility.testEngineIdIfAlias(appId); + if(!MasterDatabaseUtility.getAllEngineIds().contains(appId)) { + throw new IllegalAccessException("App " + appId + " does not exist"); + } + } + + return Utility.getEngine(appId); + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////////////// + + /* + * Code below is around app images and insight images + */ + @GET @Path("/appImage/download") @Produces(MediaType.APPLICATION_OCTET_STREAM) @@ -171,7 +207,7 @@ private File getInsightImageFile(String app, String id, String feUrl, String par ///////////////////////////////////////////////////////////////// /* - * Utility methods + * Image utility methods */ /** diff --git a/src/prerna/semoss/web/services/AuthorizationResource.java b/src/prerna/semoss/web/services/local/AuthorizationResource.java similarity index 97% rename from src/prerna/semoss/web/services/AuthorizationResource.java rename to src/prerna/semoss/web/services/local/AuthorizationResource.java index b05df62d7..5898e72d5 100644 --- a/src/prerna/semoss/web/services/AuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/AuthorizationResource.java @@ -25,7 +25,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. *******************************************************************************/ -package prerna.semoss.web.services; +package prerna.semoss.web.services.local; import java.io.IOException; import java.util.ArrayList; diff --git a/src/prerna/semoss/web/services/DataframeResource.java b/src/prerna/semoss/web/services/local/DataframeResource.java similarity index 96% rename from src/prerna/semoss/web/services/DataframeResource.java rename to src/prerna/semoss/web/services/local/DataframeResource.java index 314afb3a5..523677bd3 100644 --- a/src/prerna/semoss/web/services/DataframeResource.java +++ b/src/prerna/semoss/web/services/local/DataframeResource.java @@ -1,4 +1,4 @@ -package prerna.semoss.web.services; +package prerna.semoss.web.services.local; import java.io.File; import java.io.IOException; @@ -39,6 +39,7 @@ import prerna.query.querystruct.selectors.IQuerySelector; import prerna.query.querystruct.selectors.QueryColumnSelector; import prerna.sablecc2.reactor.imports.FileMeta; +import prerna.semoss.web.services.local.DataframeResource; import prerna.util.Constants; import prerna.util.DIHelper; import prerna.util.Utility; diff --git a/src/prerna/semoss/web/services/EngineResource.java b/src/prerna/semoss/web/services/local/EngineResource.java similarity index 96% rename from src/prerna/semoss/web/services/EngineResource.java rename to src/prerna/semoss/web/services/local/EngineResource.java index cf75c0690..7b3926998 100644 --- a/src/prerna/semoss/web/services/EngineResource.java +++ b/src/prerna/semoss/web/services/local/EngineResource.java @@ -25,7 +25,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. *******************************************************************************/ -package prerna.semoss.web.services; +package prerna.semoss.web.services.local; import java.util.HashMap; import java.util.Hashtable; @@ -68,6 +68,7 @@ import prerna.sablecc2.reactor.job.JobReactor; import prerna.sablecc2.reactor.legacy.playsheets.GetPlaysheetParamsReactor; import prerna.sablecc2.reactor.legacy.playsheets.RunPlaysheetReactor; +import prerna.semoss.web.services.local.EngineResource; import prerna.util.Constants; import prerna.util.Utility; import prerna.web.services.util.WebUtility; diff --git a/src/prerna/semoss/web/services/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java similarity index 97% rename from src/prerna/semoss/web/services/NameServer.java rename to src/prerna/semoss/web/services/local/NameServer.java index 412beba96..5e56c8f59 100644 --- a/src/prerna/semoss/web/services/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -25,7 +25,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. *******************************************************************************/ -package prerna.semoss.web.services; +package prerna.semoss.web.services.local; import java.io.File; import java.io.IOException; @@ -88,6 +88,8 @@ import prerna.sablecc2.PixelStreamUtility; import prerna.sablecc2.comm.JobManager; import prerna.sablecc2.comm.JobThread; +import prerna.semoss.web.services.remote.CentralNameServer; +import prerna.semoss.web.services.remote.EngineRemoteResource; import prerna.upload.DatabaseUploader; import prerna.upload.FileUploader; import prerna.upload.ImageUploader; diff --git a/src/prerna/semoss/web/services/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java similarity index 97% rename from src/prerna/semoss/web/services/UserResource.java rename to src/prerna/semoss/web/services/local/UserResource.java index 7bba3f931..29a1c15d8 100644 --- a/src/prerna/semoss/web/services/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -25,7 +25,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. *******************************************************************************/ -package prerna.semoss.web.services; +package prerna.semoss.web.services.local; import java.io.File; import java.io.FileInputStream; diff --git a/src/prerna/semoss/web/services/CentralNameServer.java b/src/prerna/semoss/web/services/remote/CentralNameServer.java similarity index 94% rename from src/prerna/semoss/web/services/CentralNameServer.java rename to src/prerna/semoss/web/services/remote/CentralNameServer.java index ce273e4c3..39d8da0e9 100644 --- a/src/prerna/semoss/web/services/CentralNameServer.java +++ b/src/prerna/semoss/web/services/remote/CentralNameServer.java @@ -25,7 +25,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. *******************************************************************************/ -package prerna.semoss.web.services; +package prerna.semoss.web.services.remote; import java.util.ArrayList; import java.util.Arrays; @@ -45,6 +45,8 @@ import com.google.gson.Gson; +import prerna.semoss.web.services.local.NameServer; +import prerna.semoss.web.services.remote.CentralNameServer; import prerna.util.Constants; import prerna.util.Utility; import prerna.web.services.util.WebUtility; diff --git a/src/prerna/semoss/web/services/EngineRemoteResource.java b/src/prerna/semoss/web/services/remote/EngineRemoteResource.java similarity index 96% rename from src/prerna/semoss/web/services/EngineRemoteResource.java rename to src/prerna/semoss/web/services/remote/EngineRemoteResource.java index 6bc535761..f0b73206e 100644 --- a/src/prerna/semoss/web/services/EngineRemoteResource.java +++ b/src/prerna/semoss/web/services/remote/EngineRemoteResource.java @@ -25,7 +25,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. *******************************************************************************/ -package prerna.semoss.web.services; +package prerna.semoss.web.services.remote; import java.io.IOException; import java.io.ObjectOutputStream; From dc522bf150cd538e07c877c95c4140f7c3687fe8 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 4 Oct 2018 12:21:24 +0000 Subject: [PATCH 0261/1906] UPDATE ::: Missed class needed for package change git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30295 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 01f379141d101a3fbe17b3c14ad5e2fae0735221 --- src/prerna/web/conf/NoUserExistsFilter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prerna/web/conf/NoUserExistsFilter.java b/src/prerna/web/conf/NoUserExistsFilter.java index 7d74e6b28..759a22267 100644 --- a/src/prerna/web/conf/NoUserExistsFilter.java +++ b/src/prerna/web/conf/NoUserExistsFilter.java @@ -15,7 +15,7 @@ import prerna.engine.api.IEngine; import prerna.engine.api.IRawSelectWrapper; import prerna.rdf.engine.wrappers.WrapperManager; -import prerna.semoss.web.services.AdminConfigService; +import prerna.semoss.web.services.config.AdminConfigService; import prerna.util.Constants; import prerna.util.Utility; From 13b677684093d51f140ee3c8a9c5bbd5bad8508e Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 4 Oct 2018 12:30:01 +0000 Subject: [PATCH 0262/1906] UPDATE ::: Building out CACReader to triage issues with processing cac information git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30296 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 3286b9b432039580362d304c3f0ccd4ba77049b7 --- src/prerna/auth/CACReader.java | 120 +++++++++++++++++++++------------ 1 file changed, 77 insertions(+), 43 deletions(-) diff --git a/src/prerna/auth/CACReader.java b/src/prerna/auth/CACReader.java index cbc577469..0c3cd5391 100644 --- a/src/prerna/auth/CACReader.java +++ b/src/prerna/auth/CACReader.java @@ -6,14 +6,17 @@ import java.security.KeyStore; import java.security.Provider; import java.security.Security; +import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; import java.util.Enumeration; import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import javax.naming.InvalidNameException; import javax.naming.ldap.LdapName; import javax.naming.ldap.Rdn; import javax.smartcardio.Card; -import javax.smartcardio.CardChannel; import javax.smartcardio.CardTerminal; import javax.smartcardio.TerminalFactory; @@ -35,81 +38,112 @@ public static void main(String[] args) { CACReader t = new CACReader(); t.showTerminals(); - t.getCACName(pin); + t.processCAC(pin); } catch (Exception e) { e.printStackTrace(); } } - public String getCACName(String pin) { - String ret = ""; - + public void processCAC(String pin) { if(pin == null || pin.isEmpty()) { - return ret; + return; } try { - KeyStore keyStore; + /* + * Load the information to get the CAC data + */ String config = "showInfo = true" + "\nlibrary = " + DIHelper.getInstance().getProperty("BaseFolder") + "\\config\\CACauth\\opensc-pkcs11.dll" + "\nname = SmartCard"; SunPKCS11 providerMSCAPI = new SunPKCS11(new ByteArrayInputStream(config.getBytes("UTF-8"))); Provider p = providerMSCAPI; Security.addProvider(p); - - System.out.println(p.getName()); - keyStore = KeyStore.getInstance("PKCS11", p); - + KeyStore keyStore = KeyStore.getInstance("PKCS11", p); KeyStore.PasswordProtection pp = new KeyStore.PasswordProtection(pin.toCharArray()); keyStore.load(null, pp.getPassword()); + + System.out.println("-----------------------"); + System.out.println("-----------------------"); + System.out.println("-----------------------"); + System.out.println("STARTING PROCESS"); System.out.println("-----------------------"); - Enumeration xaliasesEnum = keyStore.aliases(); + System.out.println("-----------------------"); + System.out.println("-----------------------"); + Enumeration xaliasesEnum = keyStore.aliases(); while (xaliasesEnum.hasMoreElements()) { Object alias = xaliasesEnum.nextElement(); try { - X509Certificate cert0 = (X509Certificate) keyStore.getCertificate(alias.toString()); - System.out.println("I am: " + cert0.getSubjectDN().getName()); - System.out.println(cert0.getIssuerDN().getName()); - for(List x : cert0.getSubjectAlternativeNames()) { - for(Object x2 : x) { - System.out.println(">>>> " + x2 + " , " + x2.getClass().getName() ); - } - } + X509Certificate cert = (X509Certificate) keyStore.getCertificate(alias.toString()); - String dn = cert0.getSubjectX500Principal().getName(); - LdapName ldapDN = new LdapName(dn); - for(Rdn rdn: ldapDN.getRdns()) { - if(rdn.getType().equals("CN")) { - ret = rdn.getValue().toString(); - System.out.println(rdn.getType() + " -> " + rdn.getValue()); + String fullName = cert.getSubjectX500Principal().getName(); + System.out.println("-----------------------"); + System.out.println("PROCESSING CERT >>>"); + System.out.println("REQUEST COMING FROM " + fullName); + LdapName ldapDN; + try { + ldapDN = new LdapName(fullName); + for(Rdn rdn: ldapDN.getRdns()) { + if(rdn.getType().equals("CN")) { + String value = rdn.getValue().toString(); + + String[] split = value.split("\\."); + if(split.length == 3 || split.length == 4) { + // no idea if middle name is always there or not + // just gonna validate the cac has length 10 + String cacId = split[split.length-1]; + if(cacId.length() >= 10) { + // valid CAC!!! + System.out.println("I HAVE CAC ID :::: " + cacId); + System.out.println("I HAVE NAME :::: " + Stream.of(split).limit(split.length-2).collect(Collectors.joining(" "))); + System.out.println("I HAVE TYPE :::: " + cert.getIssuerDN().getName()); + System.out.println("I HAVE EXPIRATION :::: " + (int) cert.getNotAfter().getTime()); + + // try to get the email + try { + EMAIL_LOOP : for(List altNames : cert.getSubjectAlternativeNames()) { + for(Object alternative : altNames) { + if(alternative instanceof String) { + String altStr = alternative.toString(); + // really simple email check... + if(altStr.contains("@")) { + System.out.println("I HAVE EMAIL :::: " + altStr); + break EMAIL_LOOP; + } + } + } + } + } catch (CertificateParsingException e) { + e.printStackTrace(); + } + } else { + System.out.println("IGNORE THIS VALUE ::: " + value + " , WITH CAC ID ::: " + cacId); + continue; + } + } else { + System.out.println("IGNORE THIS VALUE ::: " + value); + continue; + } + } } + System.out.println("COMPLETED PROCESSING CERT >>>"); + } catch (InvalidNameException e) { + System.out.println("ERROR WITH PARSING CAC INFORMATION!"); + e.printStackTrace(); } - System.out.println(""); } catch (Exception e) { e.printStackTrace(); } } - -// System.out.println("-----------------------"); -// -// Enumeration aliasesEnum = keyStore.aliases(); -// if(aliasesEnum.hasMoreElements()) { -// String alias = (String) aliasesEnum.nextElement(); -// System.out.println("Alias: " + alias); -// X509Certificate cert = (X509Certificate) keyStore.getCertificate(alias); -// -// String dn = cert.getSubjectX500Principal().getName(); -// LdapName ldapDN = new LdapName(dn); -// for(Rdn rdn: ldapDN.getRdns()) { -// System.out.println(rdn.getType() + " -> " + rdn.getValue()); -// } -// } } catch(Exception e) { e.printStackTrace(); } - return ret; + System.out.println("-----------------------"); + System.out.println("-----------------------"); + System.out.println("-----------------------"); + System.out.println("FINISHED PROCESS"); } public void showTerminals() { From be458df38a0730be81aca1eddb921d160426c41d Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 4 Oct 2018 14:27:08 +0000 Subject: [PATCH 0263/1906] BUGFIX ::: Accounting for Jr. or other appendage to the CN on the certificate git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30301 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 55be5567160a2970e1991aadbfb94fbd6d9621c7 --- src/prerna/web/conf/CACFilter.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/prerna/web/conf/CACFilter.java b/src/prerna/web/conf/CACFilter.java index f501c82f2..36e5b3ee5 100644 --- a/src/prerna/web/conf/CACFilter.java +++ b/src/prerna/web/conf/CACFilter.java @@ -3,7 +3,6 @@ import java.io.IOException; import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; -import java.util.Enumeration; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -14,7 +13,6 @@ import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; -import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; @@ -83,8 +81,9 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 String[] split = value.split("\\."); - if(split.length == 3 || split.length == 4) { - // no idea if middle name is always there or not + if(split.length >= 3 ) { + // need to account for middle name present + // and any other distinction like Jr. after the last name // just gonna validate the cac has length 10 String cacId = split[split.length-1]; if(cacId.length() >= 10) { From 6c5a00af6978c0c7eb97344ca276e376f0cb3804 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 4 Oct 2018 15:25:20 +0000 Subject: [PATCH 0264/1906] UPDATE ::: Making CACReader test class match how we are parsing in CACFilter git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30302 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: c076e48e2d79401957458d97b77b5ed42d5ed9d7 --- src/prerna/auth/CACReader.java | 2 +- src/prerna/web/conf/CACFilter.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/prerna/auth/CACReader.java b/src/prerna/auth/CACReader.java index 0c3cd5391..455d9a942 100644 --- a/src/prerna/auth/CACReader.java +++ b/src/prerna/auth/CACReader.java @@ -89,7 +89,7 @@ public void processCAC(String pin) { String value = rdn.getValue().toString(); String[] split = value.split("\\."); - if(split.length == 3 || split.length == 4) { + if(split.length > 3) { // no idea if middle name is always there or not // just gonna validate the cac has length 10 String cacId = split[split.length-1]; diff --git a/src/prerna/web/conf/CACFilter.java b/src/prerna/web/conf/CACFilter.java index 36e5b3ee5..1f023b393 100644 --- a/src/prerna/web/conf/CACFilter.java +++ b/src/prerna/web/conf/CACFilter.java @@ -81,7 +81,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 String[] split = value.split("\\."); - if(split.length >= 3 ) { + if(split.length >= 3) { // need to account for middle name present // and any other distinction like Jr. after the last name // just gonna validate the cac has length 10 From 5c3d119f04bbeeb7cccae99cf13197fd44d41ff4 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 4 Oct 2018 18:22:22 +0000 Subject: [PATCH 0265/1906] UPDATE ::: Adding ITableDataFrame method to close the database instead of multiple places where we check the type and write unnecessary code git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30309 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 17b93ee98bacd9da75b89ff47e082c0e940c57ff --- src/prerna/web/conf/UserSessionLoader.java | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/src/prerna/web/conf/UserSessionLoader.java b/src/prerna/web/conf/UserSessionLoader.java index 35009f5fc..690ec365e 100644 --- a/src/prerna/web/conf/UserSessionLoader.java +++ b/src/prerna/web/conf/UserSessionLoader.java @@ -14,8 +14,6 @@ import org.apache.log4j.Logger; import prerna.algorithm.api.ITableDataFrame; -import prerna.ds.h2.H2Frame; -import prerna.ds.r.RDataTable; import prerna.om.Insight; import prerna.om.InsightStore; import prerna.sablecc2.om.PixelDataType; @@ -67,18 +65,7 @@ public void sessionDestroyed(HttpSessionEvent sessionEvent) { if(nType == PixelDataType.FRAME) { ITableDataFrame dm = (ITableDataFrame) noun.getValue(); dm.setLogger(LOGGER); - //TODO: expose a delete on the frame to hide this crap - // drop the existing tables/connections if present - if(dm instanceof H2Frame) { - H2Frame frame = (H2Frame)dm; - frame.dropTable(); - if(!frame.isInMem()) { - frame.dropOnDiskTemporalSchema(); - } - } else if(dm instanceof RDataTable) { - RDataTable frame = (RDataTable)dm; - frame.closeConnection(); - } + dm.close(); } } LOGGER.info("Successfully removed all frames from insight"); From 7a35ea94f23a070e8a7e81253d701e38ec8187eb Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 5 Oct 2018 19:59:18 +0000 Subject: [PATCH 0266/1906] UPDATE ::: Outputting prop file format in addition to json format git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30321 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: d4a0124c7c89998649ddb25ce121fe19688290ad --- src/prerna/upload/DatabaseUploader.java | 52 ++++++++++++------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/src/prerna/upload/DatabaseUploader.java b/src/prerna/upload/DatabaseUploader.java index b416b3be9..0a7c3e06e 100644 --- a/src/prerna/upload/DatabaseUploader.java +++ b/src/prerna/upload/DatabaseUploader.java @@ -637,33 +637,33 @@ public Response uploadCSVFile(MultivaluedMap form, @Context Http addEngineOwner(options.getEngineID(), options.getDbName(), "RDF", "", user); } } - - // for the above case - // the reactor does this already - try { - Date currDate = Calendar.getInstance().getTime(); - SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmmssZ"); - String dateName = sdf.format(currDate); - - String dbName = options.getDbName(); - String[] fileNames = options.getFileLocations().split(";"); - String dbLocation = SmssUtilities.getUniqueName(Utility.cleanString(dbName, true).toString(), options.getEngineID()); - for(int i = 0; i < propFileArr.length; i++) { - String fileName = new File(fileNames[i]).getName().replace(".csv", ""); - FileUtils.writeStringToFile(new File( - DIHelper.getInstance().getProperty("BaseFolder") - .concat(File.separator).concat("db").concat(File.separator) - .concat(dbLocation).concat(File.separator) - .concat(dbName.toString()).concat("_").concat(fileName) - .concat("_").concat(dateName).concat("_PROP.prop")), propFileArr[i]); - } - } catch (IOException e) { - e.printStackTrace(); - Map errorHash = new HashMap(); - errorHash.put("errorMessage", "Failure to write CSV Prop File based on user-defined metamodel."); - return Response.status(400).entity(gson.toJson(errorHash)).build(); - } } + + // reactors output a json + // this is the old prop file format + try { + Date currDate = Calendar.getInstance().getTime(); + SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmmssZ"); + String dateName = sdf.format(currDate); + + String dbName = options.getDbName(); + String[] fileNames = options.getFileLocations().split(";"); + String dbLocation = SmssUtilities.getUniqueName(Utility.cleanString(dbName, true).toString(), options.getEngineID()); + for(int i = 0; i < propFileArr.length; i++) { + String fileName = new File(fileNames[i]).getName().replace(".csv", ""); + FileUtils.writeStringToFile(new File( + DIHelper.getInstance().getProperty("BaseFolder") + .concat(File.separator).concat("db").concat(File.separator) + .concat(dbLocation).concat(File.separator) + .concat(dbName.toString()).concat("_").concat(fileName) + .concat("_").concat(dateName).concat("_PROP.prop")), propFileArr[i]); + } + } catch (IOException e) { + e.printStackTrace(); + Map errorHash = new HashMap(); + errorHash.put("errorMessage", "Failure to write CSV Prop File based on user-defined metamodel."); + return Response.status(400).entity(gson.toJson(errorHash)).build(); + } } catch (IOException e) { e.printStackTrace(); Map errorHash = new HashMap(); From f11e567f4f685a31bc6b82ebf63927146c7afac8 Mon Sep 17 00:00:00 2001 From: rramirezjimenez Date: Mon, 8 Oct 2018 14:41:39 +0000 Subject: [PATCH 0267/1906] UPDATE ::: Adding datatypes map to csv reactor import git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30327 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 0b2c80c03eb023e9b34e8161a12be2f15acfa77d --- src/prerna/upload/DatabaseUploader.java | 37 ++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/src/prerna/upload/DatabaseUploader.java b/src/prerna/upload/DatabaseUploader.java index 0a7c3e06e..eb2690017 100644 --- a/src/prerna/upload/DatabaseUploader.java +++ b/src/prerna/upload/DatabaseUploader.java @@ -31,6 +31,7 @@ import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; +import prerna.algorithm.api.SemossDataType; import prerna.auth.AuthProvider; import prerna.auth.User; import prerna.auth.utils.SecurityUpdateUtils; @@ -552,6 +553,7 @@ public Response uploadCSVFile(MultivaluedMap form, @Context Http Hashtable[] propHashArr = new Hashtable[size]; propFileArr = new String[size]; + Map[] dataTypes = new Map[size]; boolean allEmpty = true; for(int i = 0; i < size; i++) { @@ -596,6 +598,7 @@ public Response uploadCSVFile(MultivaluedMap form, @Context Http Map additionalMods = gson.fromJson(itemForFile.get("additionalInfo"), Map.class); propHashArr[i] = propWriter.getPropHash(itemForFile.get("csvStartLineCount"), itemForFile.get("csvEndLineCount"), additionalMods); propFileArr[i] = propWriter.getPropFile(); + dataTypes[i] = propWriter.getDataTypeHash(); } // if no meta data specified, send an error @@ -606,6 +609,8 @@ public Response uploadCSVFile(MultivaluedMap form, @Context Http } // set it in the options options.setMetamodelArray(propHashArr); + options.setDataTypes(dataTypes); + ////////////////////// end logic to process metamodel for csv flat table ////////////////////// // run the import @@ -706,6 +711,9 @@ private String reactorImport(ImportOptions options, HttpServletRequest request) // create new metamodels for the reactor // index based for each file List> newMetamodelList = createNewMetamodel(options); + // get property data types for each file + Map[] dataTypes = options.getDataTypes(); + // if importing multiple files add to existing String[] inputFiles = fileLocations.split(";"); @@ -742,9 +750,36 @@ private String reactorImport(ImportOptions options, HttpServletRequest request) // add metamodel grs = new GenRowStruct(); - grs.add(new NounMetadata(newMetamodelList.get(i), PixelDataType.MAP)); + Map metamodel = newMetamodelList.get(i); + grs.add(new NounMetadata(metamodel, PixelDataType.MAP)); reactor.getNounStore().addNoun(ReactorKeysEnum.METAMODEL.getKey(), grs); + // add dataTypes + grs = new GenRowStruct(); + Map dataTypesMap = dataTypes[i]; + if (dataTypesMap != null) { + Map nodeMap = (Map) metamodel.get(Constants.NODE_PROP); + // add each concept as a string + for (String concept : nodeMap.keySet()) { + dataTypesMap.put(concept, SemossDataType.STRING.toString()); + } + // check relationships in case concept does not have properties + // add missing concept as a string + if (metamodel.get(Constants.RELATION) != null) { + List> edgeList = (List>) metamodel.get(Constants.RELATION); + // process each relationship + for (Map relMap : edgeList) { + String fromConcept = (String) relMap.get(Constants.FROM_TABLE); + dataTypesMap.put(fromConcept, SemossDataType.STRING.toString()); + String toConcept = (String) relMap.get(Constants.TO_TABLE); + dataTypesMap.put(toConcept, SemossDataType.STRING.toString()); + } + } + + } + grs.add(new NounMetadata(dataTypesMap, PixelDataType.MAP)); + reactor.getNounStore().addNoun(ReactorKeysEnum.DATA_TYPE_MAP.getKey(), grs); + // add file path grs = new GenRowStruct(); grs.add(new NounMetadata(fileLocation, PixelDataType.CONST_STRING)); From 9c9f7c44777d3430f986578a0610d72729b6c3bb Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 9 Oct 2018 13:20:16 +0000 Subject: [PATCH 0268/1906] UPDATE ::: Consolidation of user admin check BUGFIX ::: Fixing error with not negating boolean where doing admin check git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30347 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: c7e6d82ff5366e44f9bdfdb3f11d617cfa27d3f1 --- .../web/services/config/ServerConfigurationResource.java | 2 +- .../semoss/web/services/local/AuthorizationResource.java | 2 +- src/prerna/semoss/web/services/local/UserResource.java | 5 +++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/prerna/semoss/web/services/config/ServerConfigurationResource.java b/src/prerna/semoss/web/services/config/ServerConfigurationResource.java index 0f71f3b2d..d7b0e9a2e 100644 --- a/src/prerna/semoss/web/services/config/ServerConfigurationResource.java +++ b/src/prerna/semoss/web/services/config/ServerConfigurationResource.java @@ -63,7 +63,7 @@ private static Map getConfig(@Context HttpServletRequest request @GET @Path("/") @Produces("application/json") - public Response getTimeoutValue(@Context HttpServletRequest request) { + public Response getServerConfig(@Context HttpServletRequest request) { return WebUtility.getResponse(getConfig(request), 200); } diff --git a/src/prerna/semoss/web/services/local/AuthorizationResource.java b/src/prerna/semoss/web/services/local/AuthorizationResource.java index 5898e72d5..eea42a7d2 100644 --- a/src/prerna/semoss/web/services/local/AuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/AuthorizationResource.java @@ -300,7 +300,7 @@ public Response registerUser(@Context HttpServletRequest request, MultivaluedMap String newUserId = form.getFirst("userId"); Boolean newUserAdmin = Boolean.parseBoolean(form.getFirst("admin")); - if(SecurityQueryUtils.userIsAdmin(user)){ + if(SecurityAdminUtils.userIsAdmin(user)){ success = SecurityUpdateUtils.registerUser(newUserId, newUserAdmin); } else { errorRet.put("error", "The user doesn't have the permissions to perform this action."); diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index 29a1c15d8..59000eb7d 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -69,6 +69,7 @@ import prerna.auth.User; import prerna.auth.utils.AbstractSecurityUtils; import prerna.auth.utils.NativeUserSecurityUtils; +import prerna.auth.utils.SecurityAdminUtils; import prerna.auth.utils.SecurityQueryUtils; import prerna.auth.utils.SecurityUpdateUtils; import prerna.io.connector.IConnectorIOp; @@ -1443,7 +1444,7 @@ public Response loginProperties(@Context HttpServletRequest request) throws IOEx if(user == null) { return WebUtility.getResponse("No user defined to access properties. Please login as an admin", 400); } - if(SecurityQueryUtils.userIsAdmin(user)){ + if(!SecurityAdminUtils.userIsAdmin(user)){ return WebUtility.getResponse("User is not an admin and does not have access. Please login as an admin", 400); } } @@ -1477,7 +1478,7 @@ public synchronized Response modifyLoginProperties(@PathParam("provider") String if(user == null) { return WebUtility.getResponse("No user defined to access properties. Please login as an admin", 400); } - if(SecurityQueryUtils.userIsAdmin(user)){ + if(SecurityAdminUtils.userIsAdmin(user)){ return WebUtility.getResponse("User is not an admin and does not have access. Please login as an admin", 400); } } From 33cd62ba1bc44b482266b21f35259b83e3567058 Mon Sep 17 00:00:00 2001 From: tbanach Date: Tue, 9 Oct 2018 15:10:15 +0000 Subject: [PATCH 0269/1906] UPDATE ::: Need this for compilation given changes to smss web watcher. Will need to take out load from here git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30350 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: e3bb5551615c89e6e8a1d98f57b29085db15faab --- src/prerna/web/conf/DBLoader.java | 35 +++++++++++++++++++++++++-- src/prerna/web/conf/UserDBLoader.java | 4 +++ 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/prerna/web/conf/DBLoader.java b/src/prerna/web/conf/DBLoader.java index 96d5c4c5d..abdf0429c 100644 --- a/src/prerna/web/conf/DBLoader.java +++ b/src/prerna/web/conf/DBLoader.java @@ -27,7 +27,9 @@ *******************************************************************************/ package prerna.web.conf; +import java.io.IOException; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.Vector; @@ -40,6 +42,10 @@ import com.ibm.icu.util.StringTokenizer; +import prerna.auth.utils.SecurityQueryUtils; +import prerna.cluster.util.AZClient; +import prerna.cluster.util.ClusterUtil; +import prerna.cluster.util.PullAppRunner; import prerna.engine.api.IEngine; import prerna.forms.AbstractFormBuilder; import prerna.nameserver.utility.MasterDatabaseUtility; @@ -51,6 +57,7 @@ import prerna.util.AbstractFileWatcher; import prerna.util.Constants; import prerna.util.DIHelper; +import prerna.util.SMSSWebWatcher; import prerna.util.Utility; import prerna.util.insight.InsightUtility; @@ -92,9 +99,9 @@ public void contextInitialized(ServletContextEvent arg0) { //Load empty engine list into DIHelper, then load engines from db folder System.out.println("Loading engines..."); String engines = ""; - DIHelper.getInstance().setLocalProperty(Constants.ENGINES, engines); + DIHelper.getInstance().setLocalProperty(Constants.ENGINES, engines); loadEngines(); - + // //Just load R right away to avoid synchronization issues // try { // RJavaTranslatorFactory.initRConnection(); @@ -107,6 +114,27 @@ public void contextInitialized(ServletContextEvent arg0) { ImageCaptureReactor.setContextPath(contextPath); } + // TODO >>>timb: is this right? + // Need to pull apps when in cluster + // TODO >>>timb: this will need to be removed potentially when we move to rest + private void pullEngines(String folder) { + List> retList = SecurityQueryUtils.getAllDatabaseList(); + for (Map appData : retList) { + String appId = appData.get("app_id").toString(); + try { + AZClient.getInstance().pullApp(appId); + String alias = MasterDatabaseUtility.getEngineAliasForId(appId); + SMSSWebWatcher.catalogDB(alias + "__" + appId + ".smss", folder); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + public void loadEngines() { String watcherStr = DIHelper.getInstance().getProperty(Constants.ENGINE_WEB_WATCHER); StringTokenizer watchers = new StringTokenizer(watcherStr, ";"); @@ -122,6 +150,9 @@ public void loadEngines() { watcherInstance.setFolderToWatch(folder); watcherInstance.setExtension(ext); watcherInstance.init(); + if (ClusterUtil.IS_CLUSTER && watcherClass.equals("prerna.util.SMSSWebWatcher")) { + pullEngines(folder); + } synchronized(monitor) { Thread thread = new Thread(watcherInstance); diff --git a/src/prerna/web/conf/UserDBLoader.java b/src/prerna/web/conf/UserDBLoader.java index 932c1de83..2582a83a3 100644 --- a/src/prerna/web/conf/UserDBLoader.java +++ b/src/prerna/web/conf/UserDBLoader.java @@ -55,6 +55,8 @@ public void contextInitialized(ServletContextEvent arg0) { } + // TODO >>>timb: need to pull dbs in here for now until we get to lazy load + // TODO >>>timb: or in user resource pull on login private void publish() { Map envMap = System.getenv(); @@ -63,6 +65,8 @@ private void publish() { // we are in business ZKClient client = ZKClient.getInstance(); + // TODO >>>timb: this needs to be done with check on the env var + // client.publishContainer(System.getenv("hostname") + "@" + client.host); client.publishContainer(client.host); } // else From 3d412d7382b1ab68f92393415609efcd1f918e13 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 9 Oct 2018 17:58:27 +0000 Subject: [PATCH 0270/1906] UPDATE ::: Ignoring bad input in social properties file git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30358 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: e0875f62eeedcbfbeb594817523b61d44d440f84 --- src/prerna/semoss/web/services/local/UserResource.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index 59000eb7d..cbcdb1f90 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -1455,6 +1455,11 @@ public Response loginProperties(@Context HttpServletRequest request) throws IOEx Set propSet = socialData.stringPropertyNames(); for(String prop : propSet) { + if(!prop.contains("_")) { + // bad format + // ignore + continue; + } String[] split = prop.toString().split("_", 2); String type = split[0]; String type_key = split[1]; From 353703d55db3ef1eefc9113b06ee570d094cf280 Mon Sep 17 00:00:00 2001 From: tbanach Date: Tue, 9 Oct 2018 18:08:32 +0000 Subject: [PATCH 0271/1906] UPDATE ::: Adding in rest endpoint to pull app; removing load on startup git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30360 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: cad3be3db3cf52dca536b77664f04e1721b921eb --- .../semoss/web/services/local/NameServer.java | 18 ++++++++++ src/prerna/web/conf/DBLoader.java | 33 +------------------ 2 files changed, 19 insertions(+), 32 deletions(-) diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index 5e56c8f59..054bd2bc9 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -77,6 +77,8 @@ import prerna.auth.User; import prerna.auth.utils.AbstractSecurityUtils; import prerna.auth.utils.SecurityQueryUtils; +import prerna.cluster.util.AZClient; +import prerna.cluster.util.ClusterUtil; import prerna.engine.api.IEngine; import prerna.engine.impl.rdf.RemoteSemossSesameEngine; import prerna.insights.admin.DBAdminResource; @@ -292,11 +294,27 @@ public Response getAppImage(@Context HttpServletRequest request, @QueryParam("ap @GET @Path("/insightImage") @Produces({"image/jpeg", "image/png"}) + // TODO >>>timb: need to add rest enpoint to pull before anything else public Response getInsightImage(@Context HttpServletRequest request, @QueryParam("app") String app, @QueryParam("rdbmsId") String insightId, @QueryParam("params") String params) { AppResource r = new AppResource(); return r.downloadInsightImage(request, app, insightId, params); } + @GET + @Path("/pullApp") + @Produces("application/json") + public Response pullApp(@Context HttpServletRequest request, @QueryParam("app") String app) throws IOException, InterruptedException { + boolean pulled = false; + Map returnMap = new HashMap<>(); + if (ClusterUtil.IS_CLUSTER) { + AZClient.getInstance().pullApp(app); + pulled = true; + } + returnMap.put("pulled", pulled); + returnMap.put("success", true); + return WebUtility.getResponse(returnMap, 200); + } + /////////////////////////////////////////////// /////////////////////////////////////////////// /////////////////////////////////////////////// diff --git a/src/prerna/web/conf/DBLoader.java b/src/prerna/web/conf/DBLoader.java index abdf0429c..c01669e90 100644 --- a/src/prerna/web/conf/DBLoader.java +++ b/src/prerna/web/conf/DBLoader.java @@ -27,9 +27,7 @@ *******************************************************************************/ package prerna.web.conf; -import java.io.IOException; import java.util.List; -import java.util.Map; import java.util.Set; import java.util.Vector; @@ -42,10 +40,6 @@ import com.ibm.icu.util.StringTokenizer; -import prerna.auth.utils.SecurityQueryUtils; -import prerna.cluster.util.AZClient; -import prerna.cluster.util.ClusterUtil; -import prerna.cluster.util.PullAppRunner; import prerna.engine.api.IEngine; import prerna.forms.AbstractFormBuilder; import prerna.nameserver.utility.MasterDatabaseUtility; @@ -57,7 +51,6 @@ import prerna.util.AbstractFileWatcher; import prerna.util.Constants; import prerna.util.DIHelper; -import prerna.util.SMSSWebWatcher; import prerna.util.Utility; import prerna.util.insight.InsightUtility; @@ -113,28 +106,7 @@ public void contextInitialized(ServletContextEvent arg0) { // important for taking the image with security ImageCaptureReactor.setContextPath(contextPath); } - - // TODO >>>timb: is this right? - // Need to pull apps when in cluster - // TODO >>>timb: this will need to be removed potentially when we move to rest - private void pullEngines(String folder) { - List> retList = SecurityQueryUtils.getAllDatabaseList(); - for (Map appData : retList) { - String appId = appData.get("app_id").toString(); - try { - AZClient.getInstance().pullApp(appId); - String alias = MasterDatabaseUtility.getEngineAliasForId(appId); - SMSSWebWatcher.catalogDB(alias + "__" + appId + ".smss", folder); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - } - } - + public void loadEngines() { String watcherStr = DIHelper.getInstance().getProperty(Constants.ENGINE_WEB_WATCHER); StringTokenizer watchers = new StringTokenizer(watcherStr, ";"); @@ -150,9 +122,6 @@ public void loadEngines() { watcherInstance.setFolderToWatch(folder); watcherInstance.setExtension(ext); watcherInstance.init(); - if (ClusterUtil.IS_CLUSTER && watcherClass.equals("prerna.util.SMSSWebWatcher")) { - pullEngines(folder); - } synchronized(monitor) { Thread thread = new Thread(watcherInstance); From 1a46eec0d9a053af4bee40d081bd0ee0fdfee2df Mon Sep 17 00:00:00 2001 From: tbanach Date: Tue, 9 Oct 2018 19:32:39 +0000 Subject: [PATCH 0272/1906] UPDATE ::: Monolith call to pull app git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30361 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: d77df7e5cd2c3c94487cc66526878fb50dd8aa18 --- .../semoss/web/services/local/NameServer.java | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index 054bd2bc9..e6ee4be9a 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -300,18 +300,28 @@ public Response getInsightImage(@Context HttpServletRequest request, @QueryParam return r.downloadInsightImage(request, app, insightId, params); } - @GET + @POST @Path("/pullApp") @Produces("application/json") - public Response pullApp(@Context HttpServletRequest request, @QueryParam("app") String app) throws IOException, InterruptedException { - boolean pulled = false; + public Response pullApp(@Context HttpServletRequest request, @QueryParam("app") String app) { Map returnMap = new HashMap<>(); if (ClusterUtil.IS_CLUSTER) { - AZClient.getInstance().pullApp(app); - pulled = true; + try { + AZClient.getInstance().pullApp(app); + returnMap.put("pulled", true); + returnMap.put("success", true); + returnMap.put("message", "Successfully pulled app"); + return WebUtility.getResponse(returnMap, 200); + } catch (IOException | InterruptedException e) { + returnMap.put("pulled", false); + returnMap.put("success", false); + returnMap.put("message", "Failed to load app"); + return WebUtility.getResponse(returnMap, 400); + } } - returnMap.put("pulled", pulled); + returnMap.put("pulled", false); returnMap.put("success", true); + returnMap.put("message", "App is local"); return WebUtility.getResponse(returnMap, 200); } From e7971e60abb3a5d421351c6941fd3144381778fd Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 10 Oct 2018 05:18:49 +0000 Subject: [PATCH 0273/1906] UPDATE ::: Making keys consistent for retrieving db schema and uploading a schema as a metamodel git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30372 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: b63e5b7c1d53c751f6cbee9fccd55d1f85865ca6 --- src/prerna/upload/DatabaseUploader.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/prerna/upload/DatabaseUploader.java b/src/prerna/upload/DatabaseUploader.java index eb2690017..c7f85d093 100644 --- a/src/prerna/upload/DatabaseUploader.java +++ b/src/prerna/upload/DatabaseUploader.java @@ -66,6 +66,7 @@ import prerna.sablecc2.reactor.app.upload.rdbms.csv.RdbmsCsvUploadReactor; import prerna.sablecc2.reactor.app.upload.rdbms.csv.RdbmsExternalUploadReactor; import prerna.sablecc2.reactor.app.upload.rdf.RdfCsvUploadReactor; +import prerna.sablecc2.reactor.qs.source.ExternalJdbcSchemaReactor; import prerna.ui.components.ImportDataProcessor; import prerna.util.Constants; import prerna.util.DIHelper; @@ -1096,7 +1097,7 @@ public Response connectExistingRDBMS(@Context HttpServletRequest request, Multiv } nodesAndProps.put(nodeHash.get("node") + "." + nodeHash.get("primaryKey"), props); // Table1.idTable1 -> [prop1, prop2, ...] } - metamodel.put(Constants.NODE_PROP, nodesAndProps); + metamodel.put(ExternalJdbcSchemaReactor.TABLES_KEY, nodesAndProps); for(Object o: relationships) { HashMap relationship = gson.fromJson(gson.toJson(o), new TypeToken>() {}.getType()); String fromTable = relationship.get("sub"); @@ -1108,7 +1109,7 @@ public Response connectExistingRDBMS(@Context HttpServletRequest request, Multiv relMap.put(Constants.TO_TABLE, toTable); nodeRelationships.add(relMap); } - metamodel.put(Constants.RELATION, nodeRelationships); + metamodel.put(ExternalJdbcSchemaReactor.RELATIONS_KEY, nodeRelationships); HashMap databaseOptions = gson.fromJson(gson.toJson(details.get("databaseOptions")), new TypeToken>() {}.getType()); HashMap options = gson.fromJson(gson.toJson(details.get("options")), new TypeToken>() {}.getType()); From c13604d6618235b348b1358d0cdd6cd8b489f2b9 Mon Sep 17 00:00:00 2001 From: tbanach Date: Wed, 10 Oct 2018 21:12:04 +0000 Subject: [PATCH 0274/1906] UPDATE ::: removing pull app rest endpoint git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30385 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: c59076761474e1f2b82aa7070c9747086254f72e --- .../semoss/web/services/local/NameServer.java | 27 ------------------- 1 file changed, 27 deletions(-) diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index e6ee4be9a..8fef54d13 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -77,8 +77,6 @@ import prerna.auth.User; import prerna.auth.utils.AbstractSecurityUtils; import prerna.auth.utils.SecurityQueryUtils; -import prerna.cluster.util.AZClient; -import prerna.cluster.util.ClusterUtil; import prerna.engine.api.IEngine; import prerna.engine.impl.rdf.RemoteSemossSesameEngine; import prerna.insights.admin.DBAdminResource; @@ -299,31 +297,6 @@ public Response getInsightImage(@Context HttpServletRequest request, @QueryParam AppResource r = new AppResource(); return r.downloadInsightImage(request, app, insightId, params); } - - @POST - @Path("/pullApp") - @Produces("application/json") - public Response pullApp(@Context HttpServletRequest request, @QueryParam("app") String app) { - Map returnMap = new HashMap<>(); - if (ClusterUtil.IS_CLUSTER) { - try { - AZClient.getInstance().pullApp(app); - returnMap.put("pulled", true); - returnMap.put("success", true); - returnMap.put("message", "Successfully pulled app"); - return WebUtility.getResponse(returnMap, 200); - } catch (IOException | InterruptedException e) { - returnMap.put("pulled", false); - returnMap.put("success", false); - returnMap.put("message", "Failed to load app"); - return WebUtility.getResponse(returnMap, 400); - } - } - returnMap.put("pulled", false); - returnMap.put("success", true); - returnMap.put("message", "App is local"); - return WebUtility.getResponse(returnMap, 200); - } /////////////////////////////////////////////// /////////////////////////////////////////////// From bdb81c7cb8605bdd282105fa26246bfc8c7d42c8 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 11 Oct 2018 15:57:33 +0000 Subject: [PATCH 0275/1906] UPDATE ::: Adding back the whoami method to test waffle git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30398 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 60d9d53e23dd86e106add4ee6c41535e9d4a073e --- .../web/services/local/UserResource.java | 26 ++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index cbcdb1f90..b50c2a568 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -33,6 +33,7 @@ import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; +import java.security.Principal; import java.util.HashMap; import java.util.Hashtable; import java.util.List; @@ -61,6 +62,8 @@ import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; +import com.sun.jna.platform.win32.Secur32; +import com.sun.jna.platform.win32.Secur32Util; import jodd.util.URLDecoder; import prerna.auth.AccessToken; @@ -70,7 +73,6 @@ import prerna.auth.utils.AbstractSecurityUtils; import prerna.auth.utils.NativeUserSecurityUtils; import prerna.auth.utils.SecurityAdminUtils; -import prerna.auth.utils.SecurityQueryUtils; import prerna.auth.utils.SecurityUpdateUtils; import prerna.io.connector.IConnectorIOp; import prerna.io.connector.google.GoogleEntityResolver; @@ -86,6 +88,7 @@ import prerna.util.Constants; import prerna.util.DIHelper; import prerna.web.services.util.WebUtility; +import waffle.servlet.WindowsPrincipal; @Path("/auth") public class UserResource { @@ -1517,4 +1520,25 @@ public synchronized Response modifyLoginProperties(@PathParam("provider") String return WebUtility.getResponse(true, 200); } + + + @GET + @Produces("text/plain") + @Path("/whoami") + public Response show(@Context HttpServletRequest request, @Context HttpServletResponse response) { + HttpSession session = request.getSession(); + System.err.println(" came into user resource"); + Principal principal = request.getUserPrincipal(); + String output = ""; + output = request.getRemoteUser() + "\n" + request.getUserPrincipal().getName() + "\n"; + output = output + "Session " + request.getSession().getId() + "\n"; + output = output + "Impersonation " + Secur32Util.getUserNameEx(Secur32.EXTENDED_NAME_FORMAT.NameSamCompatible); + if (principal instanceof WindowsPrincipal) { + WindowsPrincipal windowsPrincipal = (WindowsPrincipal) principal; + for(waffle.windows.auth.WindowsAccount account : windowsPrincipal.getGroups().values()) { + output = output + account.getFqn() + account.getSidString() + "\n"; + } + } + return WebUtility.getResponse(output, 200); + } } From 9b555ef17a797b3fcafaa520c15e4680ee98452e Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 11 Oct 2018 16:09:27 +0000 Subject: [PATCH 0276/1906] UPDATE ::: Outputting more information to test ldap waffle git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30399 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 0aa58b5a7f8db350f2b06301cb081fba39d33db9 --- .../web/services/local/UserResource.java | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index b50c2a568..e1cdd30d3 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -42,6 +42,7 @@ import java.util.Set; import java.util.TreeMap; import java.util.UUID; +import java.util.Vector; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -62,8 +63,6 @@ import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; -import com.sun.jna.platform.win32.Secur32; -import com.sun.jna.platform.win32.Secur32Util; import jodd.util.URLDecoder; import prerna.auth.AccessToken; @@ -1526,18 +1525,21 @@ public synchronized Response modifyLoginProperties(@PathParam("provider") String @Produces("text/plain") @Path("/whoami") public Response show(@Context HttpServletRequest request, @Context HttpServletResponse response) { - HttpSession session = request.getSession(); - System.err.println(" came into user resource"); Principal principal = request.getUserPrincipal(); - String output = ""; - output = request.getRemoteUser() + "\n" + request.getUserPrincipal().getName() + "\n"; - output = output + "Session " + request.getSession().getId() + "\n"; - output = output + "Impersonation " + Secur32Util.getUserNameEx(Secur32.EXTENDED_NAME_FORMAT.NameSamCompatible); + Map output = new HashMap(); + output.put("name", principal.getName()); if (principal instanceof WindowsPrincipal) { WindowsPrincipal windowsPrincipal = (WindowsPrincipal) principal; + List> gropus = new Vector>(); for(waffle.windows.auth.WindowsAccount account : windowsPrincipal.getGroups().values()) { - output = output + account.getFqn() + account.getSidString() + "\n"; + Map m = new HashMap(); + m.put("name", account.getName()); + m.put("domain", account.getDomain()); + m.put("fqn", account.getFqn()); + m.put("sid", account.getSidString()); + gropus.add(m); } + output.put("groups", gropus); } return WebUtility.getResponse(output, 200); } From e7a6f8b48327189361051d8762d89989f6dfdec7 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 11 Oct 2018 16:17:38 +0000 Subject: [PATCH 0277/1906] UPDATE ::: Fixing jar issues + excluding portions where versions are duplicated git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30400 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: cb6945c537462bdd0cc0d6c406027dedd75f98e8 --- pom.xml | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 3f96eb948..f4cd46fba 100644 --- a/pom.xml +++ b/pom.xml @@ -2464,11 +2464,6 @@ 0.10.1.0 - - org.mariadb.jdbc - mariadb-java-client - 1.1.7 - com.h2database h2 @@ -2826,6 +2821,16 @@ org.seleniumhq.selenium selenium-java 3.4.0 + + + net.java.dev.jna + jna + + + net.java.dev.jna + jna-platform + + net.lingala.zip4j @@ -2836,6 +2841,16 @@ org.apache.jclouds jclouds-all 2.1.0 + + + net.java.dev.jna + jna + + + net.java.dev.jna + jna-platform + + io.minio From 049220828cc9e789e575958c5366963d7960ff6a Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 11 Oct 2018 17:20:08 +0000 Subject: [PATCH 0278/1906] UPDATE ::: Adding waffle filter to pickup windows authentication git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30405 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 11622905b785540aec5dc0630dbf4039674e69d5 --- WebContent/WEB-INF/web.xml | 124 ++++++++++++++------------ src/prerna/web/conf/WaffleFilter.java | 84 +++++++++++++++++ 2 files changed, 151 insertions(+), 57 deletions(-) create mode 100644 src/prerna/web/conf/WaffleFilter.java diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index a83ce31ae..7f0904b7d 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -26,6 +26,70 @@ CACFilter /api/* + + + + + NoUserInSessionFilter prerna.web.conf.NoUserInSessionFilter @@ -55,60 +119,6 @@ --> - - - MainApplication @@ -146,12 +156,12 @@ security-enabled - false + true Location to store uploaded file file-upload - C:\\workspace\\Semoss_Dev\\ + C:\\workspace\\Semoss\\ Temporary - Location to store uploaded file @@ -161,7 +171,7 @@ The place where the core RDF Map gets picked from RDF-MAP - C:\\workspace\\Semoss_Dev\\RDF_Map.prop + C:\\workspace\\Semoss\\RDF_Map.prop diff --git a/src/prerna/web/conf/WaffleFilter.java b/src/prerna/web/conf/WaffleFilter.java new file mode 100644 index 000000000..107293e3f --- /dev/null +++ b/src/prerna/web/conf/WaffleFilter.java @@ -0,0 +1,84 @@ +package prerna.web.conf; + +import java.io.IOException; +import java.security.Principal; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +import prerna.auth.AccessToken; +import prerna.auth.AuthProvider; +import prerna.auth.User; +import prerna.auth.utils.SecurityUpdateUtils; +import prerna.util.Constants; + +public class WaffleFilter implements Filter { + + private static final String AUTO_ADD = "autoAdd"; + private static Boolean autoAdd = null; + + private FilterConfig filterConfig; + + @Override + public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { + setInitParams(arg0); + + HttpSession session = ((HttpServletRequest)arg0).getSession(true); + + Principal principal = ((HttpServletRequest) arg0).getUserPrincipal(); + String id = principal.getName(); + String name = id.substring(id.lastIndexOf('\\')+1); + + AccessToken token = null; + User user = (User) session.getAttribute(Constants.SESSION_USER); + if(user == null) { + user = new User(); + + token = new AccessToken(); + token.setProvider(AuthProvider.WINDOWS_USER); + + token.setId(id); + token.setName(name); + + // add the user if they do not exist + if(WaffleFilter.autoAdd) { + SecurityUpdateUtils.addOAuthUser(token); + } + + user.setAccessToken(token); + session.setAttribute(Constants.SESSION_USER, user); + } + + arg2.doFilter(arg0, arg1); + } + + @Override + public void destroy() { + // TODO Auto-generated method stub + + } + + @Override + public void init(FilterConfig arg0) throws ServletException { + this.filterConfig = arg0; + } + + private void setInitParams(ServletRequest arg0) { + if(WaffleFilter.autoAdd == null) { + String autoAddStr = this.filterConfig.getInitParameter(AUTO_ADD); + if(autoAddStr != null) { + WaffleFilter.autoAdd = Boolean.parseBoolean(autoAddStr); + } else { + // Default value is true + WaffleFilter.autoAdd = true; + } + } + } + +} From f9de27ac0e5f3af4d7dff98c7fa8db3bb3183f98 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 11 Oct 2018 17:42:21 +0000 Subject: [PATCH 0279/1906] UPDATE ::: Fixing to be original paths to not have conflicts git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30406 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 2c2b71787f4d570c7e6e22222f675009ab10858b --- WebContent/WEB-INF/web.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index 7f0904b7d..601edb71d 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -161,7 +161,7 @@ Location to store uploaded file file-upload - C:\\workspace\\Semoss\\ + C:\\workspace\\Semoss_Dev\\ Temporary - Location to store uploaded file @@ -171,7 +171,7 @@ The place where the core RDF Map gets picked from RDF-MAP - C:\\workspace\\Semoss\\RDF_Map.prop + C:\\workspace\\Semoss_Dev\\RDF_Map.prop From c1aeb4249e9ac421c7341ffec02acfb8130d5f1f Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 11 Oct 2018 18:11:37 +0000 Subject: [PATCH 0280/1906] BUGFIX ::: Fixing error with boolean check in modify login properties git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30407 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 720bdc951015ca2cdc453bf462d83f633baf1690 --- src/prerna/semoss/web/services/local/UserResource.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index e1cdd30d3..5cb0b72dc 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -1485,7 +1485,7 @@ public synchronized Response modifyLoginProperties(@PathParam("provider") String if(user == null) { return WebUtility.getResponse("No user defined to access properties. Please login as an admin", 400); } - if(SecurityAdminUtils.userIsAdmin(user)){ + if(!SecurityAdminUtils.userIsAdmin(user)){ return WebUtility.getResponse("User is not an admin and does not have access. Please login as an admin", 400); } } @@ -1522,7 +1522,7 @@ public synchronized Response modifyLoginProperties(@PathParam("provider") String @GET - @Produces("text/plain") + @Produces("application/json") @Path("/whoami") public Response show(@Context HttpServletRequest request, @Context HttpServletResponse response) { Principal principal = request.getUserPrincipal(); From d58454747ee6a126b2817c33da72a35b110f6a27 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 11 Oct 2018 18:46:28 +0000 Subject: [PATCH 0281/1906] BUGFIX ::: Updating the social properties map after updating the social data file git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30408 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 089472720e9411c357dbebda664f3a7934ec34cb --- src/prerna/semoss/web/services/local/UserResource.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index 5cb0b72dc..f940392b5 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -124,6 +124,10 @@ public class UserResource { // } static { + loadSocialProperties(); + } + + private static void loadSocialProperties() { FileInputStream fis = null; File f = new File(DIHelper.getInstance().getProperty("SOCIAL")); try { @@ -1510,6 +1514,7 @@ public synchronized Response modifyLoginProperties(@PathParam("provider") String try { config.save(); + loadSocialProperties(); } catch (ConfigurationException e1) { e1.printStackTrace(); Hashtable errorRet = new Hashtable(); From d2e6bc4d55e6ba8df9122b46e71b72c2f2b54dfa Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 11 Oct 2018 20:17:03 +0000 Subject: [PATCH 0282/1906] UPDATE ::: Removing improper null check git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30414 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: d993fb25c1e974fb8a211008af3b9b6beffabc01 --- src/prerna/semoss/web/services/local/UserResource.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index f940392b5..66e0c5dfc 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -131,7 +131,7 @@ private static void loadSocialProperties() { FileInputStream fis = null; File f = new File(DIHelper.getInstance().getProperty("SOCIAL")); try { - if(socialData == null && f.exists()) { + if(f.exists()) { socialData = new Properties(); fis = new FileInputStream(f); socialData.load(fis); From 0bb5a585796c02f6526d2400dbae535590808c91 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 11 Oct 2018 21:39:20 +0000 Subject: [PATCH 0283/1906] UPDATE ::: Improving code in waffle filter UPDATE ::: Fixing error with impersonate on waffle web.xml filter causing issues the first time someone tries to logon git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30420 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: ab7c8d51d6a729b103a0d5efba230e7f28ed8760 --- WebContent/WEB-INF/web.xml | 4 ++-- src/prerna/web/conf/WaffleFilter.java | 6 +----- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index 601edb71d..2173ee08e 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -46,7 +46,7 @@ impersonate - true + false securityFilterProviders @@ -156,7 +156,7 @@ security-enabled - true + false Location to store uploaded file diff --git a/src/prerna/web/conf/WaffleFilter.java b/src/prerna/web/conf/WaffleFilter.java index 107293e3f..2240cb7a8 100644 --- a/src/prerna/web/conf/WaffleFilter.java +++ b/src/prerna/web/conf/WaffleFilter.java @@ -30,22 +30,18 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 setInitParams(arg0); HttpSession session = ((HttpServletRequest)arg0).getSession(true); - Principal principal = ((HttpServletRequest) arg0).getUserPrincipal(); String id = principal.getName(); String name = id.substring(id.lastIndexOf('\\')+1); - AccessToken token = null; User user = (User) session.getAttribute(Constants.SESSION_USER); if(user == null) { user = new User(); - token = new AccessToken(); + AccessToken token = new AccessToken(); token.setProvider(AuthProvider.WINDOWS_USER); - token.setId(id); token.setName(name); - // add the user if they do not exist if(WaffleFilter.autoAdd) { SecurityUpdateUtils.addOAuthUser(token); From 80146d6c90e607935eb67d136ea6301e060cb45e Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 16 Oct 2018 14:41:39 +0000 Subject: [PATCH 0284/1906] UPDATE ::: Searching for insight image if user puts own image.* file git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30476 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 1dcd0e4cacb443414934a2548b178939f10cbd28 --- .../web/services/local/AppResource.java | 20 +++++++++---------- .../semoss/web/services/local/NameServer.java | 4 ++-- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/prerna/semoss/web/services/local/AppResource.java b/src/prerna/semoss/web/services/local/AppResource.java index 2a951afb9..0f6b09f8c 100644 --- a/src/prerna/semoss/web/services/local/AppResource.java +++ b/src/prerna/semoss/web/services/local/AppResource.java @@ -77,7 +77,7 @@ private IEngine getApp(User user, String appId) throws IllegalAccessException { @GET @Path("/appImage/download") - @Produces(MediaType.APPLICATION_OCTET_STREAM) + @Produces({MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_SVG_XML}) public Response downloadAppImage(@Context HttpServletRequest request, @PathParam("appName") String app) { File exportFile = getAppImageFile(app); if(exportFile != null && exportFile.exists()) { @@ -127,7 +127,7 @@ protected File getAppImageFile(String app) { @GET @Path("/insightImage/download") - @Produces(MediaType.APPLICATION_OCTET_STREAM) + @Produces({MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_SVG_XML}) public Response downloadInsightImage(@Context HttpServletRequest request, @PathParam("appName") String app, @QueryParam("rdbmsId") String id, @QueryParam("params") String params) { boolean securityEnabled = Boolean.parseBoolean((String)DIHelper.getInstance().getLocalProp(Constants.SECURITY_ENABLED)); String sessionId = null; @@ -158,7 +158,7 @@ private File getInsightImageFile(String app, String id, String feUrl, String par app = prop.getProperty(Constants.ENGINE_ALIAS); String baseFolder = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER); - String fileLocation = ""; + String fileLocation = baseFolder + DIR_SEPARATOR + "db" + DIR_SEPARATOR + SmssUtilities.getUniqueName(app, appId) + DIR_SEPARATOR + "version"; if(params != null && !params.isEmpty() && !params.equals("undefined")) { String encodedParams = Utility.encodeURIComponent(params); fileLocation = baseFolder + @@ -167,18 +167,16 @@ private File getInsightImageFile(String app, String id, String feUrl, String par DIR_SEPARATOR + "version" + DIR_SEPARATOR + id + DIR_SEPARATOR + "params" + - DIR_SEPARATOR + encodedParams + - DIR_SEPARATOR + "image.png"; + DIR_SEPARATOR + encodedParams; } else { fileLocation = baseFolder + DIR_SEPARATOR + "db" + DIR_SEPARATOR + SmssUtilities.getUniqueName(app, appId) + DIR_SEPARATOR + "version" + - DIR_SEPARATOR + id + - DIR_SEPARATOR + "image.png"; - } - File f = new File(fileLocation); - if(f.exists()) { + DIR_SEPARATOR + id; + } + File f = findImageFile(fileLocation); + if(f != null && f.exists()) { return f; } else { // try making the image @@ -194,7 +192,7 @@ private File getInsightImageFile(String app, String id, String feUrl, String par return f; } } - if(f.exists()) { + if(f != null && f.exists()) { return f; } else { // return stock image diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index 8fef54d13..d66b5a92e 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -283,7 +283,7 @@ public Response downloadFile(@QueryParam("insightId") String insightId, @QueryPa @GET @Path("/appImage") - @Produces({"image/jpeg", "image/png"}) + @Produces({MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_SVG_XML}) public Response getAppImage(@Context HttpServletRequest request, @QueryParam("app") String app) { AppResource r = new AppResource(); return r.downloadAppImage(request, app); @@ -291,7 +291,7 @@ public Response getAppImage(@Context HttpServletRequest request, @QueryParam("ap @GET @Path("/insightImage") - @Produces({"image/jpeg", "image/png"}) + @Produces({MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_SVG_XML}) // TODO >>>timb: need to add rest enpoint to pull before anything else public Response getInsightImage(@Context HttpServletRequest request, @QueryParam("app") String app, @QueryParam("rdbmsId") String insightId, @QueryParam("params") String params) { AppResource r = new AppResource(); From 8864867d38bcc78859b610b5dec5e3d57cbd7698 Mon Sep 17 00:00:00 2001 From: tbanach Date: Wed, 17 Oct 2018 02:18:16 +0000 Subject: [PATCH 0285/1906] UPDATE ::: Don't attempt image capture on clustered deployments. Instead, this can be done manually on settings tab if needed git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30511 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 53bcd8cb42202fd030594292a5e1076b71cb54a5 --- .../web/services/local/AppResource.java | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/prerna/semoss/web/services/local/AppResource.java b/src/prerna/semoss/web/services/local/AppResource.java index 0f6b09f8c..895f2f93a 100644 --- a/src/prerna/semoss/web/services/local/AppResource.java +++ b/src/prerna/semoss/web/services/local/AppResource.java @@ -27,6 +27,7 @@ import prerna.auth.User; import prerna.auth.utils.AbstractSecurityUtils; import prerna.auth.utils.SecurityQueryUtils; +import prerna.cluster.util.ClusterUtil; import prerna.engine.api.IEngine; import prerna.engine.impl.SmssUtilities; import prerna.nameserver.utility.MasterDatabaseUtility; @@ -180,16 +181,18 @@ private File getInsightImageFile(String app, String id, String feUrl, String par return f; } else { // try making the image - if(feUrl != null) { - try { - ImageCaptureReactor.runImageCapture(feUrl, appId, id, params, sessionId); - } - catch(Exception | NoSuchMethodError er) { - //Image Capture will not run. No image exists nor will be made. The exception kills the rest. - // return stock image - er.printStackTrace(); - f = AbstractSecurityUtils.getStockImage(appId, id); - return f; + if (!ClusterUtil.IS_CLUSTER) { + if(feUrl != null) { + try { + ImageCaptureReactor.runImageCapture(feUrl, appId, id, params, sessionId); + } + catch(Exception | NoSuchMethodError er) { + //Image Capture will not run. No image exists nor will be made. The exception kills the rest. + // return stock image + er.printStackTrace(); + f = AbstractSecurityUtils.getStockImage(appId, id); + return f; + } } } if(f != null && f.exists()) { From 900532251b25db42025abe299dea400caa12e8e6 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 17 Oct 2018 12:35:29 +0000 Subject: [PATCH 0286/1906] BUGFIX ::: Fixing error on BE with checking if engine name exists for the user by actually passing the user filters BUGFIX ::: Performing another scan on the insight directory after successfully running the image capture to see if an image file is there UPDATE ::: Looping through all the users to determine if there is an admin to set if an engine should be public or not UPDATE ::: Refactoring code around engine owner setting the database as public or not UPDATE ::: AppMeta tries tries to find use specific alias when a engine name instead of id is passed git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30514 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 66537d61cf1bdddd697b9ae5cc1da81686e14290 --- .../web/services/local/AppResource.java | 16 +-- .../services/local/AuthorizationResource.java | 128 ++++++++++-------- 2 files changed, 76 insertions(+), 68 deletions(-) diff --git a/src/prerna/semoss/web/services/local/AppResource.java b/src/prerna/semoss/web/services/local/AppResource.java index 895f2f93a..04d12f7df 100644 --- a/src/prerna/semoss/web/services/local/AppResource.java +++ b/src/prerna/semoss/web/services/local/AppResource.java @@ -162,20 +162,13 @@ private File getInsightImageFile(String app, String id, String feUrl, String par String fileLocation = baseFolder + DIR_SEPARATOR + "db" + DIR_SEPARATOR + SmssUtilities.getUniqueName(app, appId) + DIR_SEPARATOR + "version"; if(params != null && !params.isEmpty() && !params.equals("undefined")) { String encodedParams = Utility.encodeURIComponent(params); - fileLocation = baseFolder + - DIR_SEPARATOR + "db" + - DIR_SEPARATOR + SmssUtilities.getUniqueName(app, appId) + - DIR_SEPARATOR + "version" + + fileLocation = fileLocation + DIR_SEPARATOR + id + DIR_SEPARATOR + "params" + DIR_SEPARATOR + encodedParams; } else { - fileLocation = baseFolder + - DIR_SEPARATOR + "db" + - DIR_SEPARATOR + SmssUtilities.getUniqueName(app, appId) + - DIR_SEPARATOR + "version" + - DIR_SEPARATOR + id; - } + fileLocation = fileLocation + DIR_SEPARATOR + id; + } File f = findImageFile(fileLocation); if(f != null && f.exists()) { return f; @@ -195,6 +188,9 @@ private File getInsightImageFile(String app, String id, String feUrl, String par } } } + // the image capture ran + // let us try to see if there is a file now... + f = findImageFile(fileLocation); if(f != null && f.exists()) { return f; } else { diff --git a/src/prerna/semoss/web/services/local/AuthorizationResource.java b/src/prerna/semoss/web/services/local/AuthorizationResource.java index eea42a7d2..e40cce02b 100644 --- a/src/prerna/semoss/web/services/local/AuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/AuthorizationResource.java @@ -249,16 +249,6 @@ public Response deleteUser(@Context HttpServletRequest request, MultivaluedMap form) { + User user = null; + try { + user = getUser(request); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap(); + errorMap.put("error", "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + + SecurityAdminUtils adminUtils = SecurityAdminUtils.getInstance(user); + if(adminUtils == null) { + Map retMap = new Hashtable(); + retMap.put("error", "User does not have admin priviledges"); + return WebUtility.getResponse(retMap, 400); + } + + String engineId = form.getFirst("engineId"); + boolean isPublic = Boolean.parseBoolean(form.getFirst("public")); + adminUtils.setDbGlobal(engineId, isPublic); + return WebUtility.getResponse(true, 200); + } + + ///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////// + + @POST + @Produces("application/json") + @Path("setDbPublic") + public Response setDbGlobal(@Context HttpServletRequest request, MultivaluedMap form) { + User user = null; + try { + user = getUser(request); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap(); + errorMap.put("error", "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + + String engineId = form.getFirst("engineId"); + boolean isPublic = Boolean.parseBoolean(form.getFirst("public")); + try { + SecurityUpdateUtils.setDbGlobal(user, engineId, isPublic); + } catch(IllegalArgumentException e) { + e.printStackTrace(); + Map errorRet = new HashMap(); + errorRet.put("error", e.getMessage()); + return WebUtility.getResponse(errorRet, 400); + } catch (Exception e){ + e.printStackTrace(); + Map errorRet = new HashMap(); + errorRet.put("error", "An unexpected error happened. Please try again."); + return WebUtility.getResponse(errorRet, 500); + } + + return WebUtility.getResponse(true, 200); + } + + + ///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////// + ///////////////////////////////////////////////////////// @POST @@ -377,7 +437,6 @@ public Response getDatabaseUsersAndGroups(@Context HttpServletRequest request, M return WebUtility.getResponse(errorRet, 500); } } - @POST @@ -528,53 +587,6 @@ public Response setDbVisibility(@Context HttpServletRequest request, Multivalued return WebUtility.getResponse(true, 200); } - @POST - @Produces("application/json") - @Path("/admin/setDbPublic") - public Response setAdminDbPublic(@Context HttpServletRequest request, MultivaluedMap form) { - Hashtable errorRet = new Hashtable(); - try{ - User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - String userId = user.getAccessToken(user.getLogins().get(0)).getId(); - String engineId = form.getFirst("engineId"); - String isPublic = form.getFirst("public"); - SecurityUpdateUtils.setDbPublic(userId, engineId, isPublic, true); - } catch (IllegalArgumentException e){ - e.printStackTrace(); - errorRet.put("error", e.getMessage()); - return WebUtility.getResponse(errorRet, 400); - } catch (Exception e){ - e.printStackTrace(); - errorRet.put("error", "An unexpected error happened. Please try again."); - return WebUtility.getResponse(errorRet, 500); - } - return WebUtility.getResponse(true, 200); - } - - @POST - @Produces("application/json") - @Path("setDbPublic") - public Response setDbPublic(@Context HttpServletRequest request, MultivaluedMap form) { - Hashtable errorRet = new Hashtable(); - try{ - User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - String userId = user.getAccessToken(user.getLogins().get(0)).getId(); - String engineId = form.getFirst("engineId"); - String isPublic = form.getFirst("public"); - SecurityUpdateUtils.setDbPublic(userId, engineId, isPublic, false); - } catch (IllegalArgumentException e){ - e.printStackTrace(); - errorRet.put("error", e.getMessage()); - return WebUtility.getResponse(errorRet, 400); - } catch (Exception e){ - e.printStackTrace(); - errorRet.put("error", "An unexpected error happened. Please try again."); - return WebUtility.getResponse(errorRet, 500); - } - return WebUtility.getResponse(true, 200); - } - - ///////////////////////////////////////////////// ///////////////////////////////////////////////// From 875892303c4d82a11b77ad4e77cc6a0dcd8aa542 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 23 Oct 2018 15:46:52 +0000 Subject: [PATCH 0287/1906] UPDATE ::: Redirecting the URL after login instead of sending a json message REQUIREMENT ::: Please make sure the following line in your new social.properties file is accurate "redirect http://localhost:8080/SemossWeb_AppUi" where the URL is that of your semoss homepage git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30612 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 117022584a5b7e93e6998b7df61001956be15bc3 --- .../web/services/local/UserResource.java | 200 +++++++----------- 1 file changed, 74 insertions(+), 126 deletions(-) diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index 66e0c5dfc..ce761cf11 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -534,22 +534,15 @@ public Response loginSF(@Context HttpServletRequest request, @Context HttpServle addAccessToken(accessToken, request); System.out.println("Access Token is.. " + accessToken.getAccess_token()); - ret.put("success", true); - return WebUtility.getResponse(ret, 200); - } else { - ret.put("success", true); - ret.put("Already_Authenticated", true); - return WebUtility.getResponse(ret, 200); } } - else if(userObj == null || userObj.getAccessToken(AuthProvider.SF) == null) { + + if(userObj == null || userObj.getAccessToken(AuthProvider.SF) == null) { // not authenticated response.setStatus(302); response.sendRedirect(getSFRedirect(request)); - } - else if(userObj != null && userObj.getAccessToken(AuthProvider.SF) != null) { - ret.put("success", true); - return WebUtility.getResponse(ret, 200); + } else { + setMainPageRedirect(response); } return null; } @@ -627,24 +620,15 @@ public Response loginGithub(@Context HttpServletRequest request, @Context HttpSe addAccessToken(accessToken, request); System.out.println("Access Token is.. " + accessToken.getAccess_token()); - ret.put("success", true); - return WebUtility.getResponse(ret, 200); - } else { - ret.put("success", true); - ret.put("Already_Authenticated", true); - return WebUtility.getResponse(ret, 200); } } - else if(userObj == null || userObj.getAccessToken(AuthProvider.GITHUB) == null) { + + if(userObj == null || userObj.getAccessToken(AuthProvider.GITHUB) == null) { // not authenticated response.setStatus(302); response.sendRedirect(getGitRedirect(request)); - } - // else if user object is there and git is there - else if(userObj != null && userObj.getAccessToken(AuthProvider.GITHUB) != null) - { - ret.put("success", true); - return WebUtility.getResponse(ret, 200); + } else { + setMainPageRedirect(response); } return null; } @@ -719,25 +703,17 @@ public Response loginMS(@Context HttpServletRequest request, @Context HttpServle addAccessToken(accessToken, request); System.out.println("Access Token is.. " + accessToken.getAccess_token()); - - ret.put("success", true); - return WebUtility.getResponse(ret, 200); - } else { - ret.put("success", true); - ret.put("Already_Authenticated", true); - return WebUtility.getResponse(ret, 200); } - } else if(userObj == null || userObj.getAccessToken(AuthProvider.MS) == null) { + } + + if(userObj == null || userObj.getAccessToken(AuthProvider.MS) == null) { // not authenticated response.setStatus(302); response.sendRedirect(getMSRedirect(request)); } - // else if user object is there and ms is there - else if(userObj != null && userObj.getAccessToken(AuthProvider.MS) != null) { - ret.put("success", true); - return WebUtility.getResponse(ret, 200); - } - + // at this point, you are authenticated + // redirect to main page + setMainPageRedirect(response); return null; } @@ -803,23 +779,15 @@ public Response loginDropBox(@Context HttpServletRequest request, @Context HttpS addAccessToken(accessToken, request); System.out.println("Access Token is.. " + accessToken.getAccess_token()); - ret.put("success", true); - return WebUtility.getResponse(ret, 200); - } else { - ret.put("success", true); - ret.put("Already_Authenticated", true); - return WebUtility.getResponse(ret, 200); } } - else if(userObj == null || userObj.getAccessToken(AuthProvider.DROPBOX) == null) { + + if(userObj == null || userObj.getAccessToken(AuthProvider.DROPBOX) == null) { // not authenticated response.setStatus(302); response.sendRedirect(getDBRedirect(request)); - } - // else if user object is there and dropbox is there - else if(userObj != null && userObj.getAccessToken(AuthProvider.DROPBOX) != null) { - ret.put("success", true); - return WebUtility.getResponse(ret, 200); + } else { + setMainPageRedirect(response); } return null; } @@ -879,6 +847,7 @@ public Response loginGoogle(@Context HttpServletRequest request, @Context HttpSe String url = "https://www.googleapis.com/oauth2/v4/token"; + //https://developers.google.com/api-client-library/java/google-api-java-client/oauth2 AccessToken accessToken = AbstractHttpHelper.getAccessToken(url, params, true, true); if(accessToken == null) { // not authenticated @@ -886,40 +855,29 @@ public Response loginGoogle(@Context HttpServletRequest request, @Context HttpSe response.sendRedirect(getGoogleRedirect(request)); return null; } - //https://developers.google.com/api-client-library/java/google-api-java-client/oauth2 - // Shows how to make a google credential from an access token - System.out.println("Access Token is.. " + accessToken.getAccess_token()); accessToken.setProvider(AuthProvider.GOOGLE); // fill the access token with the other properties so we can properly create the user GoogleProfile.fillAccessToken(accessToken, null); addAccessToken(accessToken, request); + // Shows how to make a google credential from an access token + System.out.println("Access Token is.. " + accessToken.getAccess_token()); + // this is just for testing... // but i will get yelled at if i remove it so here it is... // TODO: adding this todo to easily locate it // performGoogleOps(request, ret); - } else { - ret.put("success", true); - ret.put("Already_Authenticated", true); - return WebUtility.getResponse(ret, 200); } - - ret.put("success", true); - return WebUtility.getResponse(ret, 200); } // else if the user object is there, but there is no google - else if(userObj == null || userObj.getAccessToken(AuthProvider.GOOGLE) == null) { + if(userObj == null || userObj.getAccessToken(AuthProvider.GOOGLE) == null) { // not authenticated response.setStatus(302); response.sendRedirect(getGoogleRedirect(request)); + } else { + setMainPageRedirect(response); } - // else if user object is there and google is there - else if(userObj != null && userObj.getAccessToken(AuthProvider.GOOGLE) != null) { - ret.put("success", true); - return WebUtility.getResponse(ret, 200); - } - return null; } @@ -1042,18 +1000,14 @@ public Response loginProducthunt(@Context HttpServletRequest request, @Context H addAccessToken(accessToken, request); System.out.println("Access Token is.. " + accessToken.getAccess_token()); - ret.put("success", true); - return WebUtility.getResponse(ret, 200); - } else { - ret.put("success", true); - ret.put("Already_Authenticated", true); - return WebUtility.getResponse(ret, 200); } - } - else if(userObj == null || userObj.getAccessToken(AuthProvider.PRODUCT_HUNT) == null) - { + } + + if(userObj == null || userObj.getAccessToken(AuthProvider.PRODUCT_HUNT) == null) { response.setStatus(302); response.sendRedirect(getProducthuntRedirect(request)); + } else { + setMainPageRedirect(response); } return null; } @@ -1117,18 +1071,13 @@ public Response loginIn(@Context HttpServletRequest request, @Context HttpServle addAccessToken(accessToken, request); System.out.println("Access Token is.. " + accessToken.getAccess_token()); - - ret.put("success", true); - return WebUtility.getResponse(ret, 200); - } else { - ret.put("success", true); - ret.put("Already_Authenticated", true); - return WebUtility.getResponse(ret, 200); } - } + } else if(userObj == null || userObj.getAccessToken(AuthProvider.IN) == null) { response.setStatus(302); response.sendRedirect(getInRedirect(request)); + } else { + setMainPageRedirect(response); } return null; } @@ -1186,55 +1135,41 @@ public Response loginTwitter(@Context HttpServletRequest request, @Context HttpS //https://developer.github.com/apps/building-oauth-apps/authorization-options-for-oauth-apps/ String queryString = request.getQueryString(); - if(queryString != null && queryString.contains("code=")) - { - if(userObj == null || ((User)userObj).getAccessToken(AuthProvider.GITHUB) == null) - { + if(queryString != null && queryString.contains("code=")) { + if(userObj == null || ((User)userObj).getAccessToken(AuthProvider.GITHUB) == null) { - String [] outputs = AbstractHttpHelper.getCodes(queryString); - - String prefix = "git_"; - - String clientId = socialData.getProperty(prefix+"client_id"); - String clientSecret = socialData.getProperty(prefix+"secret_key"); - String redirectUri = socialData.getProperty(prefix+"redirect_uri"); - - System.out.println(">> " + request.getQueryString()); - - Hashtable params = new Hashtable(); - params.put("client_id", clientId); - params.put("redirect_uri", redirectUri); - params.put("code", outputs[0]); - params.put("state", outputs[1]); - params.put("client_secret", clientSecret); - - String url = "https://github.com/login/oauth/access_token"; - - AccessToken accessToken = AbstractHttpHelper.getAccessToken(url, params, false, true); - accessToken.setProvider(AuthProvider.GITHUB); - addAccessToken(accessToken, request); - - System.out.println("Access Token is.. " + accessToken.getAccess_token()); - - ret.put("success", true); - // return Response.status(200).entity(WebUtility.getSO(ret)).build(); - return WebUtility.getResponse(ret, 200); - } - else - { - ret.put("success", true); - ret.put("Already_Authenticated", true); - // return Response.status(200).entity(WebUtility.getSO(ret)).build(); - return WebUtility.getResponse(ret, 200); + String [] outputs = AbstractHttpHelper.getCodes(queryString); + + String prefix = "git_"; + + String clientId = socialData.getProperty(prefix+"client_id"); + String clientSecret = socialData.getProperty(prefix+"secret_key"); + String redirectUri = socialData.getProperty(prefix+"redirect_uri"); + + System.out.println(">> " + request.getQueryString()); + Hashtable params = new Hashtable(); + params.put("client_id", clientId); + params.put("redirect_uri", redirectUri); + params.put("code", outputs[0]); + params.put("state", outputs[1]); + params.put("client_secret", clientSecret); + + String url = "https://github.com/login/oauth/access_token"; + + AccessToken accessToken = AbstractHttpHelper.getAccessToken(url, params, false, true); + accessToken.setProvider(AuthProvider.GITHUB); + addAccessToken(accessToken, request); + + System.out.println("Access Token is.. " + accessToken.getAccess_token()); } } - else if(userObj == null || ((User)userObj).getAccessToken(AuthProvider.GITHUB) == null) - { + else if(userObj == null || ((User)userObj).getAccessToken(AuthProvider.GITHUB) == null) { // not authenticated - response.setStatus(302); response.sendRedirect(getGitRedirect(request)); + } else { + setMainPageRedirect(response); } return null; } @@ -1525,6 +1460,19 @@ public synchronized Response modifyLoginProperties(@PathParam("provider") String return WebUtility.getResponse(true, 200); } + /** + * Redirect the login back to the main app page + * @param response + */ + private void setMainPageRedirect(@Context HttpServletResponse response) { + response.setStatus(302); + try { + response.sendRedirect(socialData.getProperty("redirect")); + } catch (IOException e) { + e.printStackTrace(); + } + } + @GET @Produces("application/json") From c95425ad92966f1f0a3bebc5a91f1a3437708c52 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 23 Oct 2018 16:25:11 +0000 Subject: [PATCH 0288/1906] BUGFIX ::: Fixing error with first time signing on redirecting back to the same login page of the oauth provider git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30615 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: f4ba7ebecf430b248aeeccaa717230f745001892 --- .../web/services/local/UserResource.java | 32 +++++++++++++++---- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index ce761cf11..14e243804 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -536,7 +536,9 @@ public Response loginSF(@Context HttpServletRequest request, @Context HttpServle System.out.println("Access Token is.. " + accessToken.getAccess_token()); } } - + + // grab the user again + userObj = (User) request.getSession().getAttribute(Constants.SESSION_USER); if(userObj == null || userObj.getAccessToken(AuthProvider.SF) == null) { // not authenticated response.setStatus(302); @@ -623,6 +625,8 @@ public Response loginGithub(@Context HttpServletRequest request, @Context HttpSe } } + // grab the user again + userObj = (User) request.getSession().getAttribute(Constants.SESSION_USER); if(userObj == null || userObj.getAccessToken(AuthProvider.GITHUB) == null) { // not authenticated response.setStatus(302); @@ -706,6 +710,8 @@ public Response loginMS(@Context HttpServletRequest request, @Context HttpServle } } + // grab the user again + userObj = (User) request.getSession().getAttribute(Constants.SESSION_USER); if(userObj == null || userObj.getAccessToken(AuthProvider.MS) == null) { // not authenticated response.setStatus(302); @@ -782,6 +788,8 @@ public Response loginDropBox(@Context HttpServletRequest request, @Context HttpS } } + // grab the user again + userObj = (User) request.getSession().getAttribute(Constants.SESSION_USER); if(userObj == null || userObj.getAccessToken(AuthProvider.DROPBOX) == null) { // not authenticated response.setStatus(302); @@ -870,7 +878,9 @@ public Response loginGoogle(@Context HttpServletRequest request, @Context HttpSe // performGoogleOps(request, ret); } } - // else if the user object is there, but there is no google + + // grab the user again + userObj = (User) request.getSession().getAttribute(Constants.SESSION_USER); if(userObj == null || userObj.getAccessToken(AuthProvider.GOOGLE) == null) { // not authenticated response.setStatus(302); @@ -1001,8 +1011,10 @@ public Response loginProducthunt(@Context HttpServletRequest request, @Context H System.out.println("Access Token is.. " + accessToken.getAccess_token()); } - } - + } + + // grab the user again + userObj = (User) request.getSession().getAttribute(Constants.SESSION_USER); if(userObj == null || userObj.getAccessToken(AuthProvider.PRODUCT_HUNT) == null) { response.setStatus(302); response.sendRedirect(getProducthuntRedirect(request)); @@ -1072,8 +1084,11 @@ public Response loginIn(@Context HttpServletRequest request, @Context HttpServle System.out.println("Access Token is.. " + accessToken.getAccess_token()); } - } - else if(userObj == null || userObj.getAccessToken(AuthProvider.IN) == null) { + } + + // grab the user again + userObj = (User) request.getSession().getAttribute(Constants.SESSION_USER); + if(userObj == null || userObj.getAccessToken(AuthProvider.IN) == null) { response.setStatus(302); response.sendRedirect(getInRedirect(request)); } else { @@ -1164,7 +1179,10 @@ public Response loginTwitter(@Context HttpServletRequest request, @Context HttpS System.out.println("Access Token is.. " + accessToken.getAccess_token()); } } - else if(userObj == null || ((User)userObj).getAccessToken(AuthProvider.GITHUB) == null) { + + // grab the user again + userObj = (User) request.getSession().getAttribute(Constants.SESSION_USER); + if(userObj == null || ((User)userObj).getAccessToken(AuthProvider.GITHUB) == null) { // not authenticated response.setStatus(302); response.sendRedirect(getGitRedirect(request)); From d07ec1114ee82b9bee0c13cff10f0e73dad9651c Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 23 Oct 2018 19:26:44 +0000 Subject: [PATCH 0289/1906] UPDATE ::: IEngine has insert/delete data interface method that throws Exception UPDATE ::: RDBMSNativeEngine now throws its SQLException so it can be caught in things like forms to notify the user that the query didn't work UPDATE ::: Numerous try/catch clauses added to accommodate interface change UPDATE ::: Removal of userpermissionmasterdb class, userdbfiler, and userdbinsightfilter as they are no longer used/necessary git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30618 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: a2e9c70330fcfde6052cb6578c2c281411a8199a --- src/prerna/semoss/web/form/FormResource.java | 11 +- src/prerna/web/conf/UserDBFilter.java | 152 ------------------- src/prerna/web/conf/UserDBInsightFilter.java | 108 ------------- 3 files changed, 8 insertions(+), 263 deletions(-) delete mode 100644 src/prerna/web/conf/UserDBFilter.java delete mode 100644 src/prerna/web/conf/UserDBInsightFilter.java diff --git a/src/prerna/semoss/web/form/FormResource.java b/src/prerna/semoss/web/form/FormResource.java index 78c0d123f..75ad11f2f 100644 --- a/src/prerna/semoss/web/form/FormResource.java +++ b/src/prerna/semoss/web/form/FormResource.java @@ -77,9 +77,14 @@ public Response modifyUserAccess(@Context HttpServletRequest request, Multivalue IEngine formEngine = getEngine(); // execute the query - formEngine.insertData(query); - // commit to engine - formEngine.commit(); + try { + formEngine.insertData(query); + // commit to engine + formEngine.commit(); + } catch (Exception e) { + e.printStackTrace(); + return WebUtility.getResponse("An error occured to update the user's access!", 400); + } return WebUtility.getResponse("success", 200); } diff --git a/src/prerna/web/conf/UserDBFilter.java b/src/prerna/web/conf/UserDBFilter.java deleted file mode 100644 index 295d62ea8..000000000 --- a/src/prerna/web/conf/UserDBFilter.java +++ /dev/null @@ -1,152 +0,0 @@ -/******************************************************************************* - * Copyright 2015 Defense Health Agency (DHA) - * - * If your use of this software does not include any GPLv2 components: - * Licensed 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. - * ---------------------------------------------------------------------------- - * If your use of this software includes any GPLv2 components: - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - *******************************************************************************/ -package prerna.web.conf; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Hashtable; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpSession; - -import com.ibm.icu.util.StringTokenizer; - -import it.unimi.dsi.util.Properties; -//import prerna.auth.User; -//import prerna.auth.User.LOGIN_TYPES; -import prerna.auth.UserPermissionsMasterDB; -import prerna.util.Constants; -import prerna.util.DIHelper; - -public class UserDBFilter implements Filter { - - FilterConfig config; -// User user = new User(Constants.ANONYMOUS_USER_ID, "Anonymous", LOGIN_TYPES.ANONYMOUS, "Anonymous"); - - @Override - public void destroy() { - // TODO Auto-generated method stub - } - - @Override - public void doFilter(ServletRequest arg0, ServletResponse arg1, - FilterChain arg2) throws IOException, ServletException { - // assign specific DBs to a given user based on what has already been loaded - // loads the user specific databases and adds database to the users session - // try to see if this guys session is already loaded - ServletContext context = getFilterConfig().getServletContext(); - boolean securityEnabled = Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED)); - HttpSession session = ((HttpServletRequest)arg0).getSession(false); -// if(session != null) { -// if(session.getAttribute(Constants.SESSION_USER) == null) { -// session.setAttribute(Constants.SESSION_USER, user); -// } else { -// user = (User) session.getAttribute(Constants.SESSION_USER); -// } -// } - boolean dbInitialized = session != null && session.getAttribute(Constants.ENGINES+"unused") != null; - if(!dbInitialized) // this is our new friend - { - HashSet userEngines = new HashSet(); - session = ((HttpServletRequest)arg0).getSession(true); - if(securityEnabled) { - UserPermissionsMasterDB permissions = new UserPermissionsMasterDB(); -// userEngines = permissions.getUserAccessibleEngines(user.getId()); - } - // get all the engines and add the top engines - String engineNames = (String)DIHelper.getInstance().getLocalProp(Constants.ENGINES); - StringTokenizer tokens = new StringTokenizer(engineNames, ";"); - ArrayList> engines = new ArrayList>(); - while(tokens.hasMoreTokens()) - { - // this would do some check to see - String engineName = tokens.nextToken(); - //IEngine engine = (IEngine) DIHelper.getInstance().getLocalProp(engineName); - String propFile = DIHelper.getInstance().getCoreProp().getProperty(engineName + "_" + Constants.STORE); - Properties engine = null; - try - { - engine = new Properties(); - engine.load(new File(propFile)); - }catch(Exception ex) - { - - } - boolean hidden = (engine.getProperty(Constants.HIDDEN_DATABASE) != null && Boolean.parseBoolean((String)engine.getProperty(Constants.HIDDEN_DATABASE))); - if(!hidden) { - if(!securityEnabled || (securityEnabled && userEngines.contains(engineName))) { - Hashtable engineHash = new Hashtable(); - engineHash.put("name", engineName); - engineHash.put("type", engine.getProperty(Constants.ENGINE_TYPE) + ""); - engines.add(engineHash); - } - } - // set this guy into the session of our user - session.setAttribute(engineName, engine); - // and over - } - session.setAttribute(Constants.ENGINES, engines); - } - arg2.doFilter(arg0, arg1); - - } - - private void loadUserDB() - { - - } - - private boolean checkValidEngine(String engineName) - { - // this will do the check - return true; - } - - @Override - public void init(FilterConfig config) throws ServletException { - setFilterConfig(config); - } - - public void setFilterConfig(FilterConfig config) { - this.config = config; - } - - public FilterConfig getFilterConfig() { - return config; - } - -} diff --git a/src/prerna/web/conf/UserDBInsightFilter.java b/src/prerna/web/conf/UserDBInsightFilter.java deleted file mode 100644 index 36540bf10..000000000 --- a/src/prerna/web/conf/UserDBInsightFilter.java +++ /dev/null @@ -1,108 +0,0 @@ -/******************************************************************************* - * Copyright 2015 Defense Health Agency (DHA) - * - * If your use of this software does not include any GPLv2 components: - * Licensed 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. - * ---------------------------------------------------------------------------- - * If your use of this software includes any GPLv2 components: - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - *******************************************************************************/ -package prerna.web.conf; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashSet; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletContext; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; - -import com.google.gson.internal.StringMap; - -//import prerna.auth.User; -import prerna.auth.UserPermissionsMasterDB; -import prerna.util.Constants; - -public class UserDBInsightFilter implements Filter { - - FilterConfig config; - String engineAPIPath = "/e-"; - - @Override - public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { - ServletContext context = getFilterConfig().getServletContext(); - HttpSession session = ((HttpServletRequest)arg0).getSession(true); - boolean securityEnabled = Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED)); - -// if(securityEnabled) { -// HttpServletRequest request = (HttpServletRequest) arg0; -// String requestURI = request.getRequestURI(); -// if(requestURI.contains(engineAPIPath)) { -// String requestPathWithEngine = requestURI.substring(requestURI.indexOf(engineAPIPath) + engineAPIPath.length()); -// String engineName = requestPathWithEngine.substring(0, requestPathWithEngine.indexOf("/")); -// -// User user = ((User) session.getAttribute(Constants.SESSION_USER)); -// String userId = ""; -// if(user!= null) { -// userId = user.getId(); -// } -// UserPermissionsMasterDB permissions = new UserPermissionsMasterDB(); -// HashSet userEngines = permissions.getUserAccessibleEngines(userId); -// if(!engineName.equals(Constants.LOCAL_MASTER_DB_NAME) && !userEngines.contains(engineName)) { -// StringMap> insightPermissions = permissions.getInsightPermissionsForUser(userId); -// -// if(!insightPermissions.containsKey(engineName)) { -// HttpServletResponse response = (HttpServletResponse) arg1; -// response.addHeader("userId", userId); -// response.sendError(HttpServletResponse.SC_UNAUTHORIZED); -// return; -// } -// } -// } -// } - arg2.doFilter(arg0, arg1); - } - - @Override - public void init(FilterConfig config) throws ServletException { - setFilterConfig(config); - } - - @Override - public void destroy() { - - } - - public void setFilterConfig(FilterConfig config) { - this.config = config; - } - - public FilterConfig getFilterConfig() { - return config; - } -} From 95d5029de6d0e521469dfd05090988e6722b37f5 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 24 Oct 2018 20:03:07 +0000 Subject: [PATCH 0290/1906] BUGFIX ::: Fixing error with redirecting twice git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30645 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 01c7773aae234c9505ab1f317b69bdf0a177afd3 --- .../web/services/local/UserResource.java | 42 ++++++++++++++----- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index 14e243804..f998a9af9 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -530,6 +530,12 @@ public Response loginSF(@Context HttpServletRequest request, @Context HttpServle String url = "https://login.salesforce.com/services/oauth2/token"; AccessToken accessToken = AbstractHttpHelper.getAccessToken(url, params, true, true); + if(accessToken == null) { + // not authenticated + response.setStatus(302); + response.sendRedirect(getSFRedirect(request)); + return null; + } accessToken.setProvider(AuthProvider.SF); addAccessToken(accessToken, request); @@ -607,7 +613,7 @@ public Response loginGithub(@Context HttpServletRequest request, @Context HttpSe if(accessToken == null) { // not authenticated response.setStatus(302); - response.sendRedirect(getGoogleRedirect(request)); + response.sendRedirect(getGithubRedirect(request)); return null; } accessToken.setProvider(AuthProvider.GITHUB); @@ -630,14 +636,14 @@ public Response loginGithub(@Context HttpServletRequest request, @Context HttpSe if(userObj == null || userObj.getAccessToken(AuthProvider.GITHUB) == null) { // not authenticated response.setStatus(302); - response.sendRedirect(getGitRedirect(request)); + response.sendRedirect(getGithubRedirect(request)); } else { setMainPageRedirect(response); } return null; } - private String getGitRedirect(HttpServletRequest request) throws UnsupportedEncodingException { + private String getGithubRedirect(HttpServletRequest request) throws UnsupportedEncodingException { String prefix = "github_"; String clientId = socialData.getProperty(prefix+"client_id"); String redirectUri = socialData.getProperty(prefix+"redirect_uri"); @@ -698,7 +704,7 @@ public Response loginMS(@Context HttpServletRequest request, @Context HttpServle if(accessToken == null) { // not authenticated response.setStatus(302); - response.sendRedirect(getGoogleRedirect(request)); + response.sendRedirect(getMSRedirect(request)); return null; } @@ -715,11 +721,10 @@ public Response loginMS(@Context HttpServletRequest request, @Context HttpServle if(userObj == null || userObj.getAccessToken(AuthProvider.MS) == null) { // not authenticated response.setStatus(302); - response.sendRedirect(getMSRedirect(request)); + response.sendRedirect(getGithubRedirect(request)); + } else { + setMainPageRedirect(response); } - // at this point, you are authenticated - // redirect to main page - setMainPageRedirect(response); return null; } @@ -781,6 +786,12 @@ public Response loginDropBox(@Context HttpServletRequest request, @Context HttpS String url = "https://www.dropbox.com/oauth2/token"; AccessToken accessToken = AbstractHttpHelper.getAccessToken(url, params, true, true); + if(accessToken == null) { + // not authenticated + response.setStatus(302); + response.sendRedirect(getDBRedirect(request)); + return null; + } accessToken.setProvider(AuthProvider.DROPBOX); addAccessToken(accessToken, request); @@ -1006,6 +1017,12 @@ public Response loginProducthunt(@Context HttpServletRequest request, @Context H String url = "https://api.producthunt.com/v1/oauth/token"; AccessToken accessToken = AbstractHttpHelper.getAccessToken(url, params, true, true); + if(accessToken == null) { + // not authenticated + response.setStatus(302); + response.sendRedirect(getProducthuntRedirect(request)); + return null; + } accessToken.setProvider(AuthProvider.PRODUCT_HUNT); addAccessToken(accessToken, request); @@ -1079,9 +1096,14 @@ public Response loginIn(@Context HttpServletRequest request, @Context HttpServle String url = "https://www.linkedin.com/oauth/v2/accessToken"; AccessToken accessToken = AbstractHttpHelper.getAccessToken(url, params, true, true); + if(accessToken == null) { + // not authenticated + response.setStatus(302); + response.sendRedirect(getInRedirect(request)); + return null; + } accessToken.setProvider(AuthProvider.IN); addAccessToken(accessToken, request); - System.out.println("Access Token is.. " + accessToken.getAccess_token()); } } @@ -1185,7 +1207,7 @@ public Response loginTwitter(@Context HttpServletRequest request, @Context HttpS if(userObj == null || ((User)userObj).getAccessToken(AuthProvider.GITHUB) == null) { // not authenticated response.setStatus(302); - response.sendRedirect(getGitRedirect(request)); + response.sendRedirect(getGithubRedirect(request)); } else { setMainPageRedirect(response); } From 12db706534221e9917a056cf6ac047a8fc2d12ee Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 24 Oct 2018 20:44:23 +0000 Subject: [PATCH 0291/1906] UPDATE ::: Fixing to perform correct redirect git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30647 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: de85c201aa7915f5153c0947d7f55aee2dbbe54a --- src/prerna/semoss/web/services/local/UserResource.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index f998a9af9..846e2a03a 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -721,7 +721,7 @@ public Response loginMS(@Context HttpServletRequest request, @Context HttpServle if(userObj == null || userObj.getAccessToken(AuthProvider.MS) == null) { // not authenticated response.setStatus(302); - response.sendRedirect(getGithubRedirect(request)); + response.sendRedirect(getMSRedirect(request)); } else { setMainPageRedirect(response); } From c3f42c02db952242c4b727146dbc09e54e70b554 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 24 Oct 2018 21:20:47 +0000 Subject: [PATCH 0292/1906] UPDATE ::: If local master or security database do not pass the initialize steps, send the browser to a page that states that is the case. Too many unexpected behaviors can occur if parts of local master or security are operational git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30648 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: f682a5bc5b7067abe2b1645b003c11e641644032 --- WebContent/WEB-INF/web.xml | 10 ++++ WebContent/startUpFail.html | 3 + pom.xml | 3 +- src/prerna/web/conf/DBLoader.java | 11 ++++ src/prerna/web/conf/StartUpSuccessFilter.java | 60 +++++++++++++++++++ src/prerna/web/conf/WaffleFilter.java | 9 +-- 6 files changed, 91 insertions(+), 5 deletions(-) create mode 100644 WebContent/startUpFail.html create mode 100644 src/prerna/web/conf/StartUpSuccessFilter.java diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index 2173ee08e..6062a1dcd 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -5,6 +5,16 @@ index.html + + + StartUpSuccessFilter + prerna.web.conf.StartUpSuccessFilter + + + StartUpSuccessFilter + /* + + NoUserExistsFilter diff --git a/WebContent/startUpFail.html b/WebContent/startUpFail.html new file mode 100644 index 000000000..22a7913ab --- /dev/null +++ b/WebContent/startUpFail.html @@ -0,0 +1,3 @@ + +

There was an issue with starting up local master or the security database

+ \ No newline at end of file diff --git a/pom.xml b/pom.xml index f4cd46fba..2fba63efb 100644 --- a/pom.xml +++ b/pom.xml @@ -77,7 +77,8 @@ ${basedir}/WebContent index.html, - milkyway.jpg + milkyway.jpg, + startUpFail.html
diff --git a/src/prerna/web/conf/DBLoader.java b/src/prerna/web/conf/DBLoader.java index c01669e90..3d5c3fd49 100644 --- a/src/prerna/web/conf/DBLoader.java +++ b/src/prerna/web/conf/DBLoader.java @@ -105,6 +105,17 @@ public void contextInitialized(ServletContextEvent arg0) { // need to set the path // important for taking the image with security ImageCaptureReactor.setContextPath(contextPath); + + // if there was an issue starting up the server + // we should do it here so that we can redirect the user + { + IEngine localmaster = (IEngine) DIHelper.getInstance().getLocalProp(Constants.LOCAL_MASTER_DB_NAME); + IEngine security = (IEngine) DIHelper.getInstance().getLocalProp(Constants.SECURITY_DB); + if(localmaster == null || security == null || !localmaster.isConnected() || !security.isConnected()) { + // you have messed up!!! + StartUpSuccessFilter.setStartUpSuccess(false); + } + } } public void loadEngines() { diff --git a/src/prerna/web/conf/StartUpSuccessFilter.java b/src/prerna/web/conf/StartUpSuccessFilter.java new file mode 100644 index 000000000..0c6804844 --- /dev/null +++ b/src/prerna/web/conf/StartUpSuccessFilter.java @@ -0,0 +1,60 @@ +package prerna.web.conf; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +public class StartUpSuccessFilter implements Filter { + + private static boolean startUpSuccess = true; + private static final String FAIL_HTML = "/startUpFail.html"; + + @Override + public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { + ServletContext context = arg0.getServletContext(); + + if(!startUpSuccess) { + // this will be the deployment name of the app + String contextPath = context.getContextPath(); + + // this will be the full path of the request + // like http://localhost:8080/Monolith_Dev/api/engine/runPixel + String fullUrl = ((HttpServletRequest) arg0).getRequestURL().toString(); + + if(!fullUrl.endsWith(FAIL_HTML)) { + // we redirect to the index.html page where we have pushed the admin page + String redirectUrl = fullUrl.substring(0, fullUrl.indexOf(contextPath) + contextPath.length()) + FAIL_HTML; + ((HttpServletResponse) arg1).setHeader("redirect", redirectUrl); + ((HttpServletResponse) arg1).sendError(302, "Need to redirect to " + redirectUrl); + return; + } + } + + arg2.doFilter(arg0, arg1); + } + + static void setStartUpSuccess(boolean startUpSuccess) { + StartUpSuccessFilter.startUpSuccess = startUpSuccess; + } + + @Override + public void destroy() { + // TODO Auto-generated method stub + + } + + + @Override + public void init(FilterConfig arg0) throws ServletException { + // TODO Auto-generated method stub + + } +} diff --git a/src/prerna/web/conf/WaffleFilter.java b/src/prerna/web/conf/WaffleFilter.java index 2240cb7a8..7464a82b0 100644 --- a/src/prerna/web/conf/WaffleFilter.java +++ b/src/prerna/web/conf/WaffleFilter.java @@ -30,14 +30,15 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 setInitParams(arg0); HttpSession session = ((HttpServletRequest)arg0).getSession(true); - Principal principal = ((HttpServletRequest) arg0).getUserPrincipal(); - String id = principal.getName(); - String name = id.substring(id.lastIndexOf('\\')+1); - User user = (User) session.getAttribute(Constants.SESSION_USER); if(user == null) { user = new User(); + // grab the waffle elements + Principal principal = ((HttpServletRequest) arg0).getUserPrincipal(); + String id = principal.getName(); + String name = id.substring(id.lastIndexOf('\\')+1); + AccessToken token = new AccessToken(); token.setProvider(AuthProvider.WINDOWS_USER); token.setId(id); From 52852c3e854dd4cd6818505ca8ceb8dd748752e4 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 29 Oct 2018 12:15:11 +0000 Subject: [PATCH 0293/1906] UPDATE ::: Adding new reactor to get list of tables and views from external rdbms to limit import size UPDATE ::: Fixing package location of files git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30692 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 5722d72eb07b458e85317ebe581f54b303b9971c --- src/prerna/upload/DatabaseUploader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prerna/upload/DatabaseUploader.java b/src/prerna/upload/DatabaseUploader.java index c7f85d093..0c1d8e33c 100644 --- a/src/prerna/upload/DatabaseUploader.java +++ b/src/prerna/upload/DatabaseUploader.java @@ -64,7 +64,7 @@ import prerna.sablecc2.reactor.app.upload.UploadUtilities; import prerna.sablecc2.reactor.app.upload.gremlin.TinkerCsvUploadReactor; import prerna.sablecc2.reactor.app.upload.rdbms.csv.RdbmsCsvUploadReactor; -import prerna.sablecc2.reactor.app.upload.rdbms.csv.RdbmsExternalUploadReactor; +import prerna.sablecc2.reactor.app.upload.rdbms.external.RdbmsExternalUploadReactor; import prerna.sablecc2.reactor.app.upload.rdf.RdfCsvUploadReactor; import prerna.sablecc2.reactor.qs.source.ExternalJdbcSchemaReactor; import prerna.ui.components.ImportDataProcessor; From e89afb77c07336f6257fc2bde87254ef0a6e256b Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 29 Oct 2018 15:17:45 +0000 Subject: [PATCH 0294/1906] UPDATE ::: Adding in logic to auto shift ids to emails and account for current security permissions UPDATE ::: Cleaning up code by removing embedded if statements that overlap large portions of code and instead reversing the criteria and adding a continue statement git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30696 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: d5ac63be93c121866d5e05f47303184f734df444 --- src/prerna/web/conf/CACFilter.java | 180 ++++++++++++++++++++--------- 1 file changed, 127 insertions(+), 53 deletions(-) diff --git a/src/prerna/web/conf/CACFilter.java b/src/prerna/web/conf/CACFilter.java index 1f023b393..d9ba927ea 100644 --- a/src/prerna/web/conf/CACFilter.java +++ b/src/prerna/web/conf/CACFilter.java @@ -3,6 +3,7 @@ import java.io.IOException; import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; +import java.sql.SQLException; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -26,7 +27,12 @@ import prerna.auth.AuthProvider; import prerna.auth.User; import prerna.auth.utils.SecurityUpdateUtils; +import prerna.ds.util.RdbmsQueryBuilder; +import prerna.engine.api.IRawSelectWrapper; +import prerna.engine.impl.rdbms.RDBMSNativeEngine; +import prerna.rdf.engine.wrappers.WrapperManager; import prerna.util.Constants; +import prerna.util.Utility; public class CACFilter implements Filter { @@ -53,80 +59,104 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 token = new AccessToken(); token.setProvider(AuthProvider.CAC); - // loop thorugh all the certs + // loop through all the certs CERT_LOOP : for(int i = 0; i < certs.length; i++) { X509Certificate cert = certs[i]; String fullName = cert.getSubjectX500Principal().getName(); System.out.println("REQUEST COMING FROM " + fullName); - System.out.println("REQUEST COMING FROM " + fullName); + LdapName ldapDN; try { ldapDN = new LdapName(fullName); for(Rdn rdn: ldapDN.getRdns()) { - if(rdn.getType().equals("CN")) { - String value = rdn.getValue().toString(); - - if(value.equals("topazbpm001.mhse2e.med.osd.mil")) { - // THIS IS FOR TOPAZ HITTING MHS - // GIVE IT ACCESS - token.setId(value); - token.setName("TOPAZ"); - // now set the other properties - token.setToken_type(cert.getIssuerDN().getName()); - token.setExpires_in((int) cert.getNotAfter().getTime()); - LOGGER.info("Request coming from TOPAZ"); - break CERT_LOOP; - } - + // only care about CN + if(!rdn.getType().equals("CN")) { + // try next rdn + continue; + } + + // get the full value + String value = rdn.getValue().toString(); + + // account for topaz + if(value.equals("topazbpm001.mhse2e.med.osd.mil")) { + // THIS IS FOR TOPAZ HITTING MHS + // GIVE IT ACCESS + token.setId(value); + token.setName("TOPAZ"); + // now set the other properties + token.setToken_type(cert.getIssuerDN().getName()); + token.setExpires_in((int) cert.getNotAfter().getTime()); + LOGGER.info("Request coming from TOPAZ"); + break CERT_LOOP; + } - String[] split = value.split("\\."); - if(split.length >= 3) { - // need to account for middle name present - // and any other distinction like Jr. after the last name - // just gonna validate the cac has length 10 - String cacId = split[split.length-1]; - if(cacId.length() >= 10) { - // valid CAC!!! - token.setId(cacId); - token.setName(Stream.of(split).limit(split.length-2).collect(Collectors.joining(" "))); - // now set the other properties - token.setToken_type(cert.getIssuerDN().getName()); - token.setExpires_in((int) cert.getNotAfter().getTime()); - - // try to get the email - try { - EMAIL_LOOP : for(List altNames : cert.getSubjectAlternativeNames()) { - for(Object alternative : altNames) { - if(alternative instanceof String) { - String altStr = alternative.toString(); - // really simple email check... - if(altStr.contains("@")) { - token.setEmail(altStr); - break EMAIL_LOOP; - } - } - } + // make sure we have a valid user + // that means the value ends with a dod number + // and its the users name where each portion is period separated + // must have at least first name and last name and dod number + // need to account for middle name present + // and any other distinction like Jr. after the last name + String[] split = value.split("\\."); + if(split.length < 3) { + // didn't pass + // try next rdn + continue; + } + + // just going to validate the cac has length 10 + String cacId = split[split.length-1]; + if(cacId.length() < 10) { + // didn't pass + // try next rdn + continue; + } + + // if we got to here, we have a valid cac! + String name = Stream.of(split).limit(split.length-1).collect(Collectors.joining(" ")); + // we also need to get the email since that is what we will store + String email = null; + + try { + EMAIL_LOOP : for(List altNames : cert.getSubjectAlternativeNames()) { + for(Object alternative : altNames) { + if(alternative instanceof String) { + String altStr = alternative.toString(); + // really simple email check... + if(altStr.contains("@")) { + email = altStr; + break EMAIL_LOOP; } - } catch (CertificateParsingException e) { - e.printStackTrace(); } - - break CERT_LOOP; - } else { - continue; } - } else { - continue; } + } catch (CertificateParsingException e) { + e.printStackTrace(); } - } + + // lets make sure we have all the stuff + if(email != null & name != null) { + // we have everything! + // this is the only time we populate the token + // and then exit the cert loop + + token.setId(email); + token.setEmail(email); + token.setName(name); + + // if we get here, we have a valid cac + updateCacUsersStorage(cacId, email); + break CERT_LOOP; + } + } // end rdn loop } catch (InvalidNameException e) { LOGGER.error("ERROR WITH PARSING CAC INFORMATION!"); e.printStackTrace(); } } + // normal flow if(token.getName() != null) { LOGGER.info("Valid request coming from user " + token.getName()); user.setAccessToken(token); @@ -166,4 +196,48 @@ private void setInitParams(ServletRequest arg0) { } } + @Deprecated + /** + * We only have this because we need to update the way we store these users + */ + private void updateCacUsersStorage(String previousId, String email) { + String cleanEmail = RdbmsQueryBuilder.escapeForSQLStatement(email); + RDBMSNativeEngine securityDb = (RDBMSNativeEngine) Utility.getEngine(Constants.SECURITY_DB); + + // let us not try to run this multiple times... + String requireUpdateQuery = "SELECT * FROM USER WHERE ID='" + previousId +"'"; + IRawSelectWrapper wrapper = WrapperManager.getInstance().getRawWrapper(securityDb, requireUpdateQuery); + try { + // if we have next + // that means we need to update + // from id to email + if(wrapper.hasNext()) { + // need to update all the places the user id is used + String updateQuery = "UPDATE USER SET ID='" + cleanEmail +"', EMAIL='" + cleanEmail + "' WHERE ID='" + previousId + "'"; + try { + securityDb.insertData(updateQuery); + } catch (SQLException e) { + e.printStackTrace(); + } + + // need to update all the places the user id is used + updateQuery = "UPDATE ENGINEPERMISSION SET USERID='" + cleanEmail +"' WHERE USERID='" + previousId + "'"; + try { + securityDb.insertData(updateQuery); + } catch (SQLException e) { + e.printStackTrace(); + } + + // need to update all the places the user id is used + updateQuery = "UPDATE USERINSIGHTPERMISSION SET USERID='" + cleanEmail +"' WHERE USERID='" + previousId + "'"; + try { + securityDb.insertData(updateQuery); + } catch (SQLException e) { + e.printStackTrace(); + } + } + } finally { + wrapper.cleanUp(); + } + } } From c980011380c61aeb67ba6c7eb4f52641192c07b5 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 29 Oct 2018 20:18:35 +0000 Subject: [PATCH 0295/1906] BUGFIX ::: Forgot to push database uploader changes due to the package structure changes UPDATE ::: Adding functionality for CACFilter to be able to keep a daily log of how many people access the instance based on unique session ids git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30703 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: faef7356497e7e1d8254b02e083e604d26064b4f --- WebContent/WEB-INF/web.xml | 8 ++ src/prerna/upload/DatabaseUploader.java | 2 +- src/prerna/web/conf/CACFilter.java | 47 +++++++- src/prerna/web/conf/util/CACTrackingUtil.java | 110 ++++++++++++++++++ 4 files changed, 164 insertions(+), 3 deletions(-) create mode 100644 src/prerna/web/conf/util/CACTrackingUtil.java diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index 6062a1dcd..0eac2e249 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -31,6 +31,14 @@ autoAdd true + + countUserEntry + false + + + countUserEntryDb + USER_ACCESS__9809c0f7-04c6-43d8-87aa-2553b4a7832a + CACFilter diff --git a/src/prerna/upload/DatabaseUploader.java b/src/prerna/upload/DatabaseUploader.java index 0c1d8e33c..fad4a9d8c 100644 --- a/src/prerna/upload/DatabaseUploader.java +++ b/src/prerna/upload/DatabaseUploader.java @@ -64,9 +64,9 @@ import prerna.sablecc2.reactor.app.upload.UploadUtilities; import prerna.sablecc2.reactor.app.upload.gremlin.TinkerCsvUploadReactor; import prerna.sablecc2.reactor.app.upload.rdbms.csv.RdbmsCsvUploadReactor; +import prerna.sablecc2.reactor.app.upload.rdbms.external.ExternalJdbcSchemaReactor; import prerna.sablecc2.reactor.app.upload.rdbms.external.RdbmsExternalUploadReactor; import prerna.sablecc2.reactor.app.upload.rdf.RdfCsvUploadReactor; -import prerna.sablecc2.reactor.qs.source.ExternalJdbcSchemaReactor; import prerna.ui.components.ImportDataProcessor; import prerna.util.Constants; import prerna.util.DIHelper; diff --git a/src/prerna/web/conf/CACFilter.java b/src/prerna/web/conf/CACFilter.java index d9ba927ea..a555f61d5 100644 --- a/src/prerna/web/conf/CACFilter.java +++ b/src/prerna/web/conf/CACFilter.java @@ -4,6 +4,7 @@ import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; import java.sql.SQLException; +import java.time.LocalDate; import java.util.List; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -33,13 +34,21 @@ import prerna.rdf.engine.wrappers.WrapperManager; import prerna.util.Constants; import prerna.util.Utility; +import prerna.web.conf.util.CACTrackingUtil; public class CACFilter implements Filter { private static final Logger LOGGER = LogManager.getLogger(CACFilter.class.getName()); + + // filter init params private static final String AUTO_ADD = "autoAdd"; - private static Boolean autoAdd = null; + private static final String COUNT_USER_ENTRY = "countUserEntry"; + private static final String COUNT_USER_ENTRY_DATABASE = "countUserEntryDb"; + // realization of init params + private static Boolean autoAdd = null; + private CACTrackingUtil tracker = null; + private FilterConfig filterConfig; @Override @@ -156,7 +165,9 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 } } - // normal flow + // if we have the token + // and it has values filled in + // we know we can populate the user if(token.getName() != null) { LOGGER.info("Valid request coming from user " + token.getName()); user.setAccessToken(token); @@ -166,6 +177,12 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 if(CACFilter.autoAdd) { SecurityUpdateUtils.addOAuthUser(token); } + + // new user has entered! + // do we need to count? + if(tracker != null) { + tracker.addToQueue(LocalDate.now()); + } } } } @@ -193,6 +210,32 @@ private void setInitParams(ServletRequest arg0) { // Default value is true CACFilter.autoAdd = true; } + + boolean countUsers = false; + String countUsersStr = this.filterConfig.getInitParameter(COUNT_USER_ENTRY); + if(countUsersStr != null) { + countUsers = Boolean.parseBoolean(countUsersStr); + } else { + countUsers = false; + } + + if(countUsers) { + String countDatabaseId = this.filterConfig.getInitParameter(COUNT_USER_ENTRY_DATABASE); + if(countDatabaseId == null) { + LOGGER.info("SYSTEM HAS REGISTERED TO PERFORM A COUNT BUT NO DATABASE ID HAS BEEN ENTERED!!!"); + LOGGER.info("SYSTEM HAS REGISTERED TO PERFORM A COUNT BUT NO DATABASE ID HAS BEEN ENTERED!!!"); + LOGGER.info("SYSTEM HAS REGISTERED TO PERFORM A COUNT BUT NO DATABASE ID HAS BEEN ENTERED!!!"); + LOGGER.info("SYSTEM HAS REGISTERED TO PERFORM A COUNT BUT NO DATABASE ID HAS BEEN ENTERED!!!"); + } + try { + tracker = CACTrackingUtil.getInstance(countDatabaseId); + } catch(Exception e) { + LOGGER.info(e.getMessage()); + LOGGER.info(e.getMessage()); + LOGGER.info(e.getMessage()); + LOGGER.info(e.getMessage()); + } + } } } diff --git a/src/prerna/web/conf/util/CACTrackingUtil.java b/src/prerna/web/conf/util/CACTrackingUtil.java new file mode 100644 index 000000000..b06b28c93 --- /dev/null +++ b/src/prerna/web/conf/util/CACTrackingUtil.java @@ -0,0 +1,110 @@ +package prerna.web.conf.util; + +import java.time.LocalDate; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; + +import prerna.engine.api.IEngine; +import prerna.util.Utility; + +public class CACTrackingUtil { + + private static Map singletonStore = new HashMap(); + + /* + * Creating a class to manage updating the insight count + * This is necessary since we will get version conflicts + * if you run 2 insights at the same time + */ + + private BlockingQueue queue; + private CountUpdater updater; + + public CACTrackingUtil(IEngine trackingEngine) { + queue = new ArrayBlockingQueue(50); + updater = new CountUpdater(trackingEngine, queue); + + new Thread(updater).start(); + } + + public static CACTrackingUtil getInstance(String trackingEngineId) { + if(singletonStore.containsKey(trackingEngineId)) { + IEngine engine = Utility.getEngine(trackingEngineId); + if(engine == null) { + throw new IllegalArgumentException("Could not find tracking engine"); + } + CACTrackingUtil trackingUtil = new CACTrackingUtil(engine); + singletonStore.put(trackingEngineId, trackingUtil); + } + return singletonStore.get(trackingEngineId); + } + + public void addToQueue(LocalDate d) { + queue.add(d); + } + +} + +class CountUpdater implements Runnable { + + private static final String TABLE = "DAILY_USER_COUNT"; + private static final String COUNT_COL = "USER_COUNT"; + private static final String DATE_COL = "DATE_RECORDED"; + + // this is how we will keep the last date so we + // do not need to query if this date exists every time + private String lastDateExists = "xxxx-xx-xx"; + // no need to recreate this query every time either + private String updateQuery = null; + protected IEngine engine; + + protected BlockingQueue queue = null; + + public CountUpdater(IEngine engine, BlockingQueue queue) { + this.engine = engine; + this.queue = queue; + } + + public void run() { + try { + LocalDate localDate = null; + while( (localDate = queue.take()) != null) { + String todaysDate = java.sql.Date.valueOf(localDate).toString(); + + if(!lastDateExists.equals(todaysDate)) { + // we will insert for the first one of the day + String insertQuery = "INSERT INTO " + TABLE + + "(" + COUNT_COL + ", " + DATE_COL + ") " + + "VALUES (1,'" + todaysDate + "')"; + try { + engine.insertData(insertQuery); + } catch (Exception e) { + e.printStackTrace(); + } + + // and we will set the query up for the rest of the + // updates that happen today + + this.lastDateExists = todaysDate; + // we need to update our query + lastDateExists + this.updateQuery = "UPDATE " + TABLE + + " SET " + COUNT_COL + " = " + COUNT_COL + " + 1 " + + "WHERE " + DATE_COL + "=" + lastDateExists; + } else { + try { + engine.insertData(this.updateQuery); + } catch (Exception e) { + e.printStackTrace(); + } + } + + engine.commit(); + } + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + +} \ No newline at end of file From 22c93a21c0bf9f20bfd74856b01c00eae7313167 Mon Sep 17 00:00:00 2001 From: tbanach Date: Wed, 31 Oct 2018 18:21:35 +0000 Subject: [PATCH 0296/1906] BUGFIX ::: Compilation issue git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30723 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: c8ea4a2995e980b28b755d0b6b670bf50ce0c88f --- .../semoss/web/services/local/AuthorizationResource.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/prerna/semoss/web/services/local/AuthorizationResource.java b/src/prerna/semoss/web/services/local/AuthorizationResource.java index e40cce02b..ae1c3a538 100644 --- a/src/prerna/semoss/web/services/local/AuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/AuthorizationResource.java @@ -571,10 +571,10 @@ public Response setDbVisibility(@Context HttpServletRequest request, Multivalued Hashtable errorRet = new Hashtable(); try{ User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - String userId = user.getAccessToken(user.getLogins().get(0)).getId(); +// String userId = user.getAccessToken(user.getLogins().get(0)).getId(); String engineId = form.getFirst("engineId"); String visibility = form.getFirst("visibility"); - SecurityUpdateUtils.setDbVisibility(userId, engineId, visibility); + SecurityUpdateUtils.setDbVisibility(user, engineId, Boolean.parseBoolean(visibility)); } catch (IllegalArgumentException e){ e.printStackTrace(); errorRet.put("error", e.getMessage()); From 6723f848a1b3cb7fbb41185e5dacf46d2b2bd089 Mon Sep 17 00:00:00 2001 From: tbanach Date: Wed, 31 Oct 2018 18:24:49 +0000 Subject: [PATCH 0297/1906] UPDATE ::: reverting so there are no merge issues with next push git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30724 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 55131fe816f082c5a2d0cb88351f58f7bc6eba76 --- .../semoss/web/services/local/AuthorizationResource.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/prerna/semoss/web/services/local/AuthorizationResource.java b/src/prerna/semoss/web/services/local/AuthorizationResource.java index ae1c3a538..e40cce02b 100644 --- a/src/prerna/semoss/web/services/local/AuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/AuthorizationResource.java @@ -571,10 +571,10 @@ public Response setDbVisibility(@Context HttpServletRequest request, Multivalued Hashtable errorRet = new Hashtable(); try{ User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); -// String userId = user.getAccessToken(user.getLogins().get(0)).getId(); + String userId = user.getAccessToken(user.getLogins().get(0)).getId(); String engineId = form.getFirst("engineId"); String visibility = form.getFirst("visibility"); - SecurityUpdateUtils.setDbVisibility(user, engineId, Boolean.parseBoolean(visibility)); + SecurityUpdateUtils.setDbVisibility(userId, engineId, visibility); } catch (IllegalArgumentException e){ e.printStackTrace(); errorRet.put("error", e.getMessage()); From fce17dbfff333298096aac4ea163652740a4770e Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 31 Oct 2018 18:26:07 +0000 Subject: [PATCH 0298/1906] UPDATE ::: Pushing changes I should have pushed with updating the security setting db public git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30725 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 0ba068f5c4bfe66c61eb3cc29824327f847106d6 --- .../services/local/AuthorizationResource.java | 104 +++++++++++------- 1 file changed, 64 insertions(+), 40 deletions(-) diff --git a/src/prerna/semoss/web/services/local/AuthorizationResource.java b/src/prerna/semoss/web/services/local/AuthorizationResource.java index e40cce02b..7230f8bd8 100644 --- a/src/prerna/semoss/web/services/local/AuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/AuthorizationResource.java @@ -34,7 +34,6 @@ import java.util.List; import java.util.Map; -import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import javax.ws.rs.GET; @@ -51,7 +50,6 @@ import com.google.gson.internal.StringMap; import prerna.auth.User; -import prerna.auth.utils.AbstractSecurityUtils; import prerna.auth.utils.SecurityAdminUtils; import prerna.auth.utils.SecurityQueryUtils; import prerna.auth.utils.SecurityUpdateUtils; @@ -81,20 +79,6 @@ private User getUser(@Context HttpServletRequest request) throws IllegalAccessEx return user; } - /** - * Check if the security is enabled in the application. - * @return true or false - * @deprecated >>>> REPLACED WITH /config endpoint - * THIS IS STILL CALLED IN PLAYSHEETS SO NOT REMOVING - */ - @GET - @Produces("application/json") - @Path("securityEnabled") - @Deprecated - public StreamingOutput isSecurityEnabled(@Context ServletContext context) { - return WebUtility.getSO(AbstractSecurityUtils.securityEnabled()); - } - ////////////////////////////////////////////// ////////////////////////////////////////////// @@ -338,6 +322,70 @@ public Response setDbGlobal(@Context HttpServletRequest request, MultivaluedMap< return WebUtility.getResponse(true, 200); } + @POST + @Produces("application/json") + @Path("setDbVisibility") + public Response setDbVisibility(@Context HttpServletRequest request, MultivaluedMap form) { + User user = null; + try { + user = getUser(request); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap(); + errorMap.put("error", "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + + String engineId = form.getFirst("engineId"); + boolean isPublic = Boolean.parseBoolean(form.getFirst("visibility")); + try { + SecurityUpdateUtils.setDbVisibility(user, engineId, isPublic); + } catch(IllegalArgumentException e) { + e.printStackTrace(); + Map errorRet = new HashMap(); + errorRet.put("error", e.getMessage()); + return WebUtility.getResponse(errorRet, 400); + } catch (Exception e){ + e.printStackTrace(); + Map errorRet = new HashMap(); + errorRet.put("error", "An unexpected error happened. Please try again."); + return WebUtility.getResponse(errorRet, 500); + } + + return WebUtility.getResponse(true, 200); + } + + @POST + @Produces("application/json") + @Path("setDbPublic") + public Response getDatabaseUsers(@Context HttpServletRequest request, MultivaluedMap form) { + User user = null; + try { + user = getUser(request); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap(); + errorMap.put("error", "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + + String engineId = form.getFirst("engineId"); + + boolean isPublic = Boolean.parseBoolean(form.getFirst("public")); + try { + SecurityUpdateUtils.setDbGlobal(user, engineId, isPublic); + } catch(IllegalArgumentException e) { + e.printStackTrace(); + Map errorRet = new HashMap(); + errorRet.put("error", e.getMessage()); + return WebUtility.getResponse(errorRet, 400); + } catch (Exception e){ + e.printStackTrace(); + Map errorRet = new HashMap(); + errorRet.put("error", "An unexpected error happened. Please try again."); + return WebUtility.getResponse(errorRet, 500); + } + + return WebUtility.getResponse(true, 200); + } ///////////////////////////////////////////////////////// ///////////////////////////////////////////////////////// @@ -563,30 +611,6 @@ public Response removeUserPermissionsbyDbId(@Context HttpServletRequest request, return WebUtility.getResponse(ret, 200); } - - @POST - @Produces("application/json") - @Path("setDbVisibility") - public Response setDbVisibility(@Context HttpServletRequest request, MultivaluedMap form) { - Hashtable errorRet = new Hashtable(); - try{ - User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - String userId = user.getAccessToken(user.getLogins().get(0)).getId(); - String engineId = form.getFirst("engineId"); - String visibility = form.getFirst("visibility"); - SecurityUpdateUtils.setDbVisibility(userId, engineId, visibility); - } catch (IllegalArgumentException e){ - e.printStackTrace(); - errorRet.put("error", e.getMessage()); - return WebUtility.getResponse(errorRet, 400); - } catch (Exception e){ - e.printStackTrace(); - errorRet.put("error", "An unexpected error happened. Please try again."); - return WebUtility.getResponse(errorRet, 500); - } - return WebUtility.getResponse(true, 200); - } - ///////////////////////////////////////////////// ///////////////////////////////////////////////// From 4bb73d057502802d2c6cd011562942685d9fcd5a Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 31 Oct 2018 23:53:43 +0000 Subject: [PATCH 0299/1906] BUGFIX ::: Escaping user name as it is an email instead of digits git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30733 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 948cf28e2d3f52c0646fc91d29dd7e326e960570 --- src/prerna/semoss/web/form/FormResource.java | 21 +++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/prerna/semoss/web/form/FormResource.java b/src/prerna/semoss/web/form/FormResource.java index 75ad11f2f..846c90f23 100644 --- a/src/prerna/semoss/web/form/FormResource.java +++ b/src/prerna/semoss/web/form/FormResource.java @@ -18,6 +18,7 @@ import prerna.auth.AuthProvider; import prerna.auth.User; +import prerna.ds.util.RdbmsQueryBuilder; import prerna.engine.api.IEngine; import prerna.engine.api.IRawSelectWrapper; import prerna.forms.AbstractFormBuilder; @@ -64,13 +65,19 @@ public Response modifyUserAccess(@Context HttpServletRequest request, Multivalue String query = null; if (addOrRemove.equals("Remove")) { if(instancename != null && !instancename.isEmpty() && !instancename.equals("null") && !instancename.equals("undefined")) { - query = "DELETE FROM FORMS_USER_ACCESS WHERE USER_ID = '" + userid + "' AND INSTANCE_NAME = '" + instancename + "';"; + query = "DELETE FROM FORMS_USER_ACCESS WHERE USER_ID = '" + + RdbmsQueryBuilder.escapeForSQLStatement(userid) + + "' AND INSTANCE_NAME = '" + + RdbmsQueryBuilder.escapeForSQLStatement(instancename) + "';"; } else { // remove all of user - query = "DELETE FROM FORMS_USER_ACCESS WHERE USER_ID = '" + userid + "';"; + query = "DELETE FROM FORMS_USER_ACCESS WHERE USER_ID = '" + RdbmsQueryBuilder.escapeForSQLStatement(userid) + "';"; } } else if (addOrRemove.equals("Add")) { - query = "INSERT INTO FORMS_USER_ACCESS (USER_ID, INSTANCE_NAME, IS_SYS_ADMIN) VALUES ('" + userid + "','" + instancename + "','" + owner + "');"; + query = "INSERT INTO FORMS_USER_ACCESS (USER_ID, INSTANCE_NAME, IS_SYS_ADMIN) VALUES ('" + + RdbmsQueryBuilder.escapeForSQLStatement(userid) + "','" + + RdbmsQueryBuilder.escapeForSQLStatement(instancename) + "','" + + RdbmsQueryBuilder.escapeForSQLStatement(owner) + "');"; } else { return WebUtility.getResponse("Error: need to specify Add or Remove", 400); } @@ -176,7 +183,7 @@ public Response getUserInstanceAuth(@Context HttpServletRequest request) throws Map userAccessableInstances = new TreeMap(); // map to store the valid instances for the given user - String query = "SELECT INSTANCE_NAME, IS_SYS_ADMIN FROM FORMS_USER_ACCESS WHERE USER_ID = '" + cacId + "';"; + String query = "SELECT INSTANCE_NAME, IS_SYS_ADMIN FROM FORMS_USER_ACCESS WHERE USER_ID = '" + RdbmsQueryBuilder.escapeForSQLStatement(cacId) + "';"; IRawSelectWrapper wrapper = WrapperManager.getInstance().getRawWrapper(getEngine(), query); while(wrapper.hasNext()) { Object[] values = wrapper.next().getValues(); @@ -218,7 +225,7 @@ private String getCacId(@Context HttpServletRequest request) throws IOException */ private void throwErrorIfNotAdmin(String cacId) throws IllegalAccessException { String isAdminQuery = "SELECT * FROM FORMS_USER_ACCESS " - + "WHERE USER_ID='" + cacId + "' " + + "WHERE USER_ID='" + RdbmsQueryBuilder.escapeForSQLStatement(cacId) + "' " + "AND INSTANCE_NAME='ADMIN' " + "LIMIT 1;"; @@ -239,8 +246,8 @@ private void throwErrorIfNotAdmin(String cacId) throws IllegalAccessException { */ private void throwErrorIfNotSysAdmin(String cacId, String system) throws IllegalAccessException { String isAdminQuery = "SELECT * FROM FORMS_USER_ACCESS " - + "WHERE USER_ID='" + cacId + "' " - + "AND INSTANCE_NAME='" + system + "' " + + "WHERE USER_ID='" + RdbmsQueryBuilder.escapeForSQLStatement(cacId) + "' " + + "AND INSTANCE_NAME='" + RdbmsQueryBuilder.escapeForSQLStatement(system) + "' " + "AND IS_SYS_ADMIN=TRUE " + "LIMIT 1;"; From 55fb4c42d34bca0278e42fd2eebbaffd735f0a60 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 1 Nov 2018 05:37:10 +0000 Subject: [PATCH 0300/1906] BUGFIX ::: Fixing errors with tracking database BUGFIX ::: Fixing using just the id and not the alias+id combo in web.xml git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30735 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 4508c8d5add4a6331db1135c7c0a81039bbdceac --- WebContent/WEB-INF/web.xml | 7 +++---- src/prerna/web/conf/util/CACTrackingUtil.java | 4 ++-- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index 0eac2e249..8585483ff 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -37,7 +37,7 @@ countUserEntryDb - USER_ACCESS__9809c0f7-04c6-43d8-87aa-2553b4a7832a + 9809c0f7-04c6-43d8-87aa-2553b4a7832a @@ -107,7 +107,6 @@ --> - NoUserInSessionFilter prerna.web.conf.NoUserInSessionFilter @@ -179,7 +178,7 @@ Location to store uploaded file file-upload - C:\\workspace\\Semoss_Dev\\ + C:\\workspace\\Semoss\\ Temporary - Location to store uploaded file @@ -189,7 +188,7 @@ The place where the core RDF Map gets picked from RDF-MAP - C:\\workspace\\Semoss_Dev\\RDF_Map.prop + C:\\workspace\\Semoss\\RDF_Map.prop diff --git a/src/prerna/web/conf/util/CACTrackingUtil.java b/src/prerna/web/conf/util/CACTrackingUtil.java index b06b28c93..d9ddb0c10 100644 --- a/src/prerna/web/conf/util/CACTrackingUtil.java +++ b/src/prerna/web/conf/util/CACTrackingUtil.java @@ -30,7 +30,7 @@ public CACTrackingUtil(IEngine trackingEngine) { } public static CACTrackingUtil getInstance(String trackingEngineId) { - if(singletonStore.containsKey(trackingEngineId)) { + if(!singletonStore.containsKey(trackingEngineId)) { IEngine engine = Utility.getEngine(trackingEngineId); if(engine == null) { throw new IllegalArgumentException("Could not find tracking engine"); @@ -91,7 +91,7 @@ public void run() { // we need to update our query + lastDateExists this.updateQuery = "UPDATE " + TABLE + " SET " + COUNT_COL + " = " + COUNT_COL + " + 1 " - + "WHERE " + DATE_COL + "=" + lastDateExists; + + "WHERE " + DATE_COL + "='" + lastDateExists + "'"; } else { try { engine.insertData(this.updateQuery); From ed5c7cf1fb32bb8cba2a440dbd79021cc08e63d3 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 1 Nov 2018 12:05:53 +0000 Subject: [PATCH 0301/1906] UPDATE ::: Reverting paths to be consistent with _Dev git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30736 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: b9583c17f2a69a3c80737bcfb265a8e28e500c85 --- WebContent/WEB-INF/web.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index 8585483ff..7e0ae995e 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -1,6 +1,6 @@ - Monolith_Dev + Monolith index.html @@ -178,7 +178,7 @@ Location to store uploaded file file-upload - C:\\workspace\\Semoss\\ + C:\\workspace\\Semoss_Dev\\ Temporary - Location to store uploaded file @@ -188,7 +188,7 @@ The place where the core RDF Map gets picked from RDF-MAP - C:\\workspace\\Semoss\\RDF_Map.prop + C:\\workspace\\Semoss_Dev\\RDF_Map.prop From ad9fbe3fe6344c028d65e677dafea302547bd1a0 Mon Sep 17 00:00:00 2001 From: pkapaleeswaran Date: Thu, 1 Nov 2018 16:19:17 +0000 Subject: [PATCH 0302/1906] NameServer - Adds Python to the Insight if one exists for this user in the session UserResource - Creating Thread and ending thread as needed for python based on user login and logout. git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30741 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 7d62fba2cc72ad59c82ca00f44177afb7c865606 --- .../semoss/web/services/local/NameServer.java | 17 +++++-- .../web/services/local/UserResource.java | 46 +++++++++++++++++++ 2 files changed, 59 insertions(+), 4 deletions(-) diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index d66b5a92e..8c10514b0 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -70,10 +70,6 @@ import org.apache.http.util.EntityUtils; import org.jsoup.Jsoup; -import com.google.gson.Gson; -import com.google.gson.internal.StringMap; -import com.google.gson.reflect.TypeToken; - import prerna.auth.User; import prerna.auth.utils.AbstractSecurityUtils; import prerna.auth.utils.SecurityQueryUtils; @@ -88,6 +84,7 @@ import prerna.sablecc2.PixelStreamUtility; import prerna.sablecc2.comm.JobManager; import prerna.sablecc2.comm.JobThread; +import prerna.sablecc2.reactor.frame.py.PyExecutorThread; import prerna.semoss.web.services.remote.CentralNameServer; import prerna.semoss.web.services.remote.EngineRemoteResource; import prerna.upload.DatabaseUploader; @@ -103,6 +100,10 @@ import prerna.web.services.util.SemossThread; import prerna.web.services.util.WebUtility; +import com.google.gson.Gson; +import com.google.gson.internal.StringMap; +import com.google.gson.reflect.TypeToken; + @Path("/engine") public class NameServer { @@ -325,6 +326,7 @@ public Response runPixelSync(MultivaluedMap form, @Context HttpS HttpSession session = null; String sessionId = null; User user = null; + PyExecutorThread jepThread = null; boolean securityEnabled = Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED)); //If security is enabled try to get an existing session. @@ -334,6 +336,11 @@ public Response runPixelSync(MultivaluedMap form, @Context HttpS if(session != null){ sessionId = session.getId(); user = ((User) session.getAttribute(Constants.SESSION_USER)); + + // need to see if the user is enabling python here.. I will assume it is here + if(session.getAttribute("PYTHON") != null) + jepThread = (PyExecutorThread)session.getAttribute("PYTHON"); + } if(user == null) { @@ -390,6 +397,7 @@ public Response runPixelSync(MultivaluedMap form, @Context HttpS synchronized(insight) { // set the user insight.setUser(user); + insight.setPy(jepThread); JobManager manager = JobManager.getManager(); JobThread jt = null; if(insightId.equals(tempInsightId)) { @@ -1055,4 +1063,5 @@ public Response getAllLogicalNamesFromConceptual(MultivaluedMap // return Response.status(200).entity(WebUtility.getSO(DatabasePkqlService.getAllLogicalNamesFromConceptual(conceptualName, parentConceptualName))).build(); return WebUtility.getResponse(MasterDatabaseUtility.getAllLogicalNamesFromConceptualRDBMS(conceptualName, null), 200); } + } diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index 846e2a03a..ef53dd5a8 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -83,6 +83,7 @@ import prerna.io.connector.twitter.TwitterSearcher; import prerna.om.NLPDocumentInput; import prerna.security.AbstractHttpHelper; +import prerna.test.PyExecutorThread; import prerna.util.BeanFiller; import prerna.util.Constants; import prerna.util.DIHelper; @@ -275,6 +276,11 @@ public Response logout(@PathParam("provider") String provider, @Context HttpServ if(provider.equalsIgnoreCase("ALL")) { // remove the user from session call it a day request.getSession().removeAttribute(Constants.SESSION_USER); + if(AbstractSecurityUtils.securityEnabled() && DIHelper.getInstance().getProperty("PYTHON" ) != null && DIHelper.getInstance().getProperty("PYTHON").equalsIgnoreCase("true")) + { + PyExecutorThread pyThread = (PyExecutorThread) request.getSession().getAttribute("PYTHON"); + killPy(pyThread); + } removed = true; } else { User thisUser = (User) request.getSession().getAttribute(Constants.SESSION_USER); @@ -282,7 +288,9 @@ public Response logout(@PathParam("provider") String provider, @Context HttpServ if(thisUser.getLogins().isEmpty()) { request.getSession().removeAttribute(Constants.SESSION_USER); + if(AbstractSecurityUtils.securityEnabled()) { + // well, you have logged out and we always require a login // so i will redirect you repsonse.setStatus(302); @@ -290,11 +298,23 @@ public Response logout(@PathParam("provider") String provider, @Context HttpServ redirectUrl = redirectUrl + "#!/login"; ((HttpServletResponse) repsonse).setHeader("redirect", redirectUrl); ((HttpServletResponse) repsonse).sendError(302, "Need to redirect to " + redirectUrl); + + + // kill the python thread here + if(DIHelper.getInstance().getProperty("PYTHON" ) != null && DIHelper.getInstance().getProperty("PYTHON").equalsIgnoreCase("true")) + { + PyExecutorThread pyThread = (PyExecutorThread) request.getSession().getAttribute("PYTHON"); + killPy(pyThread); + } + + return null; } } else { request.getSession().setAttribute(Constants.SESSION_USER, thisUser); } + + // need some kind of check to see if this user has ANY access token anymore.. if not just remove theuser completely } Map ret = new Hashtable(); @@ -302,6 +322,18 @@ public Response logout(@PathParam("provider") String provider, @Context HttpServ return WebUtility.getResponse(ret, 200); } + private void killPy(PyExecutorThread py) + { + py.process = "stop"; + System.out.println(">>>>>> KILLING THREAD FOR USER <<<<<"); + Object monitor = py.getMonitor(); + synchronized(monitor) + { + monitor.notify(); + } + System.out.println(">>>>>> COMPLETE <<<<<"); + } + /** * Method to add an access token to a user * @param token @@ -314,6 +346,11 @@ private void addAccessToken(AccessToken token, HttpServletRequest request) { semossUser = (User)user; } else { semossUser = new User(); + + // also add the python thread to this user + if(DIHelper.getInstance().getProperty("PYTHON" ) != null && DIHelper.getInstance().getProperty("PYTHON").equalsIgnoreCase("true")) + request.getSession().setAttribute("PYTHON", getJep()); + // if(twitToken != null) { // semossUser.setGlobalAccessToken(twitToken); // } @@ -327,6 +364,15 @@ private void addAccessToken(AccessToken token, HttpServletRequest request) { SecurityUpdateUtils.addOAuthUser(token); } + private PyExecutorThread getJep() + { + System.out.println(">>>STARTING PYTHON THREAD FOR USER<<<"); + PyExecutorThread py = new PyExecutorThread(); + py.start(); + return py; + } + + /** * Gets user info for GoogleDrive */ From c61de84c1920566cbb8201d17e3644691825b2a1 Mon Sep 17 00:00:00 2001 From: pkapaleeswaran Date: Thu, 1 Nov 2018 16:33:57 +0000 Subject: [PATCH 0303/1906] Updating UserResource since eclipse had not completed the refresh. git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30743 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 71b9be3947c26828185bf86249931fe5374a70da --- .../semoss/web/services/local/UserResource.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index ef53dd5a8..90fb941e0 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -56,15 +56,13 @@ import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; +import jodd.util.URLDecoder; + import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.PropertiesConfiguration; import org.kohsuke.github.GHMyself; import org.kohsuke.github.GitHub; -import com.google.gson.Gson; -import com.google.gson.reflect.TypeToken; - -import jodd.util.URLDecoder; import prerna.auth.AccessToken; import prerna.auth.AppTokens; import prerna.auth.AuthProvider; @@ -82,14 +80,17 @@ import prerna.io.connector.ms.MSProfile; import prerna.io.connector.twitter.TwitterSearcher; import prerna.om.NLPDocumentInput; +import prerna.sablecc2.reactor.frame.py.PyExecutorThread; import prerna.security.AbstractHttpHelper; -import prerna.test.PyExecutorThread; import prerna.util.BeanFiller; import prerna.util.Constants; import prerna.util.DIHelper; import prerna.web.services.util.WebUtility; import waffle.servlet.WindowsPrincipal; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; + @Path("/auth") public class UserResource { From 2541fbd70fae25146a0e3e719b23d9bad983c748 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 2 Nov 2018 13:07:33 +0000 Subject: [PATCH 0304/1906] BUGFIX ::: Initializing to get the latest start date so when a server is stopped on date x, date x will not appear twice git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30755 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 75d5f4ee18b5294ea170718e3ba41169441fe354 --- src/prerna/web/conf/util/CACTrackingUtil.java | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/prerna/web/conf/util/CACTrackingUtil.java b/src/prerna/web/conf/util/CACTrackingUtil.java index d9ddb0c10..ec49fdab1 100644 --- a/src/prerna/web/conf/util/CACTrackingUtil.java +++ b/src/prerna/web/conf/util/CACTrackingUtil.java @@ -7,6 +7,8 @@ import java.util.concurrent.BlockingQueue; import prerna.engine.api.IEngine; +import prerna.engine.api.IRawSelectWrapper; +import prerna.rdf.engine.wrappers.WrapperManager; import prerna.util.Utility; public class CACTrackingUtil { @@ -52,6 +54,7 @@ class CountUpdater implements Runnable { private static final String TABLE = "DAILY_USER_COUNT"; private static final String COUNT_COL = "USER_COUNT"; private static final String DATE_COL = "DATE_RECORDED"; + private static final String GET_LATEST_DATE_QUERY = "SELECT MAX(" + DATE_COL + ") FROM " + TABLE; // this is how we will keep the last date so we // do not need to query if this date exists every time @@ -65,6 +68,23 @@ class CountUpdater implements Runnable { public CountUpdater(IEngine engine, BlockingQueue queue) { this.engine = engine; this.queue = queue; + + // since the server could go down + // need to get the last "lastDateExists" + // so we do not have duplicates + IRawSelectWrapper wrapper = WrapperManager.getInstance().getRawWrapper(engine, GET_LATEST_DATE_QUERY); + try { + if(wrapper.hasNext()) { + this.lastDateExists = wrapper.next().getValues()[0].toString(); + // we need to update our query + lastDateExists + this.updateQuery = "UPDATE " + TABLE + + " SET " + COUNT_COL + " = " + COUNT_COL + " + 1 " + + "WHERE " + DATE_COL + "='" + lastDateExists + "'"; + + } + } finally { + wrapper.cleanUp(); + } } public void run() { From 873c8e6450efb211f4bd452b4ef117c8b59c0c09 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 2 Nov 2018 16:18:44 +0000 Subject: [PATCH 0305/1906] UPDATE ::: Adding back the session id as a cookie in the response after successful login git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30767 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 21858b8d378e2116b9748258cce679102d79ac75 --- .../web/services/local/UserResource.java | 36 ++++++++++--------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index 90fb941e0..a4624918e 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -44,6 +44,7 @@ import java.util.UUID; import java.util.Vector; +import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; @@ -56,13 +57,15 @@ import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; -import jodd.util.URLDecoder; - import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.PropertiesConfiguration; import org.kohsuke.github.GHMyself; import org.kohsuke.github.GitHub; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; + +import jodd.util.URLDecoder; import prerna.auth.AccessToken; import prerna.auth.AppTokens; import prerna.auth.AuthProvider; @@ -88,9 +91,6 @@ import prerna.web.services.util.WebUtility; import waffle.servlet.WindowsPrincipal; -import com.google.gson.Gson; -import com.google.gson.reflect.TypeToken; - @Path("/auth") public class UserResource { @@ -597,7 +597,7 @@ public Response loginSF(@Context HttpServletRequest request, @Context HttpServle response.setStatus(302); response.sendRedirect(getSFRedirect(request)); } else { - setMainPageRedirect(response); + setMainPageRedirect(request, response); } return null; } @@ -685,7 +685,7 @@ public Response loginGithub(@Context HttpServletRequest request, @Context HttpSe response.setStatus(302); response.sendRedirect(getGithubRedirect(request)); } else { - setMainPageRedirect(response); + setMainPageRedirect(request, response); } return null; } @@ -770,7 +770,7 @@ public Response loginMS(@Context HttpServletRequest request, @Context HttpServle response.setStatus(302); response.sendRedirect(getMSRedirect(request)); } else { - setMainPageRedirect(response); + setMainPageRedirect(request, response); } return null; } @@ -853,7 +853,7 @@ public Response loginDropBox(@Context HttpServletRequest request, @Context HttpS response.setStatus(302); response.sendRedirect(getDBRedirect(request)); } else { - setMainPageRedirect(response); + setMainPageRedirect(request, response); } return null; } @@ -944,7 +944,7 @@ public Response loginGoogle(@Context HttpServletRequest request, @Context HttpSe response.setStatus(302); response.sendRedirect(getGoogleRedirect(request)); } else { - setMainPageRedirect(response); + setMainPageRedirect(request, response); } return null; } @@ -1083,7 +1083,7 @@ public Response loginProducthunt(@Context HttpServletRequest request, @Context H response.setStatus(302); response.sendRedirect(getProducthuntRedirect(request)); } else { - setMainPageRedirect(response); + setMainPageRedirect(request, response); } return null; } @@ -1161,7 +1161,7 @@ public Response loginIn(@Context HttpServletRequest request, @Context HttpServle response.setStatus(302); response.sendRedirect(getInRedirect(request)); } else { - setMainPageRedirect(response); + setMainPageRedirect(request, response); } return null; } @@ -1256,7 +1256,7 @@ public Response loginTwitter(@Context HttpServletRequest request, @Context HttpS response.setStatus(302); response.sendRedirect(getGithubRedirect(request)); } else { - setMainPageRedirect(response); + setMainPageRedirect(request, response); } return null; } @@ -1328,7 +1328,7 @@ private String getTwitterRedirect(HttpServletRequest request) throws Unsupported @POST @Produces("application/json") @Path("login") - public Response authentication(@Context HttpServletRequest request) { + public Response loginNative(@Context HttpServletRequest request, @Context HttpServletResponse response) { Hashtable ret = new Hashtable(); try{ String username = request.getParameter("username"); @@ -1349,7 +1349,8 @@ public Response authentication(@Context HttpServletRequest request) { //User print = (User) session.getAttribute(Constants.SESSION_USER); //LOGGER.info("Logging in with: " + print); - return WebUtility.getResponse(ret, 200); + setMainPageRedirect(request, response); + return null; } else { ret.put("error", "The user name or password are invalid."); return WebUtility.getResponse(ret, 401); @@ -1551,16 +1552,17 @@ public synchronized Response modifyLoginProperties(@PathParam("provider") String * Redirect the login back to the main app page * @param response */ - private void setMainPageRedirect(@Context HttpServletResponse response) { + private void setMainPageRedirect(@Context HttpServletRequest request, @Context HttpServletResponse response) { response.setStatus(302); try { + Cookie cookie = new Cookie("JSESSIONID", request.getSession().getId()); + response.addCookie(cookie); response.sendRedirect(socialData.getProperty("redirect")); } catch (IOException e) { e.printStackTrace(); } } - @GET @Produces("application/json") @Path("/whoami") From 907513a27993f8dfccf5a4a8354f09a20bb034e3 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Sat, 3 Nov 2018 01:22:09 +0000 Subject: [PATCH 0306/1906] BUGFIX ::: Adding null check as max of an empty returns null, not no rows git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30776 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 26d6f115964e394b6497aad42042e2f61892c50e --- src/prerna/web/conf/util/CACTrackingUtil.java | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/prerna/web/conf/util/CACTrackingUtil.java b/src/prerna/web/conf/util/CACTrackingUtil.java index ec49fdab1..ddd79a143 100644 --- a/src/prerna/web/conf/util/CACTrackingUtil.java +++ b/src/prerna/web/conf/util/CACTrackingUtil.java @@ -75,12 +75,15 @@ public CountUpdater(IEngine engine, BlockingQueue queue) { IRawSelectWrapper wrapper = WrapperManager.getInstance().getRawWrapper(engine, GET_LATEST_DATE_QUERY); try { if(wrapper.hasNext()) { - this.lastDateExists = wrapper.next().getValues()[0].toString(); - // we need to update our query + lastDateExists - this.updateQuery = "UPDATE " + TABLE + - " SET " + COUNT_COL + " = " + COUNT_COL + " + 1 " - + "WHERE " + DATE_COL + "='" + lastDateExists + "'"; + Object value = wrapper.next().getValues()[0]; + if(value != null) { + this.lastDateExists = value.toString(); + // we need to update our query + lastDateExists + this.updateQuery = "UPDATE " + TABLE + + " SET " + COUNT_COL + " = " + COUNT_COL + " + 1 " + + "WHERE " + DATE_COL + "='" + lastDateExists + "'"; + } } } finally { wrapper.cleanUp(); From 836eb842194eed65a539b37aa8a7c08d434275bb Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 5 Nov 2018 12:23:55 +0000 Subject: [PATCH 0307/1906] UPDATE ::: Allowing setting a redirect for native login git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30778 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 095f96e33f7c403c94126d0b28c85fed4bf6a4b9 --- .../web/services/local/UserResource.java | 35 +++++++++++-------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index a4624918e..8e3af817e 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -597,7 +597,7 @@ public Response loginSF(@Context HttpServletRequest request, @Context HttpServle response.setStatus(302); response.sendRedirect(getSFRedirect(request)); } else { - setMainPageRedirect(request, response); + setMainPageRedirect(request, response, null); } return null; } @@ -685,7 +685,7 @@ public Response loginGithub(@Context HttpServletRequest request, @Context HttpSe response.setStatus(302); response.sendRedirect(getGithubRedirect(request)); } else { - setMainPageRedirect(request, response); + setMainPageRedirect(request, response, null); } return null; } @@ -770,7 +770,7 @@ public Response loginMS(@Context HttpServletRequest request, @Context HttpServle response.setStatus(302); response.sendRedirect(getMSRedirect(request)); } else { - setMainPageRedirect(request, response); + setMainPageRedirect(request, response, null); } return null; } @@ -853,7 +853,7 @@ public Response loginDropBox(@Context HttpServletRequest request, @Context HttpS response.setStatus(302); response.sendRedirect(getDBRedirect(request)); } else { - setMainPageRedirect(request, response); + setMainPageRedirect(request, response, null); } return null; } @@ -944,7 +944,7 @@ public Response loginGoogle(@Context HttpServletRequest request, @Context HttpSe response.setStatus(302); response.sendRedirect(getGoogleRedirect(request)); } else { - setMainPageRedirect(request, response); + setMainPageRedirect(request, response, null); } return null; } @@ -1083,7 +1083,7 @@ public Response loginProducthunt(@Context HttpServletRequest request, @Context H response.setStatus(302); response.sendRedirect(getProducthuntRedirect(request)); } else { - setMainPageRedirect(request, response); + setMainPageRedirect(request, response, null); } return null; } @@ -1161,7 +1161,7 @@ public Response loginIn(@Context HttpServletRequest request, @Context HttpServle response.setStatus(302); response.sendRedirect(getInRedirect(request)); } else { - setMainPageRedirect(request, response); + setMainPageRedirect(request, response, null); } return null; } @@ -1256,7 +1256,7 @@ public Response loginTwitter(@Context HttpServletRequest request, @Context HttpS response.setStatus(302); response.sendRedirect(getGithubRedirect(request)); } else { - setMainPageRedirect(request, response); + setMainPageRedirect(request, response, null); } return null; } @@ -1333,7 +1333,9 @@ public Response loginNative(@Context HttpServletRequest request, @Context HttpSe try{ String username = request.getParameter("username"); String password = request.getParameter("password"); - boolean emptyCredentials = username == null || password == null || username.isEmpty() || password.isEmpty(); + String redirect = request.getParameter("redirect"); + + boolean emptyCredentials = (username == null || password == null || username.isEmpty() || password.isEmpty()); boolean canLogin = !emptyCredentials && NativeUserSecurityUtils.logIn(username, password); if(canLogin){ ret.put("success", "true"); @@ -1346,11 +1348,8 @@ public Response loginNative(@Context HttpServletRequest request, @Context HttpSe authToken.setId(id); authToken.setName(username); addAccessToken(authToken, request); - //User print = (User) session.getAttribute(Constants.SESSION_USER); - //LOGGER.info("Logging in with: " + print); - setMainPageRedirect(request, response); - return null; + setMainPageRedirect(request, response, null); } else { ret.put("error", "The user name or password are invalid."); return WebUtility.getResponse(ret, 401); @@ -1360,6 +1359,8 @@ public Response loginNative(@Context HttpServletRequest request, @Context HttpSe ret.put("error", "An unexpected error happened. Please try again."); return WebUtility.getResponse(ret, 500); } + + return null; } /** @@ -1552,12 +1553,16 @@ public synchronized Response modifyLoginProperties(@PathParam("provider") String * Redirect the login back to the main app page * @param response */ - private void setMainPageRedirect(@Context HttpServletRequest request, @Context HttpServletResponse response) { + private void setMainPageRedirect(@Context HttpServletRequest request, @Context HttpServletResponse response, String redirect) { response.setStatus(302); try { Cookie cookie = new Cookie("JSESSIONID", request.getSession().getId()); response.addCookie(cookie); - response.sendRedirect(socialData.getProperty("redirect")); + if(redirect == null) { + response.sendRedirect(socialData.getProperty("redirect")); + } else { + response.sendRedirect(redirect); + } } catch (IOException e) { e.printStackTrace(); } From 21681b6b9eb9d60f4b8a634bc25776c6ab783c57 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 5 Nov 2018 14:48:00 +0000 Subject: [PATCH 0308/1906] UPDATE ::: Always lowercasing the email for cac users git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30780 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 8b1c1012d5a3c74b7cc279078cc73e48b8810cd7 --- src/prerna/web/conf/CACFilter.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/prerna/web/conf/CACFilter.java b/src/prerna/web/conf/CACFilter.java index a555f61d5..d67d4ca2b 100644 --- a/src/prerna/web/conf/CACFilter.java +++ b/src/prerna/web/conf/CACFilter.java @@ -150,6 +150,9 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 // this is the only time we populate the token // and then exit the cert loop + // lower case the email + email = email.toLowerCase(); + token.setId(email); token.setEmail(email); token.setName(name); @@ -180,7 +183,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 // new user has entered! // do we need to count? - if(tracker != null) { + if(tracker != null && !token.getName().equals("TOPAZ")) { tracker.addToQueue(LocalDate.now()); } } From 98469b5b1202437291f9e8b9b68bcf363ff95fd0 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 6 Nov 2018 16:34:20 +0000 Subject: [PATCH 0309/1906] UPDATE ::: Adding getQuery method to interface git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30798 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: be8223166a796218e6a5a516418ff01da1a3aa53 --- src/prerna/cluster/RawSelectWrapperService.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/prerna/cluster/RawSelectWrapperService.java b/src/prerna/cluster/RawSelectWrapperService.java index 151050526..46e75700d 100644 --- a/src/prerna/cluster/RawSelectWrapperService.java +++ b/src/prerna/cluster/RawSelectWrapperService.java @@ -148,6 +148,11 @@ public void setQuery(String query) { throw new IllegalStateException("Only overriding this method for reference."); } + @Override + public String getQuery() { + throw new IllegalStateException("Only overriding this method for reference."); + } + /** * Set query requires appId, wrapperId, and query * @param request From ce0a6d8574eb00573ce843022ff5ae3be2bcd152 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 7 Nov 2018 17:26:19 +0000 Subject: [PATCH 0310/1906] UPDATE ::: Consolidating keys to be the same as the reactor git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30829 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 60b4e844004948dd6d73c554e5402fda4a4d1a97 --- src/prerna/upload/DatabaseUploader.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/prerna/upload/DatabaseUploader.java b/src/prerna/upload/DatabaseUploader.java index fad4a9d8c..b2d3a3980 100644 --- a/src/prerna/upload/DatabaseUploader.java +++ b/src/prerna/upload/DatabaseUploader.java @@ -1184,13 +1184,13 @@ public Response connectExistingRDBMS(@Context HttpServletRequest request, Multiv @Produces("application/json") public Response testExistingRDBMSConnection(@Context HttpServletRequest request, MultivaluedMap form) { Gson gson = new Gson(); - String driver = form.getFirst("driver"); - String hostname = form.getFirst("hostname"); - String port = form.getFirst("port"); - String username = form.getFirst("username"); - String password = form.getFirst("password"); - String schema = form.getFirst("schema"); - String additionalProperties = form.getFirst("additionalParams"); + String driver = form.getFirst(ReactorKeysEnum.DB_DRIVER_KEY.getKey()); + String hostname = form.getFirst(ReactorKeysEnum.HOST.getKey()); + String port = form.getFirst(ReactorKeysEnum.PORT.getKey()); + String username = form.getFirst(ReactorKeysEnum.USERNAME.getKey()); + String password = form.getFirst(ReactorKeysEnum.PASSWORD.getKey()); + String schema = form.getFirst(ReactorKeysEnum.SCHEMA.getKey()); + String additionalProperties = form.getFirst(ReactorKeysEnum.ADDITIONAL_CONNECTION_PARAMS_KEY.getKey()); HashMap ret = new HashMap(); ImportRDBMSProcessor importer = new ImportRDBMSProcessor(); From f0ee6186f89c7786d9d84632c9fa3631f4f70013 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 9 Nov 2018 00:14:52 +0000 Subject: [PATCH 0311/1906] UPDATE ::: Switching keys to be original ones sent from FE git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30861 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 7c828f3ec6363483e65c8ecc853f2607588609e2 --- src/prerna/upload/DatabaseUploader.java | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/prerna/upload/DatabaseUploader.java b/src/prerna/upload/DatabaseUploader.java index b2d3a3980..8a003d69b 100644 --- a/src/prerna/upload/DatabaseUploader.java +++ b/src/prerna/upload/DatabaseUploader.java @@ -1184,14 +1184,24 @@ public Response connectExistingRDBMS(@Context HttpServletRequest request, Multiv @Produces("application/json") public Response testExistingRDBMSConnection(@Context HttpServletRequest request, MultivaluedMap form) { Gson gson = new Gson(); - String driver = form.getFirst(ReactorKeysEnum.DB_DRIVER_KEY.getKey()); - String hostname = form.getFirst(ReactorKeysEnum.HOST.getKey()); + String driver = form.getFirst("driver"); + String hostname = form.getFirst("hostName"); String port = form.getFirst(ReactorKeysEnum.PORT.getKey()); String username = form.getFirst(ReactorKeysEnum.USERNAME.getKey()); String password = form.getFirst(ReactorKeysEnum.PASSWORD.getKey()); String schema = form.getFirst(ReactorKeysEnum.SCHEMA.getKey()); String additionalProperties = form.getFirst(ReactorKeysEnum.ADDITIONAL_CONNECTION_PARAMS_KEY.getKey()); HashMap ret = new HashMap(); + +// Gson gson = new Gson(); +// String driver = form.getFirst(ReactorKeysEnum.DB_DRIVER_KEY.getKey()); +// String hostname = form.getFirst(ReactorKeysEnum.HOST.getKey()); +// String port = form.getFirst(ReactorKeysEnum.PORT.getKey()); +// String username = form.getFirst(ReactorKeysEnum.USERNAME.getKey()); +// String password = form.getFirst(ReactorKeysEnum.PASSWORD.getKey()); +// String schema = form.getFirst(ReactorKeysEnum.SCHEMA.getKey()); +// String additionalProperties = form.getFirst(ReactorKeysEnum.ADDITIONAL_CONNECTION_PARAMS_KEY.getKey()); +// HashMap ret = new HashMap(); ImportRDBMSProcessor importer = new ImportRDBMSProcessor(); String test = importer.checkConnectionParams(driver, hostname, port, username, password, schema, additionalProperties); From 51bc11444a572f2e0db7562b7c7db130d158a03a Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 12 Nov 2018 16:07:14 +0000 Subject: [PATCH 0312/1906] UPDATE ::: Deleting unused files git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30872 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: c12ece292eba4f876e4df611e2a71bfbaddd6fdf --- WebContent/ForeRunner.html | 302 ------------------------------------- WebContent/Poller.html | 34 ----- WebContent/Register.html | 42 ------ 3 files changed, 378 deletions(-) delete mode 100644 WebContent/ForeRunner.html delete mode 100644 WebContent/Poller.html delete mode 100644 WebContent/Register.html diff --git a/WebContent/ForeRunner.html b/WebContent/ForeRunner.html deleted file mode 100644 index 5b16b0830..000000000 --- a/WebContent/ForeRunner.html +++ /dev/null @@ -1,302 +0,0 @@ - - - - -Insert title here - - - - - -Forerunner test - - - \ No newline at end of file diff --git a/WebContent/Poller.html b/WebContent/Poller.html deleted file mode 100644 index 6a07de51a..000000000 --- a/WebContent/Poller.html +++ /dev/null @@ -1,34 +0,0 @@ - - - - -Insert title here - - - - - - - -adsfasdf - - \ No newline at end of file diff --git a/WebContent/Register.html b/WebContent/Register.html deleted file mode 100644 index 2b31ff346..000000000 --- a/WebContent/Register.html +++ /dev/null @@ -1,42 +0,0 @@ - - - - -Insert title here - - - - - - - -adsfasdf - - \ No newline at end of file From 1daafb1fb325e12de26eb5e3724ea99eda0b7f2e Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 12 Nov 2018 16:58:27 +0000 Subject: [PATCH 0313/1906] UPDATE ::: Consolidating into a single enum list for the list of external rdbms types so we do not get an issue where one list is updated (so we can connect) but unable to generate a valid rdbms engine git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30875 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 13ffe19f0aeea76d9706459e3835abb8eec12b13 --- src/prerna/upload/DatabaseUploader.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/prerna/upload/DatabaseUploader.java b/src/prerna/upload/DatabaseUploader.java index 8a003d69b..0455602b0 100644 --- a/src/prerna/upload/DatabaseUploader.java +++ b/src/prerna/upload/DatabaseUploader.java @@ -71,7 +71,7 @@ import prerna.util.Constants; import prerna.util.DIHelper; import prerna.util.Utility; -import prerna.util.sql.SQLQueryUtil; +import prerna.util.sql.RdbmsTypeEnum; import prerna.web.services.util.WebUtility; public class DatabaseUploader extends Uploader { @@ -157,9 +157,9 @@ private void setDefaultOptions(ImportOptions options, Map inputD String rdbmsDriverType = inputData.get("rdbmsOutputType"); if(rdbmsDriverType == null || rdbmsDriverType.isEmpty()) { // default to h2 - options.setRDBMSDriverType(SQLQueryUtil.DB_TYPE.H2_DB); + options.setRDBMSDriverType(RdbmsTypeEnum.H2_DB); } else { - options.setRDBMSDriverType(SQLQueryUtil.DB_TYPE.valueOf(rdbmsDriverType.toUpperCase())); + options.setRDBMSDriverType(RdbmsTypeEnum.getEnumFromString(rdbmsDriverType)); } // if rdbms, also need to know if user wants duplicates or not in table @@ -240,9 +240,9 @@ private void setDefaultOptions(ImportOptions options, MultivaluedMap Date: Mon, 12 Nov 2018 20:43:59 +0000 Subject: [PATCH 0314/1906] UPDATE ::: Returning query results when getting app_name or insight name as case insensitive returns git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30883 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 776a99f3e709be02d3e578e958f5410a5e80330c --- src/prerna/semoss/web/services/local/AuthorizationResource.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prerna/semoss/web/services/local/AuthorizationResource.java b/src/prerna/semoss/web/services/local/AuthorizationResource.java index 7230f8bd8..b9f7beebf 100644 --- a/src/prerna/semoss/web/services/local/AuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/AuthorizationResource.java @@ -357,7 +357,7 @@ public Response setDbVisibility(@Context HttpServletRequest request, Multivalued @POST @Produces("application/json") @Path("setDbPublic") - public Response getDatabaseUsers(@Context HttpServletRequest request, MultivaluedMap form) { + public Response setDbPublic(@Context HttpServletRequest request, MultivaluedMap form) { User user = null; try { user = getUser(request); From d030dfc44d150d384e949c8b1c727c234ad0966d Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 12 Nov 2018 21:21:35 +0000 Subject: [PATCH 0315/1906] UPDATE ::: Adding /api/uploadFile/baseUpload POST endpoint to upload a generic file from the ui to the server. Returns a map of the input data including the new file path for the file git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30886 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 1883792a986f0b83f7b82fa3ce7f40c7d1255d62 --- src/prerna/upload/FileUploader.java | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/prerna/upload/FileUploader.java b/src/prerna/upload/FileUploader.java index 9906f38e3..40fda9687 100644 --- a/src/prerna/upload/FileUploader.java +++ b/src/prerna/upload/FileUploader.java @@ -25,9 +25,9 @@ import prerna.poi.main.helper.FileHelperUtil; import prerna.poi.main.helper.XLFileHelper; import prerna.poi.main.helper.excel.ExcelBlock; -import prerna.poi.main.helper.excel.ExcelWorkbookFilePreProcessor; import prerna.poi.main.helper.excel.ExcelRange; import prerna.poi.main.helper.excel.ExcelSheetPreProcessor; +import prerna.poi.main.helper.excel.ExcelWorkbookFilePreProcessor; import prerna.web.services.util.WebUtility; public class FileUploader extends Uploader { @@ -39,6 +39,22 @@ public class FileUploader extends Uploader { * However, this is only used to push the file to the BE server, the actual * processing of the file to create/add to a data frame occurs through PKQL */ + + @POST + @Path("baseUpload") + public Response uploadFile(@Context HttpServletRequest request) { + try { + List fileItems = processRequest(request); + // collect all of the data input on the form + Hashtable inputData = getInputData(fileItems); + return WebUtility.getResponse(inputData, 200); + } catch(Exception e) { + e.printStackTrace(); + HashMap errorMap = new HashMap(); + errorMap.put("errorMessage", "Error moving file to server"); + return WebUtility.getResponse(errorMap, 400); + } + } @POST @Path("determineDataTypesForFile") From fb4d779f9d2bb670974d69b7b09d313b44f66735 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 12 Nov 2018 21:49:43 +0000 Subject: [PATCH 0316/1906] UPDATE ::: Fixing bug with admin created native users not updating their user row and instead adding as a new user git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30888 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 1514f360b4a197385b5b5427e5ed874fe04c839c --- src/prerna/semoss/web/services/local/UserResource.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index 8e3af817e..161232abd 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -1409,9 +1409,10 @@ public Response createUser(@Context HttpServletRequest request) { String email = request.getParameter("email"); AccessToken newUser = new AccessToken(); newUser.setProvider(AuthProvider.NATIVE); + newUser.setId(username); + newUser.setUsername(username); newUser.setEmail(email); newUser.setName(name); - newUser.setUsername(username); boolean userCreated = NativeUserSecurityUtils.addNativeUser(newUser, password); if(userCreated){ ret.put("success", "true"); From 42a1ec8f5662898fae1d51ce7de412a39c31ecf2 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 13 Nov 2018 12:09:49 +0000 Subject: [PATCH 0317/1906] UPDATE ::: Autogenerate form user access table on forms git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30891 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: e569da58300b70f4bf401b5632232b2c6b080a29 --- src/prerna/semoss/web/form/FormResource.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/prerna/semoss/web/form/FormResource.java b/src/prerna/semoss/web/form/FormResource.java index 846c90f23..97aa15d0b 100644 --- a/src/prerna/semoss/web/form/FormResource.java +++ b/src/prerna/semoss/web/form/FormResource.java @@ -271,6 +271,7 @@ private void throwErrorIfNotSysAdmin(String cacId, String system) throws Illegal public IEngine getEngine() { if(formEngine == null) { formEngine = Utility.getEngine(FormBuilder.FORM_BUILDER_ENGINE_NAME); + AbstractFormBuilder.generateFormPermissionTable(formEngine); } return formEngine; } From cf31f2b1902edbc43b7238bb98affe8760f89973 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 14 Nov 2018 01:15:17 +0000 Subject: [PATCH 0318/1906] UPDATE ::: Adding ability to make requests to be a formal viewer or editor or owner of an app that is global git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30900 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: eec85fbd50aa7c257a51f25621dabad2dd11aab2 --- .../services/local/AuthorizationResource.java | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/prerna/semoss/web/services/local/AuthorizationResource.java b/src/prerna/semoss/web/services/local/AuthorizationResource.java index b9f7beebf..be98e3f9a 100644 --- a/src/prerna/semoss/web/services/local/AuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/AuthorizationResource.java @@ -387,6 +387,42 @@ public Response setDbPublic(@Context HttpServletRequest request, MultivaluedMap< return WebUtility.getResponse(true, 200); } + @POST + @Produces("application/json") + @Path("requestAccess") + public Response requestAccess(@Context HttpServletRequest request, MultivaluedMap form) { + User user = null; + try { + user = getUser(request); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap(); + errorMap.put("error", "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + + // what engine are you requesting permission from + String engineId = form.getFirst("engineId"); + // what is the permission of the ask + int requestedPermission = Integer.parseInt(form.getFirst("permission")); + + boolean addedRequests = true; + try { + addedRequests = SecurityUpdateUtils.makeRequest(user, engineId, requestedPermission); + } catch(IllegalArgumentException e) { + e.printStackTrace(); + Map errorRet = new HashMap(); + errorRet.put("error", e.getMessage()); + return WebUtility.getResponse(errorRet, 400); + } catch (Exception e){ + e.printStackTrace(); + Map errorRet = new HashMap(); + errorRet.put("error", "An unexpected error happened. Please try again."); + return WebUtility.getResponse(errorRet, 500); + } + + return WebUtility.getResponse(addedRequests, 200); + } + ///////////////////////////////////////////////////////// ///////////////////////////////////////////////////////// ///////////////////////////////////////////////////////// From c21f0db9727ef0793aca03f9a59647bf8cc29b06 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 14 Nov 2018 14:03:27 +0000 Subject: [PATCH 0319/1906] UPDATE ::: Pushing in ability to get a users requests to other global databases UPDATE ::: Pushing in basic method to make requests to global databases. TODO: Need to handle if a user first requests for certain privilege (read) and then wants to update that privilege (edit) git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30901 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: ceb6b7f854d07c5be20e0c80819d66b2eafeaa87 --- .../services/local/AuthorizationResource.java | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/src/prerna/semoss/web/services/local/AuthorizationResource.java b/src/prerna/semoss/web/services/local/AuthorizationResource.java index be98e3f9a..a15eb831a 100644 --- a/src/prerna/semoss/web/services/local/AuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/AuthorizationResource.java @@ -421,7 +421,38 @@ public Response requestAccess(@Context HttpServletRequest request, MultivaluedMa } return WebUtility.getResponse(addedRequests, 200); - } + } + + @GET + @Produces("application/json") + @Path("myRequests") + public Response getMyRequests(@Context HttpServletRequest request) { + User user = null; + try { + user = getUser(request); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap(); + errorMap.put("error", "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + + List> userRequests = null; + try { + userRequests = SecurityQueryUtils.getUserAccessRequests(user); + } catch(IllegalArgumentException e) { + e.printStackTrace(); + Map errorRet = new HashMap(); + errorRet.put("error", e.getMessage()); + return WebUtility.getResponse(errorRet, 400); + } catch (Exception e){ + e.printStackTrace(); + Map errorRet = new HashMap(); + errorRet.put("error", "An unexpected error happened. Please try again."); + return WebUtility.getResponse(errorRet, 500); + } + + return WebUtility.getResponse(userRequests, 200); + } ///////////////////////////////////////////////////////// ///////////////////////////////////////////////////////// From 0500d2e2effd44c3c6de8caa227764d533f2f2ad Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 14 Nov 2018 14:51:13 +0000 Subject: [PATCH 0320/1906] UPDATE ::: Adding proper redirect when trying to access a rest endpoint directly when security is enabled and no user session has been created on the browser git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30903 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 2ba3dc392b824162174433a16040b876bf6bda79 --- WebContent/noUserFail.html | 3 +++ src/prerna/web/conf/NoUserInSessionFilter.java | 18 +++++++++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) create mode 100644 WebContent/noUserFail.html diff --git a/WebContent/noUserFail.html b/WebContent/noUserFail.html new file mode 100644 index 000000000..6fe9330b8 --- /dev/null +++ b/WebContent/noUserFail.html @@ -0,0 +1,3 @@ + +

Must be logged in to retrieve data from this endpoint

+ \ No newline at end of file diff --git a/src/prerna/web/conf/NoUserInSessionFilter.java b/src/prerna/web/conf/NoUserInSessionFilter.java index 004384112..dd6121d6c 100644 --- a/src/prerna/web/conf/NoUserInSessionFilter.java +++ b/src/prerna/web/conf/NoUserInSessionFilter.java @@ -21,7 +21,9 @@ public class NoUserInSessionFilter implements Filter { + private static final String NO_USER_HTML = "/noUserFail.html"; protected static List ignoreDueToFE = new Vector(); + static { ignoreDueToFE.add("config"); ignoreDueToFE.add("auth/logins"); @@ -56,9 +58,19 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 ((HttpServletResponse) arg1).setStatus(302); String redirectUrl = ((HttpServletRequest) arg0).getHeader("referer"); - redirectUrl = redirectUrl + "#!/login"; - ((HttpServletResponse) arg1).setHeader("redirect", redirectUrl); - ((HttpServletResponse) arg1).sendError(302, "Need to redirect to " + redirectUrl); + // if no referrer + // then a person hit the endpoint directly + if(redirectUrl == null) { + // this will be the deployment name of the app + String contextPath = context.getContextPath(); + redirectUrl = fullUrl.substring(0, fullUrl.indexOf(contextPath) + contextPath.length()) + NO_USER_HTML; + ((HttpServletResponse) arg1).setStatus(302); + ((HttpServletResponse) arg1).sendRedirect(redirectUrl); + } else { + redirectUrl = redirectUrl + "#!/login"; + ((HttpServletResponse) arg1).setHeader("redirect", redirectUrl); + ((HttpServletResponse) arg1).sendError(302, "Need to redirect to " + redirectUrl); + } return; } } From 067c0c4f5e161c3b39d5c705f3e361c1c8bf6d8a Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 14 Nov 2018 17:54:10 +0000 Subject: [PATCH 0321/1906] UPDATE ::: Not creating unnecessary session ids UPDATE ::: Commenting out CACFilter from default web.xml as it creates a session id git-svn-id: svn://107.170.10.188:8080/Monolith/dev@30904 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: cb08bbea0c5a693fe89ea0cc60704c96452a2066 --- WebContent/WEB-INF/web.xml | 6 +++++- .../services/config/ServerConfigurationResource.java | 10 ++++++++-- src/prerna/semoss/web/services/local/UserResource.java | 6 +++++- src/prerna/web/conf/NoUserInSessionFilter.java | 7 +++++-- 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index 7e0ae995e..662e6265c 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -24,6 +24,9 @@ NoUserExistsFilter /api/*
+ + + + - + org.python @@ -1471,7 +1475,7 @@ mysql mysql-connector-java - 5.1.18 + 5.1.44 * From 828c2f3272522630975fbb0e600120043def4f81 Mon Sep 17 00:00:00 2001 From: tbanach Date: Mon, 10 Dec 2018 18:17:54 +0000 Subject: [PATCH 0362/1906] UPDATE ::: Syncing mysql driver versions in Semoss and Monolith, also commenting out JEP dep in monolith since its not used. UPDATE ::: newer version of junit git-svn-id: svn://107.170.10.188:8080/Monolith/dev@31296 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 927add2c04c85c698df5c44bb11204c80116bd25 --- pom.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 1fb73982c..5ab3dd58f 100644 --- a/pom.xml +++ b/pom.xml @@ -1153,7 +1153,7 @@ - + org.python @@ -2429,12 +2429,12 @@ - + +
+ +
@@ -299,6 +307,10 @@ } else { present = false; } + + if(params['route']) { + document.getElementById("share_route").value = decodeURIComponent(params['route']); + } if(present) { connectTableau(); From 722b76fbba0b9ecb787010ea647b309ef7ab8463 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 11 Dec 2018 13:59:40 +0000 Subject: [PATCH 0369/1906] UPDATE ::: Adding appropriate context path to route cookie git-svn-id: svn://107.170.10.188:8080/Monolith/dev@31334 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 81ce3f95a64fb508f3e37550f70a7138835f211e --- src/prerna/web/conf/NoUserInSessionFilter.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/prerna/web/conf/NoUserInSessionFilter.java b/src/prerna/web/conf/NoUserInSessionFilter.java index 95924c9fc..6c2f5d8c6 100644 --- a/src/prerna/web/conf/NoUserInSessionFilter.java +++ b/src/prerna/web/conf/NoUserInSessionFilter.java @@ -95,6 +95,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 String route = req.getParameter("route"); if(route != null) { Cookie c = new Cookie("route", route); + c.setPath(contextPath); ((HttpServletResponse)arg1).addCookie(c); } From 4d7a5aac84ba799bb81b57d1458bde34028d7253 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 11 Dec 2018 17:35:11 +0000 Subject: [PATCH 0370/1906] UPDATE ::: Using more concise syntax for includes in cdse pom.xml UPDATE ::: Removing additional "," at end of list in monolith pom.xml git-svn-id: svn://107.170.10.188:8080/Monolith/dev@31345 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 6a358a7e571bf1289286c2ce8bc2900a94058cec --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 05c43a112..847c2747e 100644 --- a/pom.xml +++ b/pom.xml @@ -79,7 +79,7 @@ setAdmin/**, startUpFail/**, noUserFail/**, - share/**, + share/** From 37ea289c9004b7142f778792024838e2cbc4bffb Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 14 Dec 2018 14:06:25 +0000 Subject: [PATCH 0371/1906] UPDATE ::: Default setting for security to be true UPDATE ::: Default setting for native registration to be true git-svn-id: svn://107.170.10.188:8080/Monolith/dev@31391 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 97b6d98cc8726cef145d52fd75ee4d7be30201cf --- WebContent/WEB-INF/web.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index 662e6265c..feaa153cf 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -177,7 +177,7 @@ security-enabled - false + true Location to store uploaded file From 29ff1eafa9391d6d37e9669a50fdb501fd6de580 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 14 Dec 2018 15:05:08 +0000 Subject: [PATCH 0372/1906] UPDATE ::: Adding additional instructions for setAdmin page git-svn-id: svn://107.170.10.188:8080/Monolith/dev@31396 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 6a005a38860aa5202527f2368dcf2a62099973bc --- WebContent/setAdmin/index.html | 54 ++++++++++++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/WebContent/setAdmin/index.html b/WebContent/setAdmin/index.html index 5e5ee183f..272c15106 100644 --- a/WebContent/setAdmin/index.html +++ b/WebContent/setAdmin/index.html @@ -10,6 +10,24 @@ font-weight: 300; overflow: hidden; } + + table, th, td { + border: 1px solid black; + border-collapse: collapse; + } + + table { + width: 100% + } + + th, td { + font-size: 12px; + padding: 15px; + } + + th { + text-align: left; + } * { -webkit-box-sizing: border-box; @@ -168,7 +186,7 @@ position: relative; display: block; margin: 0 auto; - max-width: 300px; + max-width: 500px; width: 80%; border: 1px solid #E7E7E7; border: 1px solid var(--color-grey3); @@ -208,7 +226,7 @@ action="javascript:registerAdmins(this)">
- Please set your initial admin + Please set your initial admin:
+ +
+
+ Utilize this table to determine what value to enter +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + +
Login TypeInput Value
Google OAuthEmail
Microsoft OAuthEmail
Native Login / PasswordUsername (must match one you will enter on registration page)
X.509 CertificatesEmail
WaffleUsername (e.g. US\jsmith)
From 0a3b72a9f42f08e901ed26d52206bd564fc1d361 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 14 Dec 2018 15:21:35 +0000 Subject: [PATCH 0373/1906] UPDATE ::: Adding improved verbiage on setAdmin page git-svn-id: svn://107.170.10.188:8080/Monolith/dev@31397 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 05ded9c051881cd75368f03a4a92d886b9a5dc5f --- WebContent/setAdmin/index.html | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/WebContent/setAdmin/index.html b/WebContent/setAdmin/index.html index 272c15106..23ea9fe98 100644 --- a/WebContent/setAdmin/index.html +++ b/WebContent/setAdmin/index.html @@ -256,20 +256,24 @@ Google OAuth Email + + Github OAuth + Email (must have an email set on public profile) + Microsoft OAuth Email Native Login / Password - Username (must match one you will enter on registration page) + Username (must match value to be entered on registration page) X.509 Certificates Email - Waffle + Windows Authentication - Waffle Username (e.g. US\jsmith) From ab09784aae7f8de6b81f82f3c02f26c61dba487d Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 17 Dec 2018 18:36:30 +0000 Subject: [PATCH 0374/1906] UPDATE ::: Switching to improved method for testing if user can view an app git-svn-id: svn://107.170.10.188:8080/Monolith/dev@31414 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 3c3b05e92868abfa5e27f117b4658a8e57e0bbe6 --- src/prerna/semoss/web/services/local/AppResource.java | 2 +- src/prerna/semoss/web/services/local/NameServer.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/prerna/semoss/web/services/local/AppResource.java b/src/prerna/semoss/web/services/local/AppResource.java index e5a5cad72..3f2ee009b 100644 --- a/src/prerna/semoss/web/services/local/AppResource.java +++ b/src/prerna/semoss/web/services/local/AppResource.java @@ -51,7 +51,7 @@ public class AppResource { private IEngine getApp(User user, String appId) throws IllegalAccessException { if(AbstractSecurityUtils.securityEnabled()) { appId = SecurityQueryUtils.testUserEngineIdForAlias(user, appId); - if(!SecurityQueryUtils.getUserEngineIds(user).contains(appId)) { + if(!SecurityQueryUtils.userCanViewEngine(user, appId)) { throw new IllegalAccessException("App " + appId + " does not exist or user does not have access to database"); } } else { diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index 6ae3239cf..ffe714a2b 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -725,7 +725,7 @@ public Object getLocalDatabase(@Context HttpServletRequest request, @PathParam(" return WebUtility.getSO("Not properly authenticated"); } engineId = SecurityQueryUtils.testUserEngineIdForAlias(user, engineId); - if(!SecurityQueryUtils.getUserEngineIds(user).contains(engineId)) { + if(!SecurityQueryUtils.userCanViewEngine(user, engineId)) { Map errorMap = new HashMap(); errorMap.put("errorMessage", "Database " + engineId + " does not exist or user does not have access to database"); return WebUtility.getResponse(errorMap, 400); From 36b4587d46cd99d2554d8abdfd83f7871fa4063e Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 17 Dec 2018 23:04:30 +0000 Subject: [PATCH 0375/1906] UPDATE ::: Adding new parameter to determine if only admins should be able to set if an app is global and available to everyone or not UPDATE ::: Single access for if security is enabled instead of grabbing from multiple different locations git-svn-id: svn://107.170.10.188:8080/Monolith/dev@31425 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 8a7bd22505c74f181076320bcf2927675aa65a35 --- WebContent/WEB-INF/web.xml | 4 ++ .../web/services/local/AppResource.java | 2 +- .../services/local/AuthorizationResource.java | 49 ++++++------------- .../semoss/web/services/local/NameServer.java | 27 +++++----- src/prerna/web/conf/AdminStartupFilter.java | 7 +-- src/prerna/web/conf/DBLoader.java | 8 ++- src/prerna/web/conf/NoUserExistsFilter.java | 10 ++-- .../web/conf/NoUserInSessionFilter.java | 4 +- src/prerna/web/conf/UserExistsFilter.java | 7 +-- 9 files changed, 50 insertions(+), 68 deletions(-) diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index feaa153cf..7f6a9ddef 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -179,6 +179,10 @@ security-enabled true
+ + admin-set-public + false + Location to store uploaded file file-upload diff --git a/src/prerna/semoss/web/services/local/AppResource.java b/src/prerna/semoss/web/services/local/AppResource.java index 3f2ee009b..7ad55f682 100644 --- a/src/prerna/semoss/web/services/local/AppResource.java +++ b/src/prerna/semoss/web/services/local/AppResource.java @@ -128,7 +128,7 @@ protected File getAppImageFile(String app) { @Path("/insightImage/download") @Produces({MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_SVG_XML}) public Response downloadInsightImage(@Context HttpServletRequest request, @PathParam("appName") String app, @QueryParam("rdbmsId") String id, @QueryParam("params") String params) { - boolean securityEnabled = Boolean.parseBoolean((String)DIHelper.getInstance().getLocalProp(Constants.SECURITY_ENABLED)); + boolean securityEnabled = AbstractSecurityUtils.securityEnabled(); String sessionId = null; if(securityEnabled){ sessionId = request.getSession(false).getId(); diff --git a/src/prerna/semoss/web/services/local/AuthorizationResource.java b/src/prerna/semoss/web/services/local/AuthorizationResource.java index ff08784f5..4a73d7a62 100644 --- a/src/prerna/semoss/web/services/local/AuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/AuthorizationResource.java @@ -33,6 +33,7 @@ import java.util.List; import java.util.Map; +import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.GET; import javax.ws.rs.POST; @@ -57,6 +58,9 @@ @Path("/authorization") public class AuthorizationResource { + @Context + protected ServletContext context; + /* * General methods */ @@ -268,7 +272,14 @@ public Response setAdminDbPublic(@Context HttpServletRequest request, Multivalue @POST @Produces("application/json") @Path("setDbPublic") - public Response setDbGlobal(@Context HttpServletRequest request, MultivaluedMap form) { + public Response setDbPublic(@Context HttpServletRequest request, MultivaluedMap form) { + boolean onlyAdmin = Boolean.parseBoolean(context.getInitParameter(Constants.ADMIN_SET_PUBLIC)); + if(onlyAdmin) { + Map errorMap = new HashMap(); + errorMap.put("error", "For this instance, only admins are allowed to set specific apps global"); + return WebUtility.getResponse(errorMap, 400); + } + User user = null; try { user = ResourceUtility.getUser(request); @@ -279,6 +290,7 @@ public Response setDbGlobal(@Context HttpServletRequest request, MultivaluedMap< } String engineId = form.getFirst("engineId"); + boolean isPublic = Boolean.parseBoolean(form.getFirst("public")); try { SecurityUpdateUtils.setDbGlobal(user, engineId, isPublic); @@ -295,7 +307,7 @@ public Response setDbGlobal(@Context HttpServletRequest request, MultivaluedMap< } return WebUtility.getResponse(true, 200); - } + } @POST @Produces("application/json") @@ -329,39 +341,6 @@ public Response setDbVisibility(@Context HttpServletRequest request, Multivalued return WebUtility.getResponse(true, 200); } - @POST - @Produces("application/json") - @Path("setDbPublic") - public Response setDbPublic(@Context HttpServletRequest request, MultivaluedMap form) { - User user = null; - try { - user = ResourceUtility.getUser(request); - } catch (IllegalAccessException e) { - Map errorMap = new HashMap(); - errorMap.put("error", "User session is invalid"); - return WebUtility.getResponse(errorMap, 401); - } - - String engineId = form.getFirst("engineId"); - - boolean isPublic = Boolean.parseBoolean(form.getFirst("public")); - try { - SecurityUpdateUtils.setDbGlobal(user, engineId, isPublic); - } catch(IllegalArgumentException e) { - e.printStackTrace(); - Map errorRet = new HashMap(); - errorRet.put("error", e.getMessage()); - return WebUtility.getResponse(errorRet, 400); - } catch (Exception e){ - e.printStackTrace(); - Map errorRet = new HashMap(); - errorRet.put("error", "An unexpected error happened. Please try again."); - return WebUtility.getResponse(errorRet, 500); - } - - return WebUtility.getResponse(true, 200); - } - @POST @Produces("application/json") @Path("requestAccess") diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index ffe714a2b..1bbb2bb21 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -117,34 +117,40 @@ public class NameServer { // uploader functionality @Path("/uploadDatabase") public Uploader uploadDatabase(@Context HttpServletRequest request) { + boolean securityEnabled = AbstractSecurityUtils.securityEnabled(); + Uploader upload = new DatabaseUploader(); String filePath = context.getInitParameter("file-upload"); upload.setFilePath(filePath); String tempFilePath = context.getInitParameter("temp-file-upload"); upload.setTempFilePath(tempFilePath); - upload.setSecurityEnabled(Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED))); + upload.setSecurityEnabled(securityEnabled); return upload; } @Path("/uploadFile") public Uploader uploadFile(@Context HttpServletRequest request) { + boolean securityEnabled = AbstractSecurityUtils.securityEnabled(); + Uploader upload = new FileUploader(); String filePath = DIHelper.getInstance().getProperty(Constants.INSIGHT_CACHE_DIR) + "\\" + DIHelper.getInstance().getProperty(Constants.CSV_INSIGHT_CACHE_FOLDER); upload.setFilePath(filePath); String tempFilePath = context.getInitParameter("temp-file-upload"); upload.setTempFilePath(tempFilePath); - upload.setSecurityEnabled(Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED))); + upload.setSecurityEnabled(securityEnabled); return upload; } @Path("/uploadImage") public Uploader uploadImage(@Context HttpServletRequest request) { + boolean securityEnabled = AbstractSecurityUtils.securityEnabled(); + Uploader upload = new ImageUploader(); String filePath = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER) + "\\db"; upload.setFilePath(filePath); String tempFilePath = context.getInitParameter("temp-file-upload"); upload.setTempFilePath(tempFilePath); - upload.setSecurityEnabled(Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED))); + upload.setSecurityEnabled(securityEnabled); return upload; } @@ -164,7 +170,8 @@ public StreamingOutput getPlaySheets(@Context HttpServletRequest request) { @Path("/dbAdmin") public Object modifyInsight(@Context HttpServletRequest request) { DBAdminResource questionAdmin = new DBAdminResource(); - questionAdmin.setSecurityEnabled(Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED))); + boolean securityEnabled = AbstractSecurityUtils.securityEnabled(); + questionAdmin.setSecurityEnabled(securityEnabled); return questionAdmin; } @@ -434,7 +441,7 @@ public Response runPixelSync(@Context HttpServletRequest request){ @Path("runPixelAsync") @Produces("application/json") public Response runPixelAsync(@Context HttpServletRequest request) { - boolean securityEnabled = Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED)); + boolean securityEnabled = AbstractSecurityUtils.securityEnabled(); HttpSession session = null; User user = null; if(securityEnabled){ @@ -779,11 +786,9 @@ public Object getCentralNameServer(@QueryParam("centralServerUrl") String url, @Path("all") @Produces("application/json") public StreamingOutput printEngines(@Context HttpServletRequest request) { - Object securityObj = DIHelper.getInstance().getLocalProp(Constants.SECURITY_ENABLED); - boolean security = (securityObj instanceof Boolean && ((boolean) securityObj) ) || (Boolean.parseBoolean(securityObj.toString())); - + boolean securityEnabled = AbstractSecurityUtils.securityEnabled(); List> engines = null; - if(security) { + if(securityEnabled) { HttpSession session = request.getSession(false); if(session == null) { return WebUtility.getSO("Not properly authenticated"); @@ -955,7 +960,7 @@ public StreamingOutput runPkql(MultivaluedMap form ) { @Produces("application/json") public StreamingOutput getAutoCompleteResults(@QueryParam("completeTerm") String searchString, @Context HttpServletRequest request) { List searchResults = null; - boolean securityEnabled = Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED)); + boolean securityEnabled = AbstractSecurityUtils.securityEnabled(); if(securityEnabled) { HttpSession session = request.getSession(false); User user = (User) session.getAttribute(Constants.SESSION_USER); @@ -990,7 +995,7 @@ public StreamingOutput getSearchInsightsResults(MultivaluedMap f // If security is enabled, remove the engines in the filters that aren't // accessible - if none in filters, add all accessible engines to filter // list - boolean securityEnabled = Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED)); + boolean securityEnabled = AbstractSecurityUtils.securityEnabled(); List> queryResults = null; if (securityEnabled) { // filter insights based on what the user has access to diff --git a/src/prerna/web/conf/AdminStartupFilter.java b/src/prerna/web/conf/AdminStartupFilter.java index 4863cc53f..6eba2126b 100644 --- a/src/prerna/web/conf/AdminStartupFilter.java +++ b/src/prerna/web/conf/AdminStartupFilter.java @@ -5,12 +5,12 @@ import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; -import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletResponse; +import prerna.auth.utils.AbstractSecurityUtils; import prerna.engine.api.IEngine; import prerna.engine.api.IRawSelectWrapper; import prerna.rdf.engine.wrappers.WrapperManager; @@ -23,10 +23,7 @@ public class AdminStartupFilter implements Filter { @Override public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { - ServletContext context = arg0.getServletContext(); - - boolean security = Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED)); - if(security) { + if(AbstractSecurityUtils.securityEnabled()) { IEngine engine = Utility.getEngine(Constants.SECURITY_DB); String q = "SELECT * FROM USER LIMIT 1"; IRawSelectWrapper wrapper = WrapperManager.getInstance().getRawWrapper(engine, q); diff --git a/src/prerna/web/conf/DBLoader.java b/src/prerna/web/conf/DBLoader.java index f43a9c686..3218e6767 100644 --- a/src/prerna/web/conf/DBLoader.java +++ b/src/prerna/web/conf/DBLoader.java @@ -68,7 +68,10 @@ public void contextInitialized(ServletContextEvent arg0) { String rdfPropFile = context.getInitParameter(RDFMAP); String securityEnabled = context.getInitParameter(Constants.SECURITY_ENABLED); - + String adminSetPublicOnly = context.getInitParameter(Constants.ADMIN_SET_PUBLIC); + if(adminSetPublicOnly == null) { + context.setInitParameter(Constants.ADMIN_SET_PUBLIC, "false"); + } System.out.println("Initializing application context..." + contextPath); //Set default file separator system variable @@ -88,7 +91,8 @@ public void contextInitialized(ServletContextEvent arg0) { // this is because security database, on init, will // load it as a boolean instead of us searching within DIHelper DIHelper.getInstance().setLocalProperty(Constants.SECURITY_ENABLED, securityEnabled); - + DIHelper.getInstance().setLocalProperty(Constants.ADMIN_SET_PUBLIC, adminSetPublicOnly); + //Load empty engine list into DIHelper, then load engines from db folder System.out.println("Loading engines..."); String engines = ""; diff --git a/src/prerna/web/conf/NoUserExistsFilter.java b/src/prerna/web/conf/NoUserExistsFilter.java index 4f515d35c..436dda9d9 100644 --- a/src/prerna/web/conf/NoUserExistsFilter.java +++ b/src/prerna/web/conf/NoUserExistsFilter.java @@ -5,13 +5,13 @@ import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; -import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import prerna.auth.utils.AbstractSecurityUtils; import prerna.engine.api.IEngine; import prerna.engine.api.IRawSelectWrapper; import prerna.rdf.engine.wrappers.WrapperManager; @@ -26,11 +26,7 @@ public class NoUserExistsFilter implements Filter { @Override public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { - ServletContext context = arg0.getServletContext(); - - boolean security = Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED)); - if(security) { - + if(AbstractSecurityUtils.securityEnabled()) { // i do not want to run this query for every single call // just gets annoying if(!NoUserExistsFilter.userDefined) { @@ -51,7 +47,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 ((HttpServletRequest) arg0).getSession(true).setAttribute(AdminConfigService.ADMIN_REDIRECT_KEY, referer); // this will be the deployment name of the app - String contextPath = context.getContextPath(); + String contextPath = arg0.getServletContext().getContextPath(); // this will be the full path of the request // like http://localhost:8080/Monolith_Dev/api/engine/runPixel diff --git a/src/prerna/web/conf/NoUserInSessionFilter.java b/src/prerna/web/conf/NoUserInSessionFilter.java index 6c2f5d8c6..33ea787fe 100644 --- a/src/prerna/web/conf/NoUserInSessionFilter.java +++ b/src/prerna/web/conf/NoUserInSessionFilter.java @@ -22,6 +22,7 @@ import prerna.auth.AuthProvider; import prerna.auth.InsightToken; import prerna.auth.User; +import prerna.auth.utils.AbstractSecurityUtils; import prerna.util.Constants; import prerna.web.requests.MultiReadHttpServletRequest; @@ -48,8 +49,7 @@ public class NoUserInSessionFilter implements Filter { public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { ServletContext context = arg0.getServletContext(); - boolean security = Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED)); - if(security) { + if(AbstractSecurityUtils.securityEnabled()) { // this will be the full path of the request // like http://localhost:8080/Monolith_Dev/api/engine/runPixel String fullUrl = ((HttpServletRequest) arg0).getRequestURL().toString(); diff --git a/src/prerna/web/conf/UserExistsFilter.java b/src/prerna/web/conf/UserExistsFilter.java index 02fa70cfd..3839c8603 100644 --- a/src/prerna/web/conf/UserExistsFilter.java +++ b/src/prerna/web/conf/UserExistsFilter.java @@ -4,7 +4,6 @@ import javax.servlet.FilterChain; import javax.servlet.FilterConfig; -import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; @@ -13,6 +12,7 @@ import javax.servlet.http.HttpSession; import prerna.auth.User; +import prerna.auth.utils.AbstractSecurityUtils; import prerna.engine.api.IEngine; import prerna.engine.api.IRawSelectWrapper; import prerna.rdf.engine.wrappers.WrapperManager; @@ -23,10 +23,7 @@ public class UserExistsFilter extends NoUserInSessionFilter { @Override public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { - ServletContext context = arg0.getServletContext(); - - boolean security = Boolean.parseBoolean(context.getInitParameter(Constants.SECURITY_ENABLED)); - if(security) { + if(AbstractSecurityUtils.securityEnabled()) { HttpSession session = ((HttpServletRequest) arg0).getSession(true); User user = (User) session.getAttribute(Constants.SESSION_USER); From 5f07848ef7d3f4c2dddecb163a2c07e1f80ded24 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 18 Dec 2018 15:55:48 +0000 Subject: [PATCH 0376/1906] BUGFIX ::: Fixing null pointer with default value not being set in init parameter git-svn-id: svn://107.170.10.188:8080/Monolith/dev@31433 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: abc7e8820f77fda8444ffb23d7c5bbf748eafaac --- src/prerna/web/conf/DBLoader.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/prerna/web/conf/DBLoader.java b/src/prerna/web/conf/DBLoader.java index 3218e6767..e7454727e 100644 --- a/src/prerna/web/conf/DBLoader.java +++ b/src/prerna/web/conf/DBLoader.java @@ -70,8 +70,10 @@ public void contextInitialized(ServletContextEvent arg0) { String securityEnabled = context.getInitParameter(Constants.SECURITY_ENABLED); String adminSetPublicOnly = context.getInitParameter(Constants.ADMIN_SET_PUBLIC); if(adminSetPublicOnly == null) { - context.setInitParameter(Constants.ADMIN_SET_PUBLIC, "false"); + adminSetPublicOnly = "false"; } + context.setInitParameter(Constants.ADMIN_SET_PUBLIC, "false"); + System.out.println("Initializing application context..." + contextPath); //Set default file separator system variable From ffe343d048b351830883b1744fc78030352126c5 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 18 Dec 2018 15:56:36 +0000 Subject: [PATCH 0377/1906] UPDATE ::: Setting variable value correctly git-svn-id: svn://107.170.10.188:8080/Monolith/dev@31434 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: fb2690d6b619e720a05ab828d72f056067a0e1e4 --- src/prerna/web/conf/DBLoader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prerna/web/conf/DBLoader.java b/src/prerna/web/conf/DBLoader.java index e7454727e..b7899ef37 100644 --- a/src/prerna/web/conf/DBLoader.java +++ b/src/prerna/web/conf/DBLoader.java @@ -72,7 +72,7 @@ public void contextInitialized(ServletContextEvent arg0) { if(adminSetPublicOnly == null) { adminSetPublicOnly = "false"; } - context.setInitParameter(Constants.ADMIN_SET_PUBLIC, "false"); + context.setInitParameter(Constants.ADMIN_SET_PUBLIC, adminSetPublicOnly); System.out.println("Initializing application context..." + contextPath); From 0c69bd76c8ec95e4d6e3db6da9a05b88b5d53fd6 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 18 Dec 2018 20:18:21 +0000 Subject: [PATCH 0378/1906] UPDATE ::: Adding if only admin can set public in config call git-svn-id: svn://107.170.10.188:8080/Monolith/dev@31442 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: f28c6962cca7aaca71dd20715757c23fe62e3b4c --- .../web/services/config/ServerConfigurationResource.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/prerna/semoss/web/services/config/ServerConfigurationResource.java b/src/prerna/semoss/web/services/config/ServerConfigurationResource.java index 537603cb3..9f037b11f 100644 --- a/src/prerna/semoss/web/services/config/ServerConfigurationResource.java +++ b/src/prerna/semoss/web/services/config/ServerConfigurationResource.java @@ -62,6 +62,13 @@ private static Map getConfig(@Context HttpServletRequest request // security enabled config.put("security", AbstractSecurityUtils.securityEnabled()); + // r enabled + boolean adminSetPublic = false; + String adminSetPublicStr = DIHelper.getInstance().getProperty(Constants.ADMIN_SET_PUBLIC); + if(adminSetPublicStr != null) { + adminSetPublic = Boolean.parseBoolean(adminSetPublicStr); + } + config.put("adminSetPublic", adminSetPublic); // local mode boolean localMode = false; From 36bff086bac2831299bf64dfc35d899c59cd9e73 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 18 Dec 2018 22:17:05 +0000 Subject: [PATCH 0379/1906] BUGFIX ::: Grabbing correct key for admin set public git-svn-id: svn://107.170.10.188:8080/Monolith/dev@31447 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 5018291037a27352ee6c8c5a337cee1599227826 --- .../semoss/web/services/config/ServerConfigurationResource.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prerna/semoss/web/services/config/ServerConfigurationResource.java b/src/prerna/semoss/web/services/config/ServerConfigurationResource.java index 9f037b11f..5d962f12c 100644 --- a/src/prerna/semoss/web/services/config/ServerConfigurationResource.java +++ b/src/prerna/semoss/web/services/config/ServerConfigurationResource.java @@ -64,7 +64,7 @@ private static Map getConfig(@Context HttpServletRequest request config.put("security", AbstractSecurityUtils.securityEnabled()); // r enabled boolean adminSetPublic = false; - String adminSetPublicStr = DIHelper.getInstance().getProperty(Constants.ADMIN_SET_PUBLIC); + String adminSetPublicStr = (String) DIHelper.getInstance().getLocalProp(Constants.ADMIN_SET_PUBLIC); if(adminSetPublicStr != null) { adminSetPublic = Boolean.parseBoolean(adminSetPublicStr); } From 70fe569d0255d6499ba985284dc2c3fe019f788d Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 21 Dec 2018 14:01:52 +0000 Subject: [PATCH 0380/1906] UPDATE ::: Adding new rest endpoint to connect to survey monkey BUGFIX ::: Fixing errors that occur on shut down git-svn-id: svn://107.170.10.188:8080/Monolith/dev@31483 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 62795fd87f5460c2ccf670fb529b1850c876c2c9 --- .../web/services/local/UserResource.java | 162 ++++++++++++------ src/prerna/web/conf/DBLoader.java | 3 +- 2 files changed, 115 insertions(+), 50 deletions(-) diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index fa8f1f899..6294108c2 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -87,6 +87,7 @@ import prerna.io.connector.google.GoogleListFiles; import prerna.io.connector.google.GoogleProfile; import prerna.io.connector.ms.MSProfile; +import prerna.io.connector.surveymonkey.MonkeyProfile; import prerna.io.connector.twitter.TwitterSearcher; import prerna.om.NLPDocumentInput; import prerna.security.AbstractHttpHelper; @@ -254,6 +255,17 @@ private void addAccessToken(AccessToken token, HttpServletRequest request) { SecurityUpdateUtils.addOAuthUser(token); } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + /** + * User info method calls + */ + + /** * Gets user info for GoogleDrive */ @@ -417,6 +429,18 @@ public Response userinfoGithub(@Context HttpServletRequest request) { } return WebUtility.getResponse(ret, 200); } + + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////////////////////// + + /** + * Login methods + redirect methods + */ + /** * Logs user in through salesforce @@ -497,6 +521,82 @@ private String getSFRedirect(HttpServletRequest request) throws UnsupportedEncod return redirectUrl; } + /** + * Logs user in through survey monkey + */ + @GET + @Produces("application/json") + @Path("/login/surveymonkey") + public Response loginSurveyMonkey(@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException { + /* + * Try to log in the user + * If they are not logged in + * Redirect the FE + */ + + User userObj = (User) request.getSession().getAttribute(Constants.SESSION_USER); + + String queryString = request.getQueryString(); + if(queryString != null && queryString.contains("code=")) { + if(userObj == null || userObj.getAccessToken(AuthProvider.SURVEYMONKEY) == null) { + String[] outputs = AbstractHttpHelper.getCodes(queryString); + + String prefix = "surveymonkey_"; + String clientId = socialData.getProperty(prefix+"client_id"); + String clientSecret = socialData.getProperty(prefix+"secret_key"); + String redirectUri = socialData.getProperty(prefix+"redirect_uri"); + + System.out.println(">> " + request.getQueryString()); + + Hashtable params = new Hashtable(); + params.put("client_id", clientId); + params.put("grant_type", "authorization_code"); + params.put("redirect_uri", redirectUri); + params.put("code", URLDecoder.decode(outputs[0])); + params.put("client_secret", clientSecret); + + String url = "https://api.surveymonkey.com/oauth/token"; + + AccessToken accessToken = AbstractHttpHelper.getAccessToken(url, params, true, true); + if(accessToken == null) { + // not authenticated + response.setStatus(302); + response.sendRedirect(getSurveyMonkeyRedirect(request)); + return null; + } + accessToken.setProvider(AuthProvider.SURVEYMONKEY); + MonkeyProfile.fillAccessToken(accessToken, null); + addAccessToken(accessToken, request); + + System.out.println("Access Token is.. " + accessToken.getAccess_token()); + } + } + + // grab the user again + userObj = (User) request.getSession().getAttribute(Constants.SESSION_USER); + if(userObj == null || userObj.getAccessToken(AuthProvider.SURVEYMONKEY) == null) { + // not authenticated + response.setStatus(302); + response.sendRedirect(getSurveyMonkeyRedirect(request)); + } else { + setMainPageRedirect(request, response, null); + } + return null; + } + + private String getSurveyMonkeyRedirect(HttpServletRequest request) throws UnsupportedEncodingException { + String prefix = "surveymonkey_"; + String clientId = socialData.getProperty(prefix+"client_id"); + String redirectUri = socialData.getProperty(prefix+"redirect_uri"); + + String redirectUrl = "https://api.surveymonkey.com/oauth/authorize?" + + "client_id=" + clientId + + "&response_type=code" + + "&redirect_uri=" + redirectUri; + + System.out.println("Sending redirect.. " + redirectUrl); + return redirectUrl; + } /** * Logs user in through git @@ -1195,7 +1295,7 @@ private String getTwitterRedirect(HttpServletRequest request) throws Unsupported ///////////////////////////////////////////////////////////////// - /* + /** * This portion of code is for semoss generated users */ @@ -1319,7 +1419,7 @@ public Response createUser(@Context HttpServletRequest request) { ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// - /* + /** * Setting / Getting Information from the social properties * That is needed by the FE */ @@ -1434,6 +1534,17 @@ private void setMainPageRedirect(@Context HttpServletRequest request, @Context H } } + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// + + /** + * Sharing session + */ + + @GET @Produces("application/json") @Path("/cookie") @@ -1562,53 +1673,6 @@ public StreamingOutput manCookie(@Context HttpServletRequest request, @Context H return WebUtility.getSO(outputHash); } - // redirect the user after setting session - @GET - @Produces("application/json") - @Path("/red") - public void red(@Context HttpServletRequest request, @Context HttpServletResponse response) { - - - //https://nuwanbando.com/2010/05/07/sharing-https-http-sessions-in-tomcat/ - Cookie[] cookies = request.getCookies(); - boolean done = false; - String sessionId = ""; - if (cookies != null) { - for (Cookie c : cookies) { - if (c.getName().equals("JSESSIONID")) { - sessionId = c.getValue(); - System.out.println("Session id " + sessionId); - - Cookie k = new Cookie("JSESSIONID", sessionId); - // cool blink show if you enable the lower one - //k.setPath(request.getContextPath()); - //k.setPath("/appui"); - //response.addCookie(k); - - k.setPath(request.getContextPath()); - response.addCookie(k); - break; - } - } - } - - System.out.println("Session id set to " + sessionId); - - Cookie p = new Cookie("USER", "prabhuk"); - p.setPath(request.getContextPath()); - response.addCookie(p); - - try { - response.sendRedirect("http://localhost:9090/Monolith/api/engine/all"); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - - - } - - @GET @Produces("application/json") @Path("/whoami") diff --git a/src/prerna/web/conf/DBLoader.java b/src/prerna/web/conf/DBLoader.java index b7899ef37..dd08de8bf 100644 --- a/src/prerna/web/conf/DBLoader.java +++ b/src/prerna/web/conf/DBLoader.java @@ -27,6 +27,7 @@ *******************************************************************************/ package prerna.web.conf; +import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.Vector; @@ -155,7 +156,7 @@ public void loadEngines() { public void contextDestroyed(ServletContextEvent arg0) { System.out.println("Start shutdown"); - Set insights = InsightStore.getInstance().getAllInsights(); + Set insights = new HashSet(InsightStore.getInstance().getAllInsights()); for(String id : insights) { Insight in = InsightStore.getInstance().get(id); System.out.println("Closing insight " + id); From c3963b357ab215dabdc6c0564a41a116c4238f3f Mon Sep 17 00:00:00 2001 From: tbanach Date: Mon, 7 Jan 2019 15:35:16 +0000 Subject: [PATCH 0381/1906] UPDATE ::: Adding DBUnit to the pom git-svn-id: svn://107.170.10.188:8080/Monolith/dev@31555 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 4526460352315123ff52d97cf4b4c14778baaf4e --- pom.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pom.xml b/pom.xml index 847c2747e..920779311 100644 --- a/pom.xml +++ b/pom.xml @@ -2895,5 +2895,16 @@ + + org.dbunit + dbunit + 2.6.0 + + + * + * + + + \ No newline at end of file From f117a6f42b59b35c4b4ee2e0b3d73b273fb06914 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 8 Jan 2019 00:34:48 +0000 Subject: [PATCH 0382/1906] UPDATE ::: Making everything UTF-8 compatible git-svn-id: svn://107.170.10.188:8080/Monolith/dev@31576 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 81a0702d14801ba3b23c61036450e884c1e80efb --- WebContent/WEB-INF/web.xml | 14 ++++++++ .../semoss/web/services/local/NameServer.java | 4 +-- src/prerna/web/conf/UTFEncodeFilter.java | 34 +++++++++++++++++++ 3 files changed, 50 insertions(+), 2 deletions(-) create mode 100644 src/prerna/web/conf/UTFEncodeFilter.java diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index 7f6a9ddef..e4593c2b9 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -5,6 +5,20 @@ index.html + + + SetCharacterEncoding + org.apache.catalina.filters.SetCharacterEncodingFilter + + encoding + UTF-8 + + + + SetCharacterEncoding + /* + + StartUpSuccessFilter diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index 1bbb2bb21..a8582f3b5 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -317,7 +317,7 @@ public Response getInsightImage(@Context HttpServletRequest request, @QueryParam @POST @Path("/runPixel") - @Produces("application/json") + @Produces("application/json;charset=utf-8") public Response runPixelSync(@Context HttpServletRequest request){ // I need to do a couple of things here // I need to get the basic blocking queue as a singleton @@ -439,7 +439,7 @@ public Response runPixelSync(@Context HttpServletRequest request){ @POST @Path("runPixelAsync") - @Produces("application/json") + @Produces("application/json;charset=utf-8") public Response runPixelAsync(@Context HttpServletRequest request) { boolean securityEnabled = AbstractSecurityUtils.securityEnabled(); HttpSession session = null; diff --git a/src/prerna/web/conf/UTFEncodeFilter.java b/src/prerna/web/conf/UTFEncodeFilter.java new file mode 100644 index 000000000..8a57ad457 --- /dev/null +++ b/src/prerna/web/conf/UTFEncodeFilter.java @@ -0,0 +1,34 @@ +package prerna.web.conf; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; + +public class UTFEncodeFilter implements Filter { + + @Override + public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { + arg0.setCharacterEncoding("utf-8"); + arg1.setCharacterEncoding("utf-8"); + arg1.setContentType("text/html;charset=utf-8"); + arg2.doFilter(arg0, arg1); + } + + @Override + public void destroy() { + // TODO Auto-generated method stub + + } + + @Override + public void init(FilterConfig arg0) throws ServletException { + // TODO Auto-generated method stub + + } + +} From cb6923b1b6feb646d62fb788b03bc56e0f894ab6 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 9 Jan 2019 20:08:34 +0000 Subject: [PATCH 0383/1906] UPDATE ::: Fixing back web.xml to be Monolith_Dev instead of Monolith git-svn-id: svn://107.170.10.188:8080/Monolith/dev@31625 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: fe9316fd690d5ca69065ffc7d289e44fb6744380 --- WebContent/WEB-INF/web.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index e4593c2b9..202b807d0 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -1,6 +1,6 @@ - Monolith + Monolith_Dev index.html From b4cb3ac326f41067f2f134fffa2072afe077205d Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 9 Jan 2019 23:05:24 +0000 Subject: [PATCH 0384/1906] UPDATE ::: Accounting for h2 format to ensure it still ends with .mv.db as it is required for proper connection git-svn-id: svn://107.170.10.188:8080/Monolith/dev@31632 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: aa0f73496d5653fc2b2ca183d538afcb74a0f633 --- src/prerna/upload/FileUploader.java | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/prerna/upload/FileUploader.java b/src/prerna/upload/FileUploader.java index 9158b1f03..3ce093ddf 100644 --- a/src/prerna/upload/FileUploader.java +++ b/src/prerna/upload/FileUploader.java @@ -18,6 +18,7 @@ import javax.ws.rs.core.Response; import org.apache.commons.fileupload.FileItem; +import org.apache.commons.io.FilenameUtils; import org.apache.log4j.LogManager; import org.apache.log4j.Logger; @@ -85,7 +86,22 @@ private List> getBaseUploadData(List fileItems) { Date date = new Date(); String modifiedDate = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_SSSS").format(date); - String fileLocation = this.filePath + fileName.substring(fileName.lastIndexOf(DIR_SEPARATOR) + 1, fileName.lastIndexOf(".")).trim().replace(" ", "_") + "_____UNIQUE" + modifiedDate + fileName.substring(fileName.lastIndexOf(".")); + String fileLocation = null; + // account for upload of an h2 + // the connection url requires it to end with .mv.db + // otherwise it errors + if(fileName.endsWith(".mv.db")) { + fileLocation = this.filePath + FilenameUtils.getBaseName(fileName).trim().replace(".mv", "").replace(" ", "_") + + "_____UNIQUE" + + modifiedDate + + ".mv.db"; + } else { + fileLocation = this.filePath + FilenameUtils.getBaseName(fileName).trim().replace(" ", "_") + + "_____UNIQUE" + + modifiedDate + + "." + + FilenameUtils.getExtension(fileName); + } File file = new File(fileLocation); writeFile(fi, file); From 4d56e5d9f8aa94f4858e6fe14c06fd84c3d1f6d4 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 11 Jan 2019 01:29:30 +0000 Subject: [PATCH 0385/1906] UPDATE ::: Removing redundant code so only single static method for dropping an insight UPDATE ::: Dropping and clearing and insight is now synchronized for a specific insight to prevent multiple threads attempting to drop the same insight causing concurrent modification exceptions UPDATE ::: Adding single method for the FE to drop all insights + invalidate a session UPDATE ::: Adding method to cancel invalidating a session (but still dropping the insights) when the browser is refreshed git-svn-id: svn://107.170.10.188:8080/Monolith/dev@31646 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 5ba91b20db560d87ad56997ff08cbc368c913873 --- .../semoss/web/services/local/NameServer.java | 79 ++++++++++++++++++- .../web/services/local/UserResource.java | 13 +-- src/prerna/upload/DatabaseUploader.java | 2 +- src/prerna/web/conf/UserSessionLoader.java | 79 +++++-------------- 4 files changed, 104 insertions(+), 69 deletions(-) diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index a8582f3b5..91e53f390 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -38,9 +38,11 @@ import java.util.Date; import java.util.Enumeration; import java.util.HashMap; +import java.util.HashSet; import java.util.Hashtable; import java.util.List; import java.util.Map; +import java.util.Set; import javax.servlet.ServletContext; import javax.servlet.http.Cookie; @@ -69,6 +71,8 @@ import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; +import org.apache.log4j.LogManager; +import org.apache.log4j.Logger; import org.jsoup.Jsoup; import com.google.gson.Gson; @@ -101,6 +105,7 @@ import prerna.util.DIHelper; import prerna.util.PlaySheetRDFMapBasedEnum; import prerna.util.Utility; +import prerna.util.insight.InsightUtility; import prerna.web.services.util.ResponseHashSingleton; import prerna.web.services.util.SemossExecutorSingleton; import prerna.web.services.util.SemossThread; @@ -109,11 +114,83 @@ @Path("/engine") public class NameServer { - private PyExecutorThread jepThread; + private static final Logger LOGGER = LogManager.getLogger(NameServer.class.getName()); + private static final String CANCEL_INVALIDATION = "cancelInvalidation"; + private PyExecutorThread jepThread; + @Context protected ServletContext context; + //////////////////////////////////////////////////////////////////////////////// + + /* + * End points for cleanup of the thread to account for closing/opening + */ + + @POST + @Path("/cleanSession") + public Response cleanSession(@Context HttpServletRequest request) { + HttpSession session = request.getSession(false); + if(session == null) { + return Response.status(400).entity("Invalid session").build(); + } + String sessionId = session.getId(); + // clear up insight store + InsightStore inStore = InsightStore.getInstance(); + Set insightIDs = inStore.getInsightIDsForSession(sessionId); + if(insightIDs != null) { + Set copy = new HashSet(insightIDs); + for(String insightId : copy) { + Insight insight = InsightStore.getInstance().get(insightId); + if(insight == null) { + continue; + } + InsightUtility.dropInsight(insight); + } + LOGGER.info("successfully removed insight information from session"); + + // clear the current session store + insightIDs.removeAll(copy); + } + + try { + Thread.sleep(1000); + } catch(InterruptedException e) { + e.printStackTrace(); + } + + // did the FE at any point cancel this clean? + Boolean cancelInvlidation = (Boolean) session.getAttribute(CANCEL_INVALIDATION); + // we never actually set this to true or false + // it is either null or not, but w/e + String output = null; + if(cancelInvlidation == null || !cancelInvlidation) { + // kill the entire session + session.invalidate(); + output = "invalidated"; + } else { + // just remove the attribute + session.removeAttribute(CANCEL_INVALIDATION); + output = "cancelled"; + } + + return Response.status(200).entity(output).build(); + } + + @POST + @Path("/cancelCleanSession") + public Response cancelCleanSession(@Context HttpServletRequest request) { + HttpSession session = request.getSession(false); + if(session == null) { + return Response.status(400).entity("Invalid session").build(); + } + session.setAttribute(CANCEL_INVALIDATION, true); + return Response.status(200).entity("cancel").build(); + } + + //////////////////////////////////////////////////////////////////////////////// + // uploader functionality @Path("/uploadDatabase") public Uploader uploadDatabase(@Context HttpServletRequest request) { diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index 6294108c2..0a5d599e6 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -63,6 +63,8 @@ import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.PropertiesConfiguration; +import org.apache.log4j.LogManager; +import org.apache.log4j.Logger; import org.kohsuke.github.GHMyself; import org.kohsuke.github.GitHub; @@ -101,6 +103,8 @@ @Path("/auth") public class UserResource { + private static final Logger LOGGER = LogManager.getLogger(UserResource.class.getName()); + private static Properties socialData = null; private static Map loginsAllowed; @@ -197,6 +201,8 @@ public Response logout(@PathParam("provider") String provider, @Context HttpServ // redirect the user // and invalidate the session if(noUser && AbstractSecurityUtils.securityEnabled()) { + LOGGER.info("User is no longer logged in"); + LOGGER.info("Removing user object from session"); session.removeAttribute(Constants.SESSION_USER); // well, you have logged out and we always require a login // so i will redirect you @@ -208,16 +214,11 @@ public Response logout(@PathParam("provider") String provider, @Context HttpServ // remove the cookie from the browser // for the session id + LOGGER.info("Removing session token"); Cookie cookie = new Cookie("JSESSIONID", null); cookie.setPath("/"); repsonse.addCookie(cookie); - // kill the user python thread here - if(PyUtils.pyEnabled()) { - PyExecutorThread pyThread = (PyExecutorThread) session.getAttribute(Constants.PYTHON); - PyUtils.getInstance().killPyThread(pyThread); - } - // invalidate the session session.invalidate(); return null; diff --git a/src/prerna/upload/DatabaseUploader.java b/src/prerna/upload/DatabaseUploader.java index 679c2eebb..e0285bf6b 100644 --- a/src/prerna/upload/DatabaseUploader.java +++ b/src/prerna/upload/DatabaseUploader.java @@ -62,7 +62,7 @@ import prerna.sablecc2.reactor.PixelPlanner; import prerna.sablecc2.reactor.app.upload.UploadInputUtility; import prerna.sablecc2.reactor.app.upload.UploadUtilities; -import prerna.sablecc2.reactor.app.upload.gremlin.TinkerCsvUploadReactor; +import prerna.sablecc2.reactor.app.upload.gremlin.file.TinkerCsvUploadReactor; import prerna.sablecc2.reactor.app.upload.rdbms.csv.RdbmsCsvUploadReactor; import prerna.sablecc2.reactor.app.upload.rdbms.external.ExternalJdbcSchemaReactor; import prerna.sablecc2.reactor.app.upload.rdbms.external.RdbmsExternalUploadReactor; diff --git a/src/prerna/web/conf/UserSessionLoader.java b/src/prerna/web/conf/UserSessionLoader.java index 690ec365e..31fe91ee1 100644 --- a/src/prerna/web/conf/UserSessionLoader.java +++ b/src/prerna/web/conf/UserSessionLoader.java @@ -1,38 +1,35 @@ package prerna.web.conf; -import java.io.File; import java.util.HashSet; -import java.util.List; -import java.util.Map; import java.util.Set; import javax.servlet.annotation.WebListener; +import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; import org.apache.log4j.LogManager; import org.apache.log4j.Logger; -import prerna.algorithm.api.ITableDataFrame; +import prerna.ds.py.PyExecutorThread; +import prerna.ds.py.PyUtils; import prerna.om.Insight; import prerna.om.InsightStore; -import prerna.sablecc2.om.PixelDataType; -import prerna.sablecc2.om.VarStore; -import prerna.sablecc2.om.nounmeta.NounMetadata; -import prerna.sablecc2.om.task.TaskStore; -import prerna.sablecc2.reactor.imports.FileMeta; +import prerna.util.Constants; +import prerna.util.insight.InsightUtility; @WebListener public class UserSessionLoader implements HttpSessionListener { - protected static final Logger LOGGER = LogManager.getLogger(UserSessionLoader.class.getName()); + private static final Logger LOGGER = LogManager.getLogger(UserSessionLoader.class.getName()); public void sessionCreated(HttpSessionEvent sessionEvent) { } public void sessionDestroyed(HttpSessionEvent sessionEvent) { - String sessionId = sessionEvent.getSession().getId(); + HttpSession session = sessionEvent.getSession(); + String sessionId = session.getId(); // clear up insight store InsightStore inStore = InsightStore.getInstance(); @@ -45,61 +42,21 @@ public void sessionDestroyed(HttpSessionEvent sessionEvent) { continue; } LOGGER.info("Trying to drop insight " + insightId); - - InsightStore.getInstance().remove(insightId); - LOGGER.info("Successfully removed insight from insight store"); - - // drop all the tasks that are currently running - TaskStore taskStore = insight.getTaskStore(); - taskStore.clearAllTasks(); - LOGGER.info("Successfully cleared all stored Tasks for the insight"); - - // drop all the frame connections - VarStore varStore = insight.getVarStore(); - Set keys = varStore.getKeys(); - // find all the vars which are frames - // and drop them - for(String key : keys) { - NounMetadata noun = varStore.get(key); - PixelDataType nType = noun.getNounType(); - if(nType == PixelDataType.FRAME) { - ITableDataFrame dm = (ITableDataFrame) noun.getValue(); - dm.setLogger(LOGGER); - dm.close(); - } - } - LOGGER.info("Successfully removed all frames from insight"); - - insight.getVarStore().clear(); - LOGGER.info("Successfully removed all variables from varstore"); - - // also delete any files that were used - List fileData = insight.getFilesUsedInInsight(); - if (fileData != null && !fileData.isEmpty()) { - for (int fileIdx = 0; fileIdx < fileData.size(); fileIdx++) { - FileMeta file = fileData.get(fileIdx); - File f = new File(file.getFileLoc()); - f.delete(); - LOGGER.info("Successfully deleted File used in insight " + f.getName()); - } - } - - Map fileExports = insight.getExportFiles(); - if (fileExports != null && !fileExports.isEmpty()) { - for (String fileKey : fileExports.keySet()){ - File f = new File(fileExports.get(fileKey)); - f.delete(); - LOGGER.info("Successfully deleted File used in insight " + f.getName()); - } - } - - LOGGER.info("Successfully removed insight"); + InsightUtility.dropInsight(insight); + LOGGER.info("Dropped insight " + insightId); } - System.out.println("successfully removed insight information from session"); + LOGGER.info("successfully removed insight information from session"); // clear the current session store insightIDs.removeAll(copy); } + + // now drop the thread + if(PyUtils.pyEnabled()) { + LOGGER.info("Drop session py thread"); + PyExecutorThread pyThread = (PyExecutorThread) session.getAttribute(Constants.PYTHON); + PyUtils.getInstance().killPyThread(pyThread); + } } } \ No newline at end of file From cca3d2537ad6f11177e18878b7fcef3f7d062f99 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 11 Jan 2019 01:31:15 +0000 Subject: [PATCH 0386/1906] UPDATE ::: Setting timeout to 10 seconds git-svn-id: svn://107.170.10.188:8080/Monolith/dev@31647 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 659fa9db0d70db8ffe16891a94d1ca86e24b0dfb --- src/prerna/semoss/web/services/local/NameServer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index 91e53f390..7fc161627 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -155,7 +155,7 @@ public Response cleanSession(@Context HttpServletRequest request) { } try { - Thread.sleep(1000); + Thread.sleep(10 * 1000); } catch(InterruptedException e) { e.printStackTrace(); } From 8a94674760359b92ea4b3fde5097b25570e177be Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 11 Jan 2019 01:38:50 +0000 Subject: [PATCH 0387/1906] UPDATE ::: Adding additional logger for clarity git-svn-id: svn://107.170.10.188:8080/Monolith/dev@31649 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: b227d6c214922009d7f76203e82c848f1d8173b1 --- src/prerna/semoss/web/services/local/NameServer.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index 7fc161627..cb54deaa0 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -148,7 +148,7 @@ public Response cleanSession(@Context HttpServletRequest request) { } InsightUtility.dropInsight(insight); } - LOGGER.info("successfully removed insight information from session"); + LOGGER.info("Successfully removed insight information from session"); // clear the current session store insightIDs.removeAll(copy); @@ -167,9 +167,13 @@ public Response cleanSession(@Context HttpServletRequest request) { String output = null; if(cancelInvlidation == null || !cancelInvlidation) { // kill the entire session + LOGGER.info("Invalidating session"); + session.invalidate(); output = "invalidated"; } else { + LOGGER.info("Cancelled invalidating session"); + // just remove the attribute session.removeAttribute(CANCEL_INVALIDATION); output = "cancelled"; @@ -185,6 +189,7 @@ public Response cancelCleanSession(@Context HttpServletRequest request) { if(session == null) { return Response.status(400).entity("Invalid session").build(); } + LOGGER.info("Cancelling invalidation..."); session.setAttribute(CANCEL_INVALIDATION, true); return Response.status(200).entity("cancel").build(); } From ea22c830e2f14616d93200358e1d24d52bcf8e27 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 11 Jan 2019 02:23:50 +0000 Subject: [PATCH 0388/1906] UPDATE ::: Simplifying logs as they are printing out too many lines for dropping insights UPDATE ::: Allowing clean session endpoints to bypass the redirect since it prevents the browser from properly making the endpoint call BUGFIX ::: Adding check to make sure session clean up has not occurred via another process (i.e. if you refresh then sign out quickly) git-svn-id: svn://107.170.10.188:8080/Monolith/dev@31650 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: c2906f519d28090be7d4624a4c6b66eb8f5935d4 --- .../semoss/web/services/local/NameServer.java | 39 ++++++++++++------- .../web/services/local/UserResource.java | 1 - .../web/conf/NoUserInSessionFilter.java | 6 +++ 3 files changed, 30 insertions(+), 16 deletions(-) diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index cb54deaa0..91e09d74d 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -135,6 +135,7 @@ public Response cleanSession(@Context HttpServletRequest request) { if(session == null) { return Response.status(400).entity("Invalid session").build(); } + LOGGER.info("Start invalidation of session"); String sessionId = session.getId(); // clear up insight store InsightStore inStore = InsightStore.getInstance(); @@ -155,28 +156,36 @@ public Response cleanSession(@Context HttpServletRequest request) { } try { - Thread.sleep(10 * 1000); + Thread.sleep(7 * 1000); } catch(InterruptedException e) { e.printStackTrace(); } - // did the FE at any point cancel this clean? - Boolean cancelInvlidation = (Boolean) session.getAttribute(CANCEL_INVALIDATION); - // we never actually set this to true or false - // it is either null or not, but w/e + // in case during the time this was called + // the session has been invalidated by some other means + // like a logout String output = null; - if(cancelInvlidation == null || !cancelInvlidation) { - // kill the entire session - LOGGER.info("Invalidating session"); + if(request.isRequestedSessionIdValid()) { + // did the FE at any point cancel this clean? + Boolean cancelInvlidation = (Boolean) session.getAttribute(CANCEL_INVALIDATION); + // we never actually set this to true or false + // it is either null or not, but w/e + if(cancelInvlidation == null || !cancelInvlidation) { + // kill the entire session + LOGGER.info("Invalidating session"); + + session.invalidate(); + output = "invalidated"; + } else { + LOGGER.info("Cancelled invalidating session"); - session.invalidate(); - output = "invalidated"; + // just remove the attribute + session.removeAttribute(CANCEL_INVALIDATION); + output = "cancelled"; + } } else { - LOGGER.info("Cancelled invalidating session"); - - // just remove the attribute - session.removeAttribute(CANCEL_INVALIDATION); - output = "cancelled"; + LOGGER.info("Session has already been invalidated"); + output = "invalidated"; } return Response.status(200).entity(output).build(); diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index 0a5d599e6..b0a73aedd 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -80,7 +80,6 @@ import prerna.auth.utils.NativeUserSecurityUtils; import prerna.auth.utils.SecurityAdminUtils; import prerna.auth.utils.SecurityUpdateUtils; -import prerna.ds.py.PyExecutorThread; import prerna.ds.py.PyUtils; import prerna.io.connector.IConnectorIOp; import prerna.io.connector.google.GoogleEntityResolver; diff --git a/src/prerna/web/conf/NoUserInSessionFilter.java b/src/prerna/web/conf/NoUserInSessionFilter.java index 33ea787fe..23acd0be0 100644 --- a/src/prerna/web/conf/NoUserInSessionFilter.java +++ b/src/prerna/web/conf/NoUserInSessionFilter.java @@ -34,6 +34,12 @@ public class NoUserInSessionFilter implements Filter { protected static List ignoreDueToFE = new Vector(); static { + // allow these for successful dropping of + // sessions when browser is closed/refreshed + // these do their own session checks + ignoreDueToFE.add("engine/cleanSession"); + ignoreDueToFE.add("engine/cancelCleanSession"); + ignoreDueToFE.add("config"); ignoreDueToFE.add("auth/logins"); ignoreDueToFE.add("auth/loginsAllowed"); From 52572583c381f9e86e2f9c9e59aefca95621617e Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 11 Jan 2019 20:45:44 +0000 Subject: [PATCH 0389/1906] UPDATE ::: Fixing logic logout to account for multiple refreshes occurring by same user within the time delay for session cancellation to occur git-svn-id: svn://107.170.10.188:8080/Monolith/dev@31666 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: f3e894546e7d8662bb7ac3471f0d4fc6d5a652dd --- .../semoss/web/services/local/NameServer.java | 59 +++++++++++-------- 1 file changed, 34 insertions(+), 25 deletions(-) diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index 91e09d74d..142f0184f 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -43,6 +43,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.atomic.AtomicInteger; import javax.servlet.ServletContext; import javax.servlet.http.Cookie; @@ -118,21 +119,22 @@ public class NameServer { private static final String CANCEL_INVALIDATION = "cancelInvalidation"; private PyExecutorThread jepThread; - + @Context protected ServletContext context; //////////////////////////////////////////////////////////////////////////////// - + /* * End points for cleanup of the thread to account for closing/opening */ - + @POST @Path("/cleanSession") public Response cleanSession(@Context HttpServletRequest request) { HttpSession session = request.getSession(false); if(session == null) { + LOGGER.info("Invalid session for cleaning"); return Response.status(400).entity("Invalid session").build(); } LOGGER.info("Start invalidation of session"); @@ -150,47 +152,50 @@ public Response cleanSession(@Context HttpServletRequest request) { InsightUtility.dropInsight(insight); } LOGGER.info("Successfully removed insight information from session"); - + // clear the current session store insightIDs.removeAll(copy); } - + + // wait 10 seconds try { - Thread.sleep(7 * 1000); - } catch(InterruptedException e) { - e.printStackTrace(); + Thread.sleep(10000); + } catch (InterruptedException e1) { + e1.printStackTrace(); } - - // in case during the time this was called - // the session has been invalidated by some other means - // like a logout + String output = null; if(request.isRequestedSessionIdValid()) { // did the FE at any point cancel this clean? - Boolean cancelInvlidation = (Boolean) session.getAttribute(CANCEL_INVALIDATION); - // we never actually set this to true or false - // it is either null or not, but w/e - if(cancelInvlidation == null || !cancelInvlidation) { + AtomicInteger aInt = (AtomicInteger) session.getAttribute(CANCEL_INVALIDATION); + if(aInt == null) { // kill the entire session LOGGER.info("Invalidating session"); - session.invalidate(); output = "invalidated"; } else { - LOGGER.info("Cancelled invalidating session"); - - // just remove the attribute - session.removeAttribute(CANCEL_INVALIDATION); - output = "cancelled"; + int value = aInt.getAndDecrement(); + if(value < 0) { + // kill the entire session + LOGGER.info("Invalidating session"); + session.invalidate(); + output = "invalidated"; + } else { + LOGGER.info("Cancelled invalidating session"); + output = "cancelled"; + } } } else { + // in case during the time this was called + // the session has been invalidated by some other means + // like a logout LOGGER.info("Session has already been invalidated"); output = "invalidated"; } - + return Response.status(200).entity(output).build(); } - + @POST @Path("/cancelCleanSession") public Response cancelCleanSession(@Context HttpServletRequest request) { @@ -199,7 +204,11 @@ public Response cancelCleanSession(@Context HttpServletRequest request) { return Response.status(400).entity("Invalid session").build(); } LOGGER.info("Cancelling invalidation..."); - session.setAttribute(CANCEL_INVALIDATION, true); + AtomicInteger aInt = (AtomicInteger) session.getAttribute(CANCEL_INVALIDATION); + if(aInt == null) { + aInt = new AtomicInteger(1); + session.setAttribute(CANCEL_INVALIDATION, aInt); + } return Response.status(200).entity("cancel").build(); } From cff6d69ceeaa708886ee483ea365dea9e55dc285 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 14 Jan 2019 19:11:29 +0000 Subject: [PATCH 0390/1906] UPDATE ::: Shifting from counter to a time comparison for invalidating session git-svn-id: svn://107.170.10.188:8080/Monolith/dev@31674 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 68a6b49255c7989315d40707dca5c2acdb62702e --- .../semoss/web/services/local/NameServer.java | 32 +++++++++++-------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index 142f0184f..ea66f54c2 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -43,7 +43,6 @@ import java.util.List; import java.util.Map; import java.util.Set; -import java.util.concurrent.atomic.AtomicInteger; import javax.servlet.ServletContext; import javax.servlet.http.Cookie; @@ -117,7 +116,8 @@ public class NameServer { private static final Logger LOGGER = LogManager.getLogger(NameServer.class.getName()); private static final String CANCEL_INVALIDATION = "cancelInvalidation"; - + private Object lock = new Object(); + private PyExecutorThread jepThread; @Context @@ -132,6 +132,10 @@ public class NameServer { @POST @Path("/cleanSession") public Response cleanSession(@Context HttpServletRequest request) { + // need to compare when this method was called + // to a potential cancellation + Date execTime = new Date(); + HttpSession session = request.getSession(false); if(session == null) { LOGGER.info("Invalid session for cleaning"); @@ -167,22 +171,25 @@ public Response cleanSession(@Context HttpServletRequest request) { String output = null; if(request.isRequestedSessionIdValid()) { // did the FE at any point cancel this clean? - AtomicInteger aInt = (AtomicInteger) session.getAttribute(CANCEL_INVALIDATION); - if(aInt == null) { + Date cancelTime = null; + synchronized(lock) { + cancelTime = (Date) session.getAttribute(CANCEL_INVALIDATION); + } + if(cancelTime == null) { // kill the entire session LOGGER.info("Invalidating session"); session.invalidate(); output = "invalidated"; } else { - int value = aInt.getAndDecrement(); - if(value < 0) { + boolean isCancelled = execTime.before(cancelTime); + if(isCancelled) { + LOGGER.info("Cancelled invalidating session"); + output = "cancelled"; + } else { // kill the entire session LOGGER.info("Invalidating session"); session.invalidate(); output = "invalidated"; - } else { - LOGGER.info("Cancelled invalidating session"); - output = "cancelled"; } } } else { @@ -204,10 +211,9 @@ public Response cancelCleanSession(@Context HttpServletRequest request) { return Response.status(400).entity("Invalid session").build(); } LOGGER.info("Cancelling invalidation..."); - AtomicInteger aInt = (AtomicInteger) session.getAttribute(CANCEL_INVALIDATION); - if(aInt == null) { - aInt = new AtomicInteger(1); - session.setAttribute(CANCEL_INVALIDATION, aInt); + Date d = new Date(); + synchronized(lock) { + session.setAttribute(CANCEL_INVALIDATION, d); } return Response.status(200).entity("cancel").build(); } From 50ed0b25c3c7530f6f52e9e907635c7b9c768ee4 Mon Sep 17 00:00:00 2001 From: tbanach Date: Wed, 16 Jan 2019 20:32:07 +0000 Subject: [PATCH 0391/1906] REQUIREMENT ::: Maven update BUGFIX ::: Removing ws4j jar which conflicts with JUnit version git-svn-id: svn://107.170.10.188:8080/Monolith/dev@31718 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 60e85c0c4a083b06a7de53f7469ee7734cd4d1e3 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 920779311..f3423fc3c 100644 --- a/pom.xml +++ b/pom.xml @@ -2265,7 +2265,7 @@ - + org.rosuda.REngine Rserve From 5ea0e74830c974e94f633beb09d3370c8617b812 Mon Sep 17 00:00:00 2001 From: tbanach Date: Wed, 16 Jan 2019 22:30:38 +0000 Subject: [PATCH 0392/1906] BUGFIX ::: Changing the scope of Junit to normal (not test) so that it can be used to compile tests residing in the rest of the SEMOSS source code. (Needed for GitLab runner, not eclipse...) git-svn-id: svn://107.170.10.188:8080/Monolith/dev@31725 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 721f51ad0f68bc3f521dd7daa6f2f96d552a25ac --- pom.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/pom.xml b/pom.xml index f3423fc3c..2cc79ab71 100644 --- a/pom.xml +++ b/pom.xml @@ -2432,7 +2432,6 @@ junit junit 4.12 - test - + + org.apache.tika tika-core From 7a54e0943328874435ae68066b61f7f110ee39ef Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 8 Feb 2019 17:13:59 +0000 Subject: [PATCH 0397/1906] UPDATE ::: Starting to build out insight lvl security calls UPDATE ::: Modifying FE to loop through different key in map for ng-repeat through all the insights git-svn-id: svn://107.170.10.188:8080/Monolith/dev@31978 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: c9b98999c87ec595d78f3844773a4174e11bd1ba --- .../semoss/web/app/MonolithApplication.java | 3 + .../semoss/web/services/local/NameServer.java | 9 +-- .../auth/InsightAuthorizationResource.java | 64 +++++++++++++++++++ 3 files changed, 72 insertions(+), 4 deletions(-) create mode 100644 src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java diff --git a/src/prerna/semoss/web/app/MonolithApplication.java b/src/prerna/semoss/web/app/MonolithApplication.java index ef2d87026..5fda1433c 100644 --- a/src/prerna/semoss/web/app/MonolithApplication.java +++ b/src/prerna/semoss/web/app/MonolithApplication.java @@ -41,6 +41,7 @@ import prerna.semoss.web.services.local.ShareInsightResource; import prerna.semoss.web.services.local.ThemeResource; import prerna.semoss.web.services.local.UserResource; +import prerna.semoss.web.services.local.auth.InsightAuthorizationResource; public class MonolithApplication extends Application { @@ -50,7 +51,9 @@ public MonolithApplication() { singletons.add(new UserResource()); singletons.add(new NameServer()); singletons.add(new AppResource()); + // authorization resources singletons.add(new AuthorizationResource()); + singletons.add(new InsightAuthorizationResource()); singletons.add(new ThemeResource()); singletons.add(new ShareInsightResource()); singletons.add(new FormResource()); diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index a02de7b56..e0789b809 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -81,6 +81,7 @@ import prerna.auth.User; import prerna.auth.utils.AbstractSecurityUtils; +import prerna.auth.utils.SecurityInsightUtils; import prerna.auth.utils.SecurityQueryUtils; import prerna.ds.py.PyExecutorThread; import prerna.ds.py.PyUtils; @@ -1081,9 +1082,9 @@ public StreamingOutput getAutoCompleteResults(@QueryParam("completeTerm") String if(securityEnabled) { HttpSession session = request.getSession(false); User user = (User) session.getAttribute(Constants.SESSION_USER); - searchResults = SecurityQueryUtils.predictUserInsightSearch(user, searchString, "15", "0"); + searchResults = SecurityInsightUtils.predictUserInsightSearch(user, searchString, "15", "0"); } else { - searchResults = SecurityQueryUtils.predictInsightSearch(searchString, "15", "0"); + searchResults = SecurityInsightUtils.predictInsightSearch(searchString, "15", "0"); } return WebUtility.getSO(searchResults); } @@ -1118,9 +1119,9 @@ public StreamingOutput getSearchInsightsResults(MultivaluedMap f // filter insights based on what the user has access to HttpSession session = request.getSession(false); User user = ((User) session.getAttribute(Constants.SESSION_USER)); - queryResults = SecurityQueryUtils.searchUserInsightDataByName(user, searchString, limit, offset); + queryResults = SecurityInsightUtils.searchUserInsightDataByName(user, searchString, limit, offset); } else { - queryResults = SecurityQueryUtils.searchAllInsightDataByName(searchString, limit, offset); + queryResults = SecurityInsightUtils.searchAllInsightDataByName(searchString, limit, offset); } return WebUtility.getSO(queryResults); diff --git a/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java new file mode 100644 index 000000000..ecc8e217f --- /dev/null +++ b/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java @@ -0,0 +1,64 @@ +package prerna.semoss.web.services.local.auth; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.Response; + +import prerna.auth.User; +import prerna.auth.utils.SecurityInsightUtils; +import prerna.semoss.web.services.local.ResourceUtility; +import prerna.web.services.util.WebUtility; + +@Path("/auth/insight") +public class InsightAuthorizationResource { + + /** + * Get the user insight permissions for a given insight + * @param request + * @param form + * @return + */ + @POST + @Produces("application/json") + @Path("getInsightUsers") + public Response getInsightUsers(@Context HttpServletRequest request, MultivaluedMap form) { + User user = null; + try { + user = ResourceUtility.getUser(request); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap(); + errorMap.put("error", "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + + String appId = form.getFirst("appId"); + String insightId = form.getFirst("insightId"); + + // can the user view this insight to see the permissions + if(!SecurityInsightUtils.userCanViewInsight(user, appId, insightId)) { + Map errorMap = new HashMap(); + errorMap.put("error", "App/Insight id are invalid or user does not have access to view this insight"); + return WebUtility.getResponse(errorMap, 401); + } + + List> ret = null; + try { + ret = SecurityInsightUtils.getInsightUsers(user, appId, insightId); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap(); + errorMap.put("error", "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + + return WebUtility.getResponse(ret, 200); + } + +} From 1160a875d0f9edfb116069fde61c7e4f5c5484f5 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 8 Feb 2019 17:23:58 +0000 Subject: [PATCH 0398/1906] UPDATE ::: Adding rest endpoint to get the user insight permission /auth/insight/getUserInsightPermission git-svn-id: svn://107.170.10.188:8080/Monolith/dev@31979 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 066504894532d15c5a306c5e1606596db3726c9c --- .../auth/InsightAuthorizationResource.java | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java index ecc8e217f..c201bb25b 100644 --- a/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java @@ -20,6 +20,41 @@ @Path("/auth/insight") public class InsightAuthorizationResource { + /** + * Get the user insight permissions for a given insight + * @param request + * @param form + * @return + */ + @POST + @Produces("application/json") + @Path("getUserInsightPermission") + public Response getUserInsightPermission(@Context HttpServletRequest request, MultivaluedMap form) { + User user = null; + try { + user = ResourceUtility.getUser(request); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap(); + errorMap.put("error", "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + + String appId = form.getFirst("appId"); + String insightId = form.getFirst("insightId"); + + String permission = SecurityInsightUtils.getUserInsightPermission(user, appId, insightId); + if(permission == null) { + Map errorMap = new HashMap(); + errorMap.put("error", "User does not have access to this insight"); + return WebUtility.getResponse(errorMap, 401); + } + + Map ret = new HashMap(); + ret.put("permission", permission); + return WebUtility.getResponse(ret, 200); + } + + /** * Get the user insight permissions for a given insight * @param request @@ -61,4 +96,6 @@ public Response getInsightUsers(@Context HttpServletRequest request, Multivalued return WebUtility.getResponse(ret, 200); } + + } From 682335eba23b3a165a14b2edb59ea46c5611f764 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 8 Feb 2019 17:36:58 +0000 Subject: [PATCH 0399/1906] UPDATE ::: Switching from POST to GET git-svn-id: svn://107.170.10.188:8080/Monolith/dev@31980 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: a12c2d02612dc45d5445085deb9106925ff81175 --- .../auth/InsightAuthorizationResource.java | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java index c201bb25b..03a0145a7 100644 --- a/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java @@ -5,11 +5,11 @@ import java.util.Map; import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.POST; +import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; import javax.ws.rs.core.Context; -import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; import prerna.auth.User; @@ -26,10 +26,10 @@ public class InsightAuthorizationResource { * @param form * @return */ - @POST + @GET @Produces("application/json") @Path("getUserInsightPermission") - public Response getUserInsightPermission(@Context HttpServletRequest request, MultivaluedMap form) { + public Response getUserInsightPermission(@Context HttpServletRequest request, @QueryParam("appId") String appId, @QueryParam("insightId") String insightId) { User user = null; try { user = ResourceUtility.getUser(request); @@ -39,9 +39,6 @@ public Response getUserInsightPermission(@Context HttpServletRequest request, Mu return WebUtility.getResponse(errorMap, 401); } - String appId = form.getFirst("appId"); - String insightId = form.getFirst("insightId"); - String permission = SecurityInsightUtils.getUserInsightPermission(user, appId, insightId); if(permission == null) { Map errorMap = new HashMap(); @@ -61,10 +58,10 @@ public Response getUserInsightPermission(@Context HttpServletRequest request, Mu * @param form * @return */ - @POST + @GET @Produces("application/json") @Path("getInsightUsers") - public Response getInsightUsers(@Context HttpServletRequest request, MultivaluedMap form) { + public Response getInsightUsers(@Context HttpServletRequest request, @QueryParam("appId") String appId, @QueryParam("insightId") String insightId) { User user = null; try { user = ResourceUtility.getUser(request); @@ -74,9 +71,6 @@ public Response getInsightUsers(@Context HttpServletRequest request, Multivalued return WebUtility.getResponse(errorMap, 401); } - String appId = form.getFirst("appId"); - String insightId = form.getFirst("insightId"); - // can the user view this insight to see the permissions if(!SecurityInsightUtils.userCanViewInsight(user, appId, insightId)) { Map errorMap = new HashMap(); From 30c1e13b37295fe44f1e473469c62d5a2198ea7e Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 8 Feb 2019 18:25:31 +0000 Subject: [PATCH 0400/1906] UPDATE ::: Shifting methods around for insight level security calls UPDATE ::: Adding new rest endpoint to add user permissions api/auth/insight/addInsightUserPermission which takes in id, appId, insightId, permission as POST data git-svn-id: svn://107.170.10.188:8080/Monolith/dev@31982 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 7fc316484aecc6f7f4228e0a0211eeb75e0a171a --- .../auth/InsightAuthorizationResource.java | 39 +++++++++++++++++++ src/prerna/upload/ImageUploader.java | 3 +- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java index 03a0145a7..5df41a22d 100644 --- a/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java @@ -6,10 +6,12 @@ import javax.servlet.http.HttpServletRequest; import javax.ws.rs.GET; +import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.Context; +import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; import prerna.auth.User; @@ -91,5 +93,42 @@ public Response getInsightUsers(@Context HttpServletRequest request, @QueryParam } + /** + * Get the user insight permissions for a given insight + * @param request + * @param form + * @return + */ + @POST + @Produces("application/json") + @Path("addInsightUserPermission") + public Response addInsightUserPermission(@Context HttpServletRequest request, MultivaluedMap form) { + User user = null; + try { + user = ResourceUtility.getUser(request); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap(); + errorMap.put("error", "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + + String newUserId = form.getFirst("id"); + String appId = form.getFirst("appId"); + String insightId = form.getFirst("insightId"); + String permission = form.getFirst("permission"); + + try { + SecurityInsightUtils.addInsightUser(user, newUserId, appId, insightId, permission); + } catch (Exception e) { + Map errorMap = new HashMap(); + errorMap.put("error", e.getMessage()); + return WebUtility.getResponse(errorMap, 400); + } + + Map ret = new HashMap(); + ret.put("success", true); + return WebUtility.getResponse(ret, 200); + } + } diff --git a/src/prerna/upload/ImageUploader.java b/src/prerna/upload/ImageUploader.java index 5dc43230e..51e29f418 100644 --- a/src/prerna/upload/ImageUploader.java +++ b/src/prerna/upload/ImageUploader.java @@ -19,6 +19,7 @@ import org.apache.commons.io.filefilter.WildcardFileFilter; import prerna.auth.User; +import prerna.auth.utils.SecurityInsightUtils; import prerna.auth.utils.SecurityQueryUtils; import prerna.engine.impl.SmssUtilities; import prerna.nameserver.utility.MasterDatabaseUtility; @@ -140,7 +141,7 @@ public Response uploadInsightImage(@Context HttpServletRequest request) { returnMap.put("errorMessage", e.getMessage()); return WebUtility.getResponse(returnMap, 401); } - if(!SecurityQueryUtils.userCanEditInsight(user, appId, insightId)) { + if(!SecurityInsightUtils.userCanEditInsight(user, appId, insightId)) { throw new IllegalArgumentException("User does not have access to edit this insight within the app"); } appName = SecurityQueryUtils.getEngineAliasForId(appId); From 7adbfeca79e745352da5591d29831cc4d04a009c Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 8 Feb 2019 20:26:25 +0000 Subject: [PATCH 0401/1906] UPDATE ::: Pushing initial code around editing a user insight permission git-svn-id: svn://107.170.10.188:8080/Monolith/dev@31984 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: c87126aeb27110cfffd3919aee578a28b2090e56 --- .../auth/InsightAuthorizationResource.java | 38 ++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java index 5df41a22d..39b18bb27 100644 --- a/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java @@ -94,7 +94,7 @@ public Response getInsightUsers(@Context HttpServletRequest request, @QueryParam /** - * Get the user insight permissions for a given insight + * Add a user to an insight * @param request * @param form * @return @@ -130,5 +130,41 @@ public Response addInsightUserPermission(@Context HttpServletRequest request, Mu return WebUtility.getResponse(ret, 200); } + /** + * Add a user to an insight + * @param request + * @param form + * @return + */ + @POST + @Produces("application/json") + @Path("addInsightUserPermission") + public Response editInsightUserPermission(@Context HttpServletRequest request, MultivaluedMap form) { + User user = null; + try { + user = ResourceUtility.getUser(request); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap(); + errorMap.put("error", "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + + String existingUserId = form.getFirst("id"); + String appId = form.getFirst("appId"); + String insightId = form.getFirst("insightId"); + String newPermission = form.getFirst("permission"); + + try { + SecurityInsightUtils.editInsightUserPermission(user, existingUserId, appId, insightId, newPermission); + } catch (Exception e) { + Map errorMap = new HashMap(); + errorMap.put("error", e.getMessage()); + return WebUtility.getResponse(errorMap, 400); + } + + Map ret = new HashMap(); + ret.put("success", true); + return WebUtility.getResponse(ret, 200); + } } From bfe5b6ffd67cd7d86753a9ca4fc18f8656f7059e Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 11 Feb 2019 16:31:44 +0000 Subject: [PATCH 0402/1906] UPDATE ::: Fixing rules around being able to add/edit user insight permissions git-svn-id: svn://107.170.10.188:8080/Monolith/dev@31988 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 129d5581c21fea6e4ff3e8c657bf062c496ba438 --- .../auth/InsightAuthorizationResource.java | 27 ++++++++----------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java index 39b18bb27..3d3f53d12 100644 --- a/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java @@ -22,6 +22,8 @@ @Path("/auth/insight") public class InsightAuthorizationResource { + private static String ERROR_KEY = "errorMessage"; + /** * Get the user insight permissions for a given insight * @param request @@ -37,14 +39,14 @@ public Response getUserInsightPermission(@Context HttpServletRequest request, @Q user = ResourceUtility.getUser(request); } catch (IllegalAccessException e) { Map errorMap = new HashMap(); - errorMap.put("error", "User session is invalid"); + errorMap.put(ERROR_KEY, "User session is invalid"); return WebUtility.getResponse(errorMap, 401); } String permission = SecurityInsightUtils.getUserInsightPermission(user, appId, insightId); if(permission == null) { Map errorMap = new HashMap(); - errorMap.put("error", "User does not have access to this insight"); + errorMap.put(ERROR_KEY, "User does not have access to this insight"); return WebUtility.getResponse(errorMap, 401); } @@ -69,14 +71,7 @@ public Response getInsightUsers(@Context HttpServletRequest request, @QueryParam user = ResourceUtility.getUser(request); } catch (IllegalAccessException e) { Map errorMap = new HashMap(); - errorMap.put("error", "User session is invalid"); - return WebUtility.getResponse(errorMap, 401); - } - - // can the user view this insight to see the permissions - if(!SecurityInsightUtils.userCanViewInsight(user, appId, insightId)) { - Map errorMap = new HashMap(); - errorMap.put("error", "App/Insight id are invalid or user does not have access to view this insight"); + errorMap.put(ERROR_KEY, "User session is invalid"); return WebUtility.getResponse(errorMap, 401); } @@ -85,7 +80,7 @@ public Response getInsightUsers(@Context HttpServletRequest request, @QueryParam ret = SecurityInsightUtils.getInsightUsers(user, appId, insightId); } catch (IllegalAccessException e) { Map errorMap = new HashMap(); - errorMap.put("error", "User session is invalid"); + errorMap.put(ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 401); } @@ -108,7 +103,7 @@ public Response addInsightUserPermission(@Context HttpServletRequest request, Mu user = ResourceUtility.getUser(request); } catch (IllegalAccessException e) { Map errorMap = new HashMap(); - errorMap.put("error", "User session is invalid"); + errorMap.put(ERROR_KEY, "User session is invalid"); return WebUtility.getResponse(errorMap, 401); } @@ -121,7 +116,7 @@ public Response addInsightUserPermission(@Context HttpServletRequest request, Mu SecurityInsightUtils.addInsightUser(user, newUserId, appId, insightId, permission); } catch (Exception e) { Map errorMap = new HashMap(); - errorMap.put("error", e.getMessage()); + errorMap.put(ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 400); } @@ -138,14 +133,14 @@ public Response addInsightUserPermission(@Context HttpServletRequest request, Mu */ @POST @Produces("application/json") - @Path("addInsightUserPermission") + @Path("editInsightUserPermission") public Response editInsightUserPermission(@Context HttpServletRequest request, MultivaluedMap form) { User user = null; try { user = ResourceUtility.getUser(request); } catch (IllegalAccessException e) { Map errorMap = new HashMap(); - errorMap.put("error", "User session is invalid"); + errorMap.put(ERROR_KEY, "User session is invalid"); return WebUtility.getResponse(errorMap, 401); } @@ -158,7 +153,7 @@ public Response editInsightUserPermission(@Context HttpServletRequest request, M SecurityInsightUtils.editInsightUserPermission(user, existingUserId, appId, insightId, newPermission); } catch (Exception e) { Map errorMap = new HashMap(); - errorMap.put("error", e.getMessage()); + errorMap.put(ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 400); } From 4594881c19e2cebd184deda6cece0e8b2fab653b Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 11 Feb 2019 16:38:25 +0000 Subject: [PATCH 0403/1906] UPDATE ::: Adding new rest endpoint to remove user insight permission api/auth/insight/removeInsightUserPermission which takes in appId, insightId, and id (being the user id to remove) git-svn-id: svn://107.170.10.188:8080/Monolith/dev@31989 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 144e32a291b2ce34c1ebfae587a48c434f81434a --- .../auth/InsightAuthorizationResource.java | 38 ++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java index 3d3f53d12..0d2044a76 100644 --- a/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java @@ -126,7 +126,7 @@ public Response addInsightUserPermission(@Context HttpServletRequest request, Mu } /** - * Add a user to an insight + * Edit user permission for an insight * @param request * @param form * @return @@ -162,4 +162,40 @@ public Response editInsightUserPermission(@Context HttpServletRequest request, M return WebUtility.getResponse(ret, 200); } + /** + * Remove user permission for an insight + * @param request + * @param form + * @return + */ + @POST + @Produces("application/json") + @Path("removeInsightUserPermission") + public Response removeInsightUserPermission(@Context HttpServletRequest request, MultivaluedMap form) { + User user = null; + try { + user = ResourceUtility.getUser(request); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap(); + errorMap.put(ERROR_KEY, "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + + String existingUserId = form.getFirst("id"); + String appId = form.getFirst("appId"); + String insightId = form.getFirst("insightId"); + + try { + SecurityInsightUtils.removeInsightUser(user, existingUserId, appId, insightId); + } catch (Exception e) { + Map errorMap = new HashMap(); + errorMap.put(ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 400); + } + + Map ret = new HashMap(); + ret.put("success", true); + return WebUtility.getResponse(ret, 200); + } + } From 2f83265dffa3c2505330918fbe5a05b2d2370b96 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 11 Feb 2019 16:50:37 +0000 Subject: [PATCH 0404/1906] UPDATE ::: Adding rest endpoint to set an insight global (visible to all) within an app git-svn-id: svn://107.170.10.188:8080/Monolith/dev@31990 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 91c8a5dddcd7b44806b78414dd3dbc0d325644b3 --- .../auth/InsightAuthorizationResource.java | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java index 0d2044a76..47cf614d9 100644 --- a/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java @@ -198,4 +198,40 @@ public Response removeInsightUserPermission(@Context HttpServletRequest request, return WebUtility.getResponse(ret, 200); } + /** + * Remove user permission for an insight + * @param request + * @param form + * @return + */ + @POST + @Produces("application/json") + @Path("setInsightGlobal") + public Response setInsightGlobal(@Context HttpServletRequest request, MultivaluedMap form) { + User user = null; + try { + user = ResourceUtility.getUser(request); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap(); + errorMap.put(ERROR_KEY, "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + + String appId = form.getFirst("appId"); + String insightId = form.getFirst("insightId"); + boolean isPublic = Boolean.parseBoolean(form.getFirst("isPublic")); + + try { + SecurityInsightUtils.setInsightGlobalWithinApp(user, appId, insightId, isPublic); + } catch (Exception e) { + Map errorMap = new HashMap(); + errorMap.put(ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 400); + } + + Map ret = new HashMap(); + ret.put("success", true); + return WebUtility.getResponse(ret, 200); + } + } From dc75537559b76e1947c05ad5a26d318544cf46ce Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 12 Feb 2019 20:08:23 +0000 Subject: [PATCH 0405/1906] UPDATE ::: Not sending back READ_ONLY when the insight is global for the check if the user permission exists for this insight git-svn-id: svn://107.170.10.188:8080/Monolith/dev@32005 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: c8d710e0f53ec345ce5507dead699db04c1aa4a0 --- .../web/services/local/auth/InsightAuthorizationResource.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java index 47cf614d9..953bd838a 100644 --- a/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java @@ -43,7 +43,7 @@ public Response getUserInsightPermission(@Context HttpServletRequest request, @Q return WebUtility.getResponse(errorMap, 401); } - String permission = SecurityInsightUtils.getUserInsightPermission(user, appId, insightId); + String permission = SecurityInsightUtils.getActualUserInsightPermission(user, appId, insightId); if(permission == null) { Map errorMap = new HashMap(); errorMap.put(ERROR_KEY, "User does not have access to this insight"); From f1bd59aa921f8bb9c4fa2c9b627f926ed9676cf5 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 15 Feb 2019 13:11:01 +0000 Subject: [PATCH 0406/1906] BUGFIX ::: Fixing issue with LAT/LONG not working when not logged into google but have a valid API key git-svn-id: svn://107.170.10.188:8080/Monolith/dev@32043 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: ee7e79e2437b5c1f7c59477789bb6f846a8fbac5 --- src/prerna/semoss/web/services/local/UserResource.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index 6fef1094a..7e9c0ddba 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -73,6 +73,7 @@ import jodd.util.URLDecoder; import prerna.auth.AccessToken; +import prerna.auth.AppTokens; import prerna.auth.AuthProvider; import prerna.auth.InsightToken; import prerna.auth.User; @@ -109,6 +110,7 @@ public class UserResource { static { loadSocialProperties(); + AppTokens.setSocial(socialData); } private static void loadSocialProperties() { From 87a268a123fde6b5bb94f75bf4f23e680bc8f4f7 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 21 Feb 2019 15:10:44 +0000 Subject: [PATCH 0407/1906] UPDATE ::: Adding admin level modifications for insight auth git-svn-id: svn://107.170.10.188:8080/Monolith/dev@32121 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 9aa62f97a161e0d9cf36c8eaca86f901792acc12 --- .../semoss/web/app/MonolithApplication.java | 4 + .../semoss/web/services/local/NameServer.java | 2 +- .../web/services/local/ResourceUtility.java | 2 + .../AdminInsightAuthorizationResource.java | 212 ++++++++++++++++++ .../auth/InsightAuthorizationResource.java | 26 +-- 5 files changed, 231 insertions(+), 15 deletions(-) create mode 100644 src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java diff --git a/src/prerna/semoss/web/app/MonolithApplication.java b/src/prerna/semoss/web/app/MonolithApplication.java index 5fda1433c..f17ff28bb 100644 --- a/src/prerna/semoss/web/app/MonolithApplication.java +++ b/src/prerna/semoss/web/app/MonolithApplication.java @@ -41,6 +41,7 @@ import prerna.semoss.web.services.local.ShareInsightResource; import prerna.semoss.web.services.local.ThemeResource; import prerna.semoss.web.services.local.UserResource; +import prerna.semoss.web.services.local.auth.AdminInsightAuthorizationResource; import prerna.semoss.web.services.local.auth.InsightAuthorizationResource; public class MonolithApplication extends Application { @@ -48,12 +49,15 @@ public class MonolithApplication extends Application { private Set singletons = new HashSet(); public MonolithApplication() { + // core singletons.add(new UserResource()); singletons.add(new NameServer()); singletons.add(new AppResource()); // authorization resources singletons.add(new AuthorizationResource()); singletons.add(new InsightAuthorizationResource()); + singletons.add(new AdminInsightAuthorizationResource()); + // other singletons.add(new ThemeResource()); singletons.add(new ShareInsightResource()); singletons.add(new FormResource()); diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index e0789b809..05d469e3c 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -167,7 +167,7 @@ public Response cleanSession(@Context HttpServletRequest request) { // wait 10 seconds try { - Thread.sleep(10000); + Thread.sleep(10_000); } catch (InterruptedException e1) { e1.printStackTrace(); } diff --git a/src/prerna/semoss/web/services/local/ResourceUtility.java b/src/prerna/semoss/web/services/local/ResourceUtility.java index 343ab5976..814b13616 100644 --- a/src/prerna/semoss/web/services/local/ResourceUtility.java +++ b/src/prerna/semoss/web/services/local/ResourceUtility.java @@ -11,6 +11,8 @@ public class ResourceUtility { + public static String ERROR_KEY = "errorMessage"; + /** * Get the user * @param request diff --git a/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java new file mode 100644 index 000000000..1b6e6bff9 --- /dev/null +++ b/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java @@ -0,0 +1,212 @@ +package prerna.semoss.web.services.local.auth; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.Response; + +import prerna.auth.User; +import prerna.auth.utils.SecurityAdminUtils; +import prerna.semoss.web.services.local.ResourceUtility; +import prerna.web.services.util.WebUtility; + +@Path("/auth/admin/insight") +public class AdminInsightAuthorizationResource { + + private SecurityAdminUtils performAdminCheck(@Context HttpServletRequest request) throws IllegalAccessException { + User user = ResourceUtility.getUser(request); + SecurityAdminUtils adminUtils = SecurityAdminUtils.getInstance(user); + if(adminUtils == null) { + throw new IllegalArgumentException("User is not an admin"); + } + return adminUtils; + } + + /** + * Get the user insight permissions for a given insight + * @param request + * @param form + * @return + */ + @GET + @Produces("application/json") + @Path("getInsightUsers") + public Response getInsightUsers(@Context HttpServletRequest request, @QueryParam("appId") String appId, @QueryParam("insightId") String insightId) { + SecurityAdminUtils adminUtils = null; + try { + adminUtils = performAdminCheck(request); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + + List> ret = null; + try { + ret = adminUtils.getInsightUsers(appId, insightId); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + + return WebUtility.getResponse(ret, 200); + } + + + /** + * Add a user to an insight + * @param request + * @param form + * @return + */ + @POST + @Produces("application/json") + @Path("addInsightUserPermission") + public Response addInsightUserPermission(@Context HttpServletRequest request, MultivaluedMap form) { + SecurityAdminUtils adminUtils = null; + try { + adminUtils = performAdminCheck(request); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + + String newUserId = form.getFirst("id"); + String appId = form.getFirst("appId"); + String insightId = form.getFirst("insightId"); + String permission = form.getFirst("permission"); + + try { + adminUtils.addInsightUser(newUserId, appId, insightId, permission); + } catch (Exception e) { + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 400); + } + + Map ret = new HashMap(); + ret.put("success", true); + return WebUtility.getResponse(ret, 200); + } + + /** + * Edit user permission for an insight + * @param request + * @param form + * @return + */ + @POST + @Produces("application/json") + @Path("editInsightUserPermission") + public Response editInsightUserPermission(@Context HttpServletRequest request, MultivaluedMap form) { + SecurityAdminUtils adminUtils = null; + try { + adminUtils = performAdminCheck(request); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + + String existingUserId = form.getFirst("id"); + String appId = form.getFirst("appId"); + String insightId = form.getFirst("insightId"); + String newPermission = form.getFirst("permission"); + + try { + adminUtils.editInsightUserPermission(existingUserId, appId, insightId, newPermission); + } catch (Exception e) { + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 400); + } + + Map ret = new HashMap(); + ret.put("success", true); + return WebUtility.getResponse(ret, 200); + } + + /** + * Remove user permission for an insight + * @param request + * @param form + * @return + */ + @POST + @Produces("application/json") + @Path("removeInsightUserPermission") + public Response removeInsightUserPermission(@Context HttpServletRequest request, MultivaluedMap form) { + SecurityAdminUtils adminUtils = null; + try { + adminUtils = performAdminCheck(request); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + + String existingUserId = form.getFirst("id"); + String appId = form.getFirst("appId"); + String insightId = form.getFirst("insightId"); + + try { + adminUtils.removeInsightUser(existingUserId, appId, insightId); + } catch (Exception e) { + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 400); + } + + Map ret = new HashMap(); + ret.put("success", true); + return WebUtility.getResponse(ret, 200); + } + + /** + * Remove user permission for an insight + * @param request + * @param form + * @return + */ + @POST + @Produces("application/json") + @Path("setInsightGlobal") + public Response setInsightGlobal(@Context HttpServletRequest request, MultivaluedMap form) { + SecurityAdminUtils adminUtils = null; + try { + adminUtils = performAdminCheck(request); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + + String appId = form.getFirst("appId"); + String insightId = form.getFirst("insightId"); + boolean isPublic = Boolean.parseBoolean(form.getFirst("isPublic")); + + try { + adminUtils.setInsightGlobalWithinApp(appId, insightId, isPublic); + } catch (Exception e) { + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 400); + } + + Map ret = new HashMap(); + ret.put("success", true); + return WebUtility.getResponse(ret, 200); + } + +} diff --git a/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java index 953bd838a..77a0316b5 100644 --- a/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java @@ -22,8 +22,6 @@ @Path("/auth/insight") public class InsightAuthorizationResource { - private static String ERROR_KEY = "errorMessage"; - /** * Get the user insight permissions for a given insight * @param request @@ -39,14 +37,14 @@ public Response getUserInsightPermission(@Context HttpServletRequest request, @Q user = ResourceUtility.getUser(request); } catch (IllegalAccessException e) { Map errorMap = new HashMap(); - errorMap.put(ERROR_KEY, "User session is invalid"); + errorMap.put(ResourceUtility.ERROR_KEY, "User session is invalid"); return WebUtility.getResponse(errorMap, 401); } String permission = SecurityInsightUtils.getActualUserInsightPermission(user, appId, insightId); if(permission == null) { Map errorMap = new HashMap(); - errorMap.put(ERROR_KEY, "User does not have access to this insight"); + errorMap.put(ResourceUtility.ERROR_KEY, "User does not have access to this insight"); return WebUtility.getResponse(errorMap, 401); } @@ -71,7 +69,7 @@ public Response getInsightUsers(@Context HttpServletRequest request, @QueryParam user = ResourceUtility.getUser(request); } catch (IllegalAccessException e) { Map errorMap = new HashMap(); - errorMap.put(ERROR_KEY, "User session is invalid"); + errorMap.put(ResourceUtility.ERROR_KEY, "User session is invalid"); return WebUtility.getResponse(errorMap, 401); } @@ -80,7 +78,7 @@ public Response getInsightUsers(@Context HttpServletRequest request, @QueryParam ret = SecurityInsightUtils.getInsightUsers(user, appId, insightId); } catch (IllegalAccessException e) { Map errorMap = new HashMap(); - errorMap.put(ERROR_KEY, e.getMessage()); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 401); } @@ -103,7 +101,7 @@ public Response addInsightUserPermission(@Context HttpServletRequest request, Mu user = ResourceUtility.getUser(request); } catch (IllegalAccessException e) { Map errorMap = new HashMap(); - errorMap.put(ERROR_KEY, "User session is invalid"); + errorMap.put(ResourceUtility.ERROR_KEY, "User session is invalid"); return WebUtility.getResponse(errorMap, 401); } @@ -116,7 +114,7 @@ public Response addInsightUserPermission(@Context HttpServletRequest request, Mu SecurityInsightUtils.addInsightUser(user, newUserId, appId, insightId, permission); } catch (Exception e) { Map errorMap = new HashMap(); - errorMap.put(ERROR_KEY, e.getMessage()); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 400); } @@ -140,7 +138,7 @@ public Response editInsightUserPermission(@Context HttpServletRequest request, M user = ResourceUtility.getUser(request); } catch (IllegalAccessException e) { Map errorMap = new HashMap(); - errorMap.put(ERROR_KEY, "User session is invalid"); + errorMap.put(ResourceUtility.ERROR_KEY, "User session is invalid"); return WebUtility.getResponse(errorMap, 401); } @@ -153,7 +151,7 @@ public Response editInsightUserPermission(@Context HttpServletRequest request, M SecurityInsightUtils.editInsightUserPermission(user, existingUserId, appId, insightId, newPermission); } catch (Exception e) { Map errorMap = new HashMap(); - errorMap.put(ERROR_KEY, e.getMessage()); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 400); } @@ -177,7 +175,7 @@ public Response removeInsightUserPermission(@Context HttpServletRequest request, user = ResourceUtility.getUser(request); } catch (IllegalAccessException e) { Map errorMap = new HashMap(); - errorMap.put(ERROR_KEY, "User session is invalid"); + errorMap.put(ResourceUtility.ERROR_KEY, "User session is invalid"); return WebUtility.getResponse(errorMap, 401); } @@ -189,7 +187,7 @@ public Response removeInsightUserPermission(@Context HttpServletRequest request, SecurityInsightUtils.removeInsightUser(user, existingUserId, appId, insightId); } catch (Exception e) { Map errorMap = new HashMap(); - errorMap.put(ERROR_KEY, e.getMessage()); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 400); } @@ -213,7 +211,7 @@ public Response setInsightGlobal(@Context HttpServletRequest request, Multivalue user = ResourceUtility.getUser(request); } catch (IllegalAccessException e) { Map errorMap = new HashMap(); - errorMap.put(ERROR_KEY, "User session is invalid"); + errorMap.put(ResourceUtility.ERROR_KEY, "User session is invalid"); return WebUtility.getResponse(errorMap, 401); } @@ -225,7 +223,7 @@ public Response setInsightGlobal(@Context HttpServletRequest request, Multivalue SecurityInsightUtils.setInsightGlobalWithinApp(user, appId, insightId, isPublic); } catch (Exception e) { Map errorMap = new HashMap(); - errorMap.put(ERROR_KEY, e.getMessage()); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 400); } From 008b762b8dc6224d23278b469484b5fea1cc58d5 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 21 Feb 2019 19:14:03 +0000 Subject: [PATCH 0408/1906] UPDATE ::: Adding admin get app insights rest endpoint git-svn-id: svn://107.170.10.188:8080/Monolith/dev@32126 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: a42537322ed2390b9ff058100edc9d1befae1f2a --- .../AdminInsightAuthorizationResource.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java index 1b6e6bff9..63348a224 100644 --- a/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java @@ -31,6 +31,29 @@ private SecurityAdminUtils performAdminCheck(@Context HttpServletRequest request return adminUtils; } + /** + * Get the user insight permissions for a given insight + * @param request + * @param form + * @return + */ + @GET + @Produces("application/json") + @Path("getAppInsights") + public Response getAppInsights(@Context HttpServletRequest request, @QueryParam("appId") String appId) { + SecurityAdminUtils adminUtils = null; + try { + adminUtils = performAdminCheck(request); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + + List> ret = adminUtils.getAppInsights(appId); + return WebUtility.getResponse(ret, 200); + } + /** * Get the user insight permissions for a given insight * @param request From 88ecefb3828710d4b663ad2372443aa2bc687dcc Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 21 Feb 2019 19:27:22 +0000 Subject: [PATCH 0409/1906] UPDATE ::: Adding admin rest endpoint to delete an insight git-svn-id: svn://107.170.10.188:8080/Monolith/dev@32127 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 356aba62f6afe4384005776e3ba12965ee0835fd --- .../AdminInsightAuthorizationResource.java | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java index 63348a224..2085a6456 100644 --- a/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java @@ -14,8 +14,11 @@ import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; +import com.google.gson.Gson; + import prerna.auth.User; import prerna.auth.utils.SecurityAdminUtils; +import prerna.cluster.util.ClusterUtil; import prerna.semoss.web.services.local.ResourceUtility; import prerna.web.services.util.WebUtility; @@ -54,6 +57,46 @@ public Response getAppInsights(@Context HttpServletRequest request, @QueryParam( return WebUtility.getResponse(ret, 200); } + /** + * Get the user insight permissions for a given insight + * @param request + * @param form + * @return + */ + @POST + @Produces("application/json") + @Path("deleteAppInsights") + public Response deleteAppInsights(@Context HttpServletRequest request, MultivaluedMap form) { + SecurityAdminUtils adminUtils = null; + try { + adminUtils = performAdminCheck(request); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + + String appId = form.getFirst("appId"); + Gson gson = new Gson(); + List insightIds = gson.fromJson(form.getFirst("insightId"), List.class); + + try { + adminUtils.deleteAppInsights(appId, insightIds); + + // since modifying insight list + // need to push to cloud storage + ClusterUtil.reactorPushApp(appId); + } catch (Exception e) { + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + + Map ret = new HashMap(); + ret.put("success", true); + return WebUtility.getResponse(ret, 200); + } + /** * Get the user insight permissions for a given insight * @param request From 0340ecb3c27b0c99c0b2b0c24d9b75675c8ffb19 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 27 Feb 2019 19:11:01 +0000 Subject: [PATCH 0410/1906] UPDATE ::: Adding new app auth class to start shifting over specific calls from auth into the correct class (app vs. insight) git-svn-id: svn://107.170.10.188:8080/Monolith/dev@32192 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 38db608c4e3d069b89a23d27411676970d77f2d3 --- .../semoss/web/app/MonolithApplication.java | 2 + .../web/services/local/AppResource.java | 3 +- .../semoss/web/services/local/NameServer.java | 3 +- .../local/auth/AppAuthorizationResource.java | 53 +++++++++++++++++++ src/prerna/upload/ImageUploader.java | 3 +- 5 files changed, 61 insertions(+), 3 deletions(-) create mode 100644 src/prerna/semoss/web/services/local/auth/AppAuthorizationResource.java diff --git a/src/prerna/semoss/web/app/MonolithApplication.java b/src/prerna/semoss/web/app/MonolithApplication.java index f17ff28bb..8399c2694 100644 --- a/src/prerna/semoss/web/app/MonolithApplication.java +++ b/src/prerna/semoss/web/app/MonolithApplication.java @@ -42,6 +42,7 @@ import prerna.semoss.web.services.local.ThemeResource; import prerna.semoss.web.services.local.UserResource; import prerna.semoss.web.services.local.auth.AdminInsightAuthorizationResource; +import prerna.semoss.web.services.local.auth.AppAuthorizationResource; import prerna.semoss.web.services.local.auth.InsightAuthorizationResource; public class MonolithApplication extends Application { @@ -55,6 +56,7 @@ public MonolithApplication() { singletons.add(new AppResource()); // authorization resources singletons.add(new AuthorizationResource()); + singletons.add(new AppAuthorizationResource()); singletons.add(new InsightAuthorizationResource()); singletons.add(new AdminInsightAuthorizationResource()); // other diff --git a/src/prerna/semoss/web/services/local/AppResource.java b/src/prerna/semoss/web/services/local/AppResource.java index 7ad55f682..86771bd54 100644 --- a/src/prerna/semoss/web/services/local/AppResource.java +++ b/src/prerna/semoss/web/services/local/AppResource.java @@ -26,6 +26,7 @@ import prerna.auth.User; import prerna.auth.utils.AbstractSecurityUtils; +import prerna.auth.utils.SecurityAppUtils; import prerna.auth.utils.SecurityQueryUtils; import prerna.engine.api.IEngine; import prerna.engine.impl.SmssUtilities; @@ -51,7 +52,7 @@ public class AppResource { private IEngine getApp(User user, String appId) throws IllegalAccessException { if(AbstractSecurityUtils.securityEnabled()) { appId = SecurityQueryUtils.testUserEngineIdForAlias(user, appId); - if(!SecurityQueryUtils.userCanViewEngine(user, appId)) { + if(!SecurityAppUtils.userCanViewEngine(user, appId)) { throw new IllegalAccessException("App " + appId + " does not exist or user does not have access to database"); } } else { diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index 05d469e3c..ee3d815a6 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -81,6 +81,7 @@ import prerna.auth.User; import prerna.auth.utils.AbstractSecurityUtils; +import prerna.auth.utils.SecurityAppUtils; import prerna.auth.utils.SecurityInsightUtils; import prerna.auth.utils.SecurityQueryUtils; import prerna.ds.py.PyExecutorThread; @@ -850,7 +851,7 @@ public Object getLocalDatabase(@Context HttpServletRequest request, @PathParam(" return WebUtility.getSO("Not properly authenticated"); } engineId = SecurityQueryUtils.testUserEngineIdForAlias(user, engineId); - if(!SecurityQueryUtils.userCanViewEngine(user, engineId)) { + if(!SecurityAppUtils.userCanViewEngine(user, engineId)) { Map errorMap = new HashMap(); errorMap.put("errorMessage", "Database " + engineId + " does not exist or user does not have access to database"); return WebUtility.getResponse(errorMap, 400); diff --git a/src/prerna/semoss/web/services/local/auth/AppAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/AppAuthorizationResource.java new file mode 100644 index 000000000..813de587b --- /dev/null +++ b/src/prerna/semoss/web/services/local/auth/AppAuthorizationResource.java @@ -0,0 +1,53 @@ +package prerna.semoss.web.services.local.auth; + +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.Response; + +import prerna.auth.User; +import prerna.auth.utils.SecurityAppUtils; +import prerna.semoss.web.services.local.ResourceUtility; +import prerna.web.services.util.WebUtility; + +@Path("/auth/app") +public class AppAuthorizationResource { + + /** + * Get the user insight permissions for a given insight + * @param request + * @param form + * @return + */ + @GET + @Produces("application/json") + @Path("getUserAppPermission") + public Response getUserAppPermission(@Context HttpServletRequest request, @QueryParam("appId") String appId) { + User user = null; + try { + user = ResourceUtility.getUser(request); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + + String permission = SecurityAppUtils.getActualUserAppPermission(user, appId); + if(permission == null) { + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, "User does not have access to this app"); + return WebUtility.getResponse(errorMap, 401); + } + + Map ret = new HashMap(); + ret.put("permission", permission); + return WebUtility.getResponse(ret, 200); + } + +} diff --git a/src/prerna/upload/ImageUploader.java b/src/prerna/upload/ImageUploader.java index 51e29f418..56ad0c01c 100644 --- a/src/prerna/upload/ImageUploader.java +++ b/src/prerna/upload/ImageUploader.java @@ -19,6 +19,7 @@ import org.apache.commons.io.filefilter.WildcardFileFilter; import prerna.auth.User; +import prerna.auth.utils.SecurityAppUtils; import prerna.auth.utils.SecurityInsightUtils; import prerna.auth.utils.SecurityQueryUtils; import prerna.engine.impl.SmssUtilities; @@ -61,7 +62,7 @@ public Response uploadAppImage(@Context HttpServletRequest request) { returnMap.put("errorMessage", e.getMessage()); return WebUtility.getResponse(returnMap, 401); } - if(!SecurityQueryUtils.userCanEditEngine(user, appId)) { + if(!SecurityAppUtils.userCanEditEngine(user, appId)) { throw new IllegalArgumentException("Database " + appId + " does not exist or user does not have access to database"); } appName = SecurityQueryUtils.getEngineAliasForId(appId); From a920f0535678a2228cc2d12350f39ffd4794039f Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 27 Feb 2019 22:23:18 +0000 Subject: [PATCH 0411/1906] UPDATE ::: Modifying the code to take in any route cookie like route-dev, route-health, etc. git-svn-id: svn://107.170.10.188:8080/Monolith/dev@32200 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 47e7c284b5f78753297f28e248368492f2c15fa1 --- src/prerna/web/conf/NoUserInSessionFilter.java | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/prerna/web/conf/NoUserInSessionFilter.java b/src/prerna/web/conf/NoUserInSessionFilter.java index 23acd0be0..4401dfd72 100644 --- a/src/prerna/web/conf/NoUserInSessionFilter.java +++ b/src/prerna/web/conf/NoUserInSessionFilter.java @@ -3,9 +3,12 @@ import java.io.IOException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; +import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.Vector; +import java.util.stream.Collectors; import javax.servlet.Filter; import javax.servlet.FilterChain; @@ -98,11 +101,15 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 } } - String route = req.getParameter("route"); - if(route != null) { - Cookie c = new Cookie("route", route); - c.setPath(contextPath); - ((HttpServletResponse)arg1).addCookie(c); + Set routes = Collections.list(req.getParameterNames()) + .stream().filter(s -> s.startsWith("route")) + .collect(Collectors.toSet()); + if(routes != null && !routes.isEmpty()) { + for(String r : routes) { + Cookie c = new Cookie(r, req.getParameter(r)); + c.setPath(contextPath); + ((HttpServletResponse)arg1).addCookie(c); + } } // add the hash cookie From 058ea799be591a8fc5c38525bfa4d48e033b9035 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 28 Feb 2019 22:36:49 +0000 Subject: [PATCH 0412/1906] UPDATE ::: Adding user-app level permission rest endpoints git-svn-id: svn://107.170.10.188:8080/Monolith/dev@32217 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: e9c3b6802ea9cf99b65a69d0b55f369c3505ba5f --- .../local/auth/AppAuthorizationResource.java | 108 ++++++++++++++++++ .../auth/InsightAuthorizationResource.java | 13 +++ 2 files changed, 121 insertions(+) diff --git a/src/prerna/semoss/web/services/local/auth/AppAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/AppAuthorizationResource.java index 813de587b..dd50cdccd 100644 --- a/src/prerna/semoss/web/services/local/auth/AppAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/AppAuthorizationResource.java @@ -5,10 +5,12 @@ import javax.servlet.http.HttpServletRequest; import javax.ws.rs.GET; +import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.Context; +import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; import prerna.auth.User; @@ -50,4 +52,110 @@ public Response getUserAppPermission(@Context HttpServletRequest request, @Query return WebUtility.getResponse(ret, 200); } + /** + * Add a user to an insight + * @param request + * @param form + * @return + */ + @POST + @Produces("application/json") + @Path("addAppUserPermission") + public Response addAppUserPermission(@Context HttpServletRequest request, MultivaluedMap form) { + User user = null; + try { + user = ResourceUtility.getUser(request); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + + String newUserId = form.getFirst("id"); + String appId = form.getFirst("appId"); + String permission = form.getFirst("permission"); + + try { + SecurityAppUtils.addAppUser(user, newUserId, appId, permission); + } catch (Exception e) { + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 400); + } + + Map ret = new HashMap(); + ret.put("success", true); + return WebUtility.getResponse(ret, 200); + } + + /** + * Edit user permission for an insight + * @param request + * @param form + * @return + */ + @POST + @Produces("application/json") + @Path("editAppUserPermission") + public Response editAppUserPermission(@Context HttpServletRequest request, MultivaluedMap form) { + User user = null; + try { + user = ResourceUtility.getUser(request); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + + String existingUserId = form.getFirst("id"); + String appId = form.getFirst("appId"); + String newPermission = form.getFirst("permission"); + + try { + SecurityAppUtils.editAppUserPermission(user, existingUserId, appId, newPermission); + } catch (Exception e) { + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 400); + } + + Map ret = new HashMap(); + ret.put("success", true); + return WebUtility.getResponse(ret, 200); + } + + /** + * Remove user permission for an insight + * @param request + * @param form + * @return + */ + @POST + @Produces("application/json") + @Path("removeAppUserPermission") + public Response removeAppUserPermission(@Context HttpServletRequest request, MultivaluedMap form) { + User user = null; + try { + user = ResourceUtility.getUser(request); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + + String existingUserId = form.getFirst("id"); + String appId = form.getFirst("appId"); + + try { + SecurityAppUtils.removeAppUser(user, existingUserId, appId); + } catch (Exception e) { + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 400); + } + + Map ret = new HashMap(); + ret.put("success", true); + return WebUtility.getResponse(ret, 200); + } } diff --git a/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java index 77a0316b5..2c9b14f84 100644 --- a/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java @@ -14,7 +14,9 @@ import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; +import prerna.auth.AccessPermission; import prerna.auth.User; +import prerna.auth.utils.SecurityAppUtils; import prerna.auth.utils.SecurityInsightUtils; import prerna.semoss.web.services.local.ResourceUtility; import prerna.web.services.util.WebUtility; @@ -110,6 +112,17 @@ public Response addInsightUserPermission(@Context HttpServletRequest request, Mu String insightId = form.getFirst("insightId"); String permission = form.getFirst("permission"); + // add the person with read only access if they do not have access to the app + if(SecurityAppUtils.getUserAppPermission(newUserId, appId) == null) { + try { + SecurityAppUtils.addAppUser(user, newUserId, appId, AccessPermission.READ_ONLY.getPermission()); + } catch(Exception e) { + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 400); + } + } + try { SecurityInsightUtils.addInsightUser(user, newUserId, appId, insightId, permission); } catch (Exception e) { From 8f8b990013e8c037c43ae09502884d46c8bc4ee6 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 1 Mar 2019 16:20:47 +0000 Subject: [PATCH 0413/1906] UPDATE ::: Adding more modifications to shift methods into appropriate locations for app lvl security git-svn-id: svn://107.170.10.188:8080/Monolith/dev@32223 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 9dbb773436e5a30b7e39b06ddbaa69e1d9ba8944 --- .../services/local/AuthorizationResource.java | 3 +- .../local/auth/AppAuthorizationResource.java | 76 +++++++++++++++++++ 2 files changed, 78 insertions(+), 1 deletion(-) diff --git a/src/prerna/semoss/web/services/local/AuthorizationResource.java b/src/prerna/semoss/web/services/local/AuthorizationResource.java index 4a73d7a62..bfc918ad0 100644 --- a/src/prerna/semoss/web/services/local/AuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/AuthorizationResource.java @@ -50,6 +50,7 @@ import prerna.auth.User; import prerna.auth.utils.SecurityAdminUtils; +import prerna.auth.utils.SecurityAppUtils; import prerna.auth.utils.SecurityQueryUtils; import prerna.auth.utils.SecurityUpdateUtils; import prerna.util.Constants; @@ -293,7 +294,7 @@ public Response setDbPublic(@Context HttpServletRequest request, MultivaluedMap< boolean isPublic = Boolean.parseBoolean(form.getFirst("public")); try { - SecurityUpdateUtils.setDbGlobal(user, engineId, isPublic); + SecurityAppUtils.setAppGlobal(user, engineId, isPublic); } catch(IllegalArgumentException e) { e.printStackTrace(); Map errorRet = new HashMap(); diff --git a/src/prerna/semoss/web/services/local/auth/AppAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/AppAuthorizationResource.java index dd50cdccd..99c0366b2 100644 --- a/src/prerna/semoss/web/services/local/auth/AppAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/AppAuthorizationResource.java @@ -1,8 +1,10 @@ package prerna.semoss.web.services.local.auth; import java.util.HashMap; +import java.util.List; import java.util.Map; +import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.GET; import javax.ws.rs.POST; @@ -16,11 +18,15 @@ import prerna.auth.User; import prerna.auth.utils.SecurityAppUtils; import prerna.semoss.web.services.local.ResourceUtility; +import prerna.util.Constants; import prerna.web.services.util.WebUtility; @Path("/auth/app") public class AppAuthorizationResource { + @Context + protected ServletContext context; + /** * Get the user insight permissions for a given insight * @param request @@ -52,6 +58,37 @@ public Response getUserAppPermission(@Context HttpServletRequest request, @Query return WebUtility.getResponse(ret, 200); } + /** + * Get the user app permissions for a given insight + * @param request + * @param form + * @return + */ + @GET + @Produces("application/json") + @Path("getAppUsers") + public Response getInsightUsers(@Context HttpServletRequest request, @QueryParam("appId") String appId) { + User user = null; + try { + user = ResourceUtility.getUser(request); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + + List> ret = null; + try { + ret = SecurityAppUtils.getAppUsers(user, appId); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + + return WebUtility.getResponse(ret, 200); + } + /** * Add a user to an insight * @param request @@ -158,4 +195,43 @@ public Response removeAppUserPermission(@Context HttpServletRequest request, Mul ret.put("success", true); return WebUtility.getResponse(ret, 200); } + + @POST + @Produces("application/json") + @Path("setAppGlobal") + public Response setDbPublic(@Context HttpServletRequest request, MultivaluedMap form) { + boolean onlyAdmin = Boolean.parseBoolean(context.getInitParameter(Constants.ADMIN_SET_PUBLIC)); + if(onlyAdmin) { + Map errorMap = new HashMap(); + errorMap.put("error", "For this instance, only admins are allowed to set specific apps global"); + return WebUtility.getResponse(errorMap, 400); + } + + User user = null; + try { + user = ResourceUtility.getUser(request); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + + String engineId = form.getFirst("appId"); + boolean isPublic = Boolean.parseBoolean(form.getFirst("public")); + try { + SecurityAppUtils.setAppGlobal(user, engineId, isPublic); + } catch(IllegalArgumentException e) { + e.printStackTrace(); + Map errorRet = new HashMap(); + errorRet.put("error", e.getMessage()); + return WebUtility.getResponse(errorRet, 400); + } catch (Exception e){ + e.printStackTrace(); + Map errorRet = new HashMap(); + errorRet.put("error", "An unexpected error happened. Please try again."); + return WebUtility.getResponse(errorRet, 500); + } + + return WebUtility.getResponse(true, 200); + } } From 5f02039b4711126f23a0c512a5b61cf7966bb9d4 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 12 Mar 2019 21:16:23 +0000 Subject: [PATCH 0414/1906] UPDATE ::: Adding new key for file transfer size UPDATE ::: Sending back file transfer size in server config git-svn-id: svn://107.170.10.188:8080/Monolith/dev@32346 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 55535cce88e4c6da093cac25633c316d30cbe453 --- .../services/config/ServerConfigurationResource.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/prerna/semoss/web/services/config/ServerConfigurationResource.java b/src/prerna/semoss/web/services/config/ServerConfigurationResource.java index 5d962f12c..b37bb11c8 100644 --- a/src/prerna/semoss/web/services/config/ServerConfigurationResource.java +++ b/src/prerna/semoss/web/services/config/ServerConfigurationResource.java @@ -70,6 +70,16 @@ private static Map getConfig(@Context HttpServletRequest request } config.put("adminSetPublic", adminSetPublic); + // max file transfer size + String fileTransferMax = DIHelper.getInstance().getProperty(Constants.FILE_TRANSFER_LIMIT); + if(fileTransferMax != null) { + try { + config.put("file-limit", Integer.parseInt(fileTransferMax)); + } catch(Exception e) { + // ignore + } + } + // local mode boolean localMode = false; String localModeStr = DIHelper.getInstance().getProperty(Constants.LOCAL_DEPLOYMENT); From e36880b407b49eea195036a462f4665b8e64e398 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 13 Mar 2019 15:57:58 +0000 Subject: [PATCH 0415/1906] UPDATE ::: Enabling session naming for server deployment such that cookies do not overlap git-svn-id: svn://107.170.10.188:8080/Monolith/dev@32356 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 6170b77a5472e4f36d024d382eefceb94eb4ff5f --- WebContent/WEB-INF/web.xml | 5 +- WebContent/share/index.html | 73 ++++++------ .../semoss/web/services/local/NameServer.java | 108 ------------------ .../web/services/local/UserResource.java | 91 ++++----------- src/prerna/web/conf/DBLoader.java | 54 ++++++--- .../web/conf/NoUserInSessionFilter.java | 16 ++- 6 files changed, 112 insertions(+), 235 deletions(-) diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index 202b807d0..b06e4f2bc 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -4,7 +4,7 @@ index.html - + SetCharacterEncoding @@ -221,5 +221,8 @@ 120 + + monolith + \ No newline at end of file diff --git a/WebContent/share/index.html b/WebContent/share/index.html index 5952791de..af8e9766d 100644 --- a/WebContent/share/index.html +++ b/WebContent/share/index.html @@ -178,22 +178,25 @@ } - - - - - - \ No newline at end of file diff --git a/WebContent/exp/Arcs2.html b/WebContent/exp/Arcs2.html deleted file mode 100644 index 2574e8426..000000000 --- a/WebContent/exp/Arcs2.html +++ /dev/null @@ -1,376 +0,0 @@ - - - - - D3: Pie layout - - - - - - - \ No newline at end of file diff --git a/WebContent/exp/ContextMenu.html b/WebContent/exp/ContextMenu.html deleted file mode 100644 index 03388a90b..000000000 --- a/WebContent/exp/ContextMenu.html +++ /dev/null @@ -1,1044 +0,0 @@ - - - - - - - D3: Pie layout - - - - - - - - - - - - - - \ No newline at end of file diff --git a/WebContent/exp/MenuData.csv.xlsx b/WebContent/exp/MenuData.csv.xlsx deleted file mode 100644 index f3e60eba11100d3868bc8e186949e53e99bd60dc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12442 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 jAM{u0ZkoSH|Jx(UN Date: Wed, 24 Jul 2019 20:09:01 +0000 Subject: [PATCH 0459/1906] UPDATE ::: Removing unused pkql caching classes UPDATE ::: Modifying location of newer caching classes (pixel version) into old version package UPDATE ::: Using thread local for storing insight id and session id and using for rdbms frame file locations UPDATE ::: Deleting session folder on session invalidation UPDATE ::: FileUpload loads into insight folder UPDATE ::: Never deleting file's passed into saved insight (dnd always gets those files saved - will work on UI to be able to modify these) UPDATE ::: File uploads always return base $IF file path instead of returning the true system path UPDATE ::: Fixing save insight to properly parameterize with $IF (moves files into /data folder for insight post save) git-svn-id: svn://107.170.10.188:8080/Monolith/dev@33746 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: d198fe4f3a8c0c77deadbd20fb5b6ff754b572db --- .../web/services/local/AppResource.java | 39 ++- .../web/services/local/EngineResource.java | 4 +- .../semoss/web/services/local/NameServer.java | 48 ++-- src/prerna/upload/FileUploader.java | 264 ++++-------------- src/prerna/web/conf/UserSessionLoader.java | 6 + 5 files changed, 117 insertions(+), 244 deletions(-) diff --git a/src/prerna/semoss/web/services/local/AppResource.java b/src/prerna/semoss/web/services/local/AppResource.java index 4e729c364..cbb8e5c57 100644 --- a/src/prerna/semoss/web/services/local/AppResource.java +++ b/src/prerna/semoss/web/services/local/AppResource.java @@ -4,6 +4,7 @@ import java.io.FileFilter; import java.io.FileInputStream; import java.io.IOException; +import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -16,9 +17,13 @@ import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; +import javax.ws.rs.core.CacheControl; import javax.ws.rs.core.Context; +import javax.ws.rs.core.EntityTag; import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Request; import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.ResponseBuilder; import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.IOUtils; @@ -79,11 +84,24 @@ private IEngine getApp(User user, String appId) throws IllegalAccessException { @GET @Path("/appImage/download") @Produces({MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_SVG_XML}) - public Response downloadAppImage(@Context HttpServletRequest request, @PathParam("appName") String app) { + public Response downloadAppImage(@Context final Request coreRequest, @Context HttpServletRequest request, @PathParam("appName") String app) { File exportFile = getAppImageFile(app); if(exportFile != null && exportFile.exists()) { String exportName = app + "_Image." + FilenameUtils.getExtension(exportFile.getAbsolutePath()); - return Response.status(200).entity(exportFile).header("Content-Disposition", "attachment; filename=" + exportName).build(); + // want to cache this on browser if user has access + CacheControl cc = new CacheControl(); + cc.setMaxAge(86400); + cc.setPrivate(true); + EntityTag etag = new EntityTag(Integer.toString(exportFile.hashCode())); + ResponseBuilder builder = coreRequest.evaluatePreconditions(etag); + + // cached resource did not change + if(builder != null) { + return builder.build(); + } + + return Response.status(200).entity(exportFile).header("Content-Disposition", "attachment; filename=" + exportName) + .cacheControl(cc).tag(etag).lastModified(new Date(exportFile.lastModified())).build(); } else { Map errorMap = new HashMap(); errorMap.put("errorMessage", "error sending image file"); @@ -132,7 +150,7 @@ protected File getAppImageFile(String app) { @GET @Path("/insightImage/download") @Produces({MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_SVG_XML}) - public Response downloadInsightImage(@Context HttpServletRequest request, @PathParam("appName") String app, @QueryParam("rdbmsId") String id, @QueryParam("params") String params) { + public Response downloadInsightImage(@Context final Request coreRequest, @Context HttpServletRequest request, @PathParam("appName") String app, @QueryParam("rdbmsId") String id, @QueryParam("params") String params) { boolean securityEnabled = AbstractSecurityUtils.securityEnabled(); String sessionId = null; if(securityEnabled){ @@ -142,7 +160,20 @@ public Response downloadInsightImage(@Context HttpServletRequest request, @PathP File exportFile = getInsightImageFile(app, id, request.getHeader("Referer"), params, sessionId); if(exportFile != null && exportFile.exists()) { String exportName = app + "_Image." + FilenameUtils.getExtension(exportFile.getAbsolutePath()); - return Response.status(200).entity(exportFile).header("Content-Disposition", "attachment; filename=" + exportName).build(); + // want to cache this on browser if user has access + CacheControl cc = new CacheControl(); + cc.setMaxAge(86400); + cc.setPrivate(true); + EntityTag etag = new EntityTag(Integer.toString(exportFile.hashCode())); + ResponseBuilder builder = coreRequest.evaluatePreconditions(etag); + + // cached resource did not change + if(builder != null) { + return builder.build(); + } + + return Response.status(200).entity(exportFile).header("Content-Disposition", "attachment; filename=" + exportName) + .cacheControl(cc).tag(etag).lastModified(new Date(exportFile.lastModified())).build(); } else { Map errorMap = new HashMap(); errorMap.put("errorMessage", "error sending image file"); diff --git a/src/prerna/semoss/web/services/local/EngineResource.java b/src/prerna/semoss/web/services/local/EngineResource.java index 7b3926998..76272e434 100644 --- a/src/prerna/semoss/web/services/local/EngineResource.java +++ b/src/prerna/semoss/web/services/local/EngineResource.java @@ -65,10 +65,8 @@ import prerna.sablecc2.om.ReactorKeysEnum; import prerna.sablecc2.om.nounmeta.NounMetadata; import prerna.sablecc2.reactor.PixelPlanner; -import prerna.sablecc2.reactor.job.JobReactor; import prerna.sablecc2.reactor.legacy.playsheets.GetPlaysheetParamsReactor; import prerna.sablecc2.reactor.legacy.playsheets.RunPlaysheetReactor; -import prerna.semoss.web.services.local.EngineResource; import prerna.util.Constants; import prerna.util.Utility; import prerna.web.services.util.WebUtility; @@ -208,7 +206,7 @@ public Response createOutput(MultivaluedMap form, @Context HttpS Insight dummyIn = new Insight(); InsightStore.getInstance().put(dummyIn); InsightStore.getInstance().addToSessionHash(session.getId(), dummyIn.getInsightId()); - dummyIn.getVarStore().put(JobReactor.SESSION_KEY, new NounMetadata(session.getId(), PixelDataType.CONST_STRING)); +// dummyIn.getVarStore().put(JobReactor.SESSION_KEY, new NounMetadata(session.getId(), PixelDataType.CONST_STRING)); dummyIn.setUser(user); playsheetRunReactor.setInsight(dummyIn); PixelPlanner planner = new PixelPlanner(); diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index ded6cbb5b..5b6f0b611 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -43,6 +43,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.UUID; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; @@ -59,6 +60,7 @@ import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.Request; import javax.ws.rs.core.Response; import javax.ws.rs.core.StreamingOutput; @@ -92,6 +94,7 @@ import prerna.nameserver.utility.MasterDatabaseUtility; import prerna.om.Insight; import prerna.om.InsightStore; +import prerna.om.ThreadStore; import prerna.sablecc.PKQLRunner; import prerna.sablecc2.PixelRunner; import prerna.sablecc2.PixelStreamUtility; @@ -281,8 +284,6 @@ public Uploader uploadFile(@Context HttpServletRequest request) { boolean securityEnabled = AbstractSecurityUtils.securityEnabled(); Uploader upload = new FileUploader(); - String filePath = DIHelper.getInstance().getProperty(Constants.INSIGHT_CACHE_DIR) + DIR_SEPARATOR + DIHelper.getInstance().getProperty(Constants.CSV_INSIGHT_CACHE_FOLDER); - upload.setFilePath(filePath); String tempFilePath = context.getInitParameter("temp-file-upload"); upload.setTempFilePath(tempFilePath); upload.setSecurityEnabled(securityEnabled); @@ -444,18 +445,17 @@ public Response downloadFile(@QueryParam("insightId") String insightId, @QueryPa @GET @Path("/appImage") @Produces({MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_SVG_XML}) - public Response getAppImage(@Context HttpServletRequest request, @QueryParam("app") String app) { + public Response getAppImage(@Context final Request coreRequest, @Context HttpServletRequest request, @QueryParam("app") String app) { AppResource r = new AppResource(); - return r.downloadAppImage(request, app); + return r.downloadAppImage(coreRequest, request, app); } @GET @Path("/insightImage") @Produces({MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_SVG_XML}) - // TODO >>>timb: need to add rest enpoint to pull before anything else - public Response getInsightImage(@Context HttpServletRequest request, @QueryParam("app") String app, @QueryParam("rdbmsId") String insightId, @QueryParam("params") String params) { + public Response getInsightImage(@Context final Request coreRequest, @Context HttpServletRequest request, @QueryParam("app") String app, @QueryParam("rdbmsId") String insightId, @QueryParam("params") String params) { AppResource r = new AppResource(); - return r.downloadInsightImage(request, app, insightId, params); + return r.downloadInsightImage(coreRequest, request, app, insightId, params); } /////////////////////////////////////////////// @@ -519,8 +519,6 @@ public Response runPixelSync(@Context HttpServletRequest request){ } String jobId = ""; - final String tempInsightId = "TempInsightNotStored"; - String insightId = request.getParameter("insightId"); String expression = request.getParameter("expression"); Insight insight = null; @@ -528,9 +526,9 @@ public Response runPixelSync(@Context HttpServletRequest request){ // figure out the type of insight // first is temp if(insightId == null || insightId.toString().isEmpty() || insightId.equals("undefined")) { - insightId = tempInsightId; + insightId = "TempInsightNotStored_" + UUID.randomUUID().toString(); insight = new Insight(); - insight.setInsightId(tempInsightId); + insight.setInsightId(insightId); //insight.setUser(user); } else if (insightId.equals("new")) { // need to make a new insight here insight = new Insight(); @@ -562,18 +560,20 @@ public Response runPixelSync(@Context HttpServletRequest request){ insight.setUser(user); insight.setPy(jepThread); JobManager manager = JobManager.getManager(); - JobThread jt = null; - if(insightId.equals(tempInsightId)) { - jt = manager.makeJob(); - } else { - jt = manager.makeJob(insightId); - } + JobThread jt = manager.makeJob(insightId); jobId = jt.getJobId(); session.setAttribute(jobId+"", "TRUE"); - String job = "META | Job(\"" + jobId + "\", \"" + insightId + "\", \"" + sessionId + "\");"; - // add the job first - // so we can do things like logging - jt.addPixel(job); + + // set in thread + ThreadStore.setInsightId(insightId); + ThreadStore.setSessionId(sessionId); + ThreadStore.setJobId(jobId); + ThreadStore.setUser(user); + +// String job = "META | Job(\"" + jobId + "\", \"" + insightId + "\", \"" + sessionId + "\");"; +// // add the job first +// // so we can do things like logging +// jt.addPixel(job); // then add the expression jt.addPixel(expression); jt.setInsight(insight); @@ -642,9 +642,9 @@ public Response runPixelAsync(@Context HttpServletRequest request) { JobThread jt = manager.makeJob(); jobId = jt.getJobId(); session.setAttribute(jobId+"", "TRUE"); - String job = "META | Job(\"" + jobId + "\", \"" + insightId + "\", \"" + sessionId + "\");"; - // so we can do things like logging - jt.addPixel(job); +// String job = "META | Job(\"" + jobId + "\", \"" + insightId + "\", \"" + sessionId + "\");"; +// // so we can do things like logging +// jt.addPixel(job); // then add the expression jt.addPixel(expression); jt.setInsight(insight); diff --git a/src/prerna/upload/FileUploader.java b/src/prerna/upload/FileUploader.java index ca8b878c0..28a2d8353 100644 --- a/src/prerna/upload/FileUploader.java +++ b/src/prerna/upload/FileUploader.java @@ -1,11 +1,9 @@ package prerna.upload; import java.io.File; -import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; -import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -26,16 +24,9 @@ import prerna.auth.User; import prerna.auth.utils.AbstractSecurityUtils; import prerna.auth.utils.SecurityQueryUtils; -import prerna.cache.FileStore; import prerna.om.Insight; import prerna.om.InsightStore; -import prerna.poi.main.helper.CSVFileHelper; -import prerna.poi.main.helper.FileHelperUtil; -import prerna.poi.main.helper.XLFileHelper; -import prerna.poi.main.helper.excel.ExcelBlock; -import prerna.poi.main.helper.excel.ExcelRange; -import prerna.poi.main.helper.excel.ExcelSheetPreProcessor; -import prerna.poi.main.helper.excel.ExcelWorkbookFilePreProcessor; +import prerna.om.ThreadStore; import prerna.web.services.util.WebUtility; public class FileUploader extends Uploader { @@ -51,14 +42,14 @@ public class FileUploader extends Uploader { @POST @Path("baseUpload") public Response uploadFile(@Context HttpServletRequest request, @QueryParam("insightId") String insightId) { - if(AbstractSecurityUtils.securityEnabled()) { - Insight in = InsightStore.getInstance().get(insightId); - if(in == null) { - HashMap errorMap = new HashMap(); - errorMap.put("errorMessage", "Session could not be validated in order to upload files"); - return WebUtility.getResponse(errorMap, 400); - } + Insight in = InsightStore.getInstance().get(insightId); + if(in == null) { + HashMap errorMap = new HashMap(); + errorMap.put("errorMessage", "Session could not be validated in order to upload files"); + return WebUtility.getResponse(errorMap, 400); + } + if(AbstractSecurityUtils.securityEnabled()) { User user = in.getUser(); if(user == null) { HashMap errorMap = new HashMap(); @@ -79,16 +70,20 @@ public Response uploadFile(@Context HttpServletRequest request, @QueryParam("ins } } + ThreadStore.setSessionId(request.getSession().getId()); try { List fileItems = processRequest(request, insightId); // collect all of the data input on the form - List> inputData = getBaseUploadData(fileItems); + List> inputData = getBaseUploadData(fileItems, in); + // clear the thread store return WebUtility.getResponse(inputData, 200); } catch(Exception e) { e.printStackTrace(); HashMap errorMap = new HashMap(); errorMap.put("errorMessage", "Error moving file to server"); return WebUtility.getResponse(errorMap, 400); + } finally { + ThreadStore.remove(); } } @@ -97,7 +92,13 @@ public Response uploadFile(@Context HttpServletRequest request, @QueryParam("ins * @param fileItems a list of maps containing the file name and file location * @return */ - private List> getBaseUploadData(List fileItems) { + private List> getBaseUploadData(List fileItems, Insight in) { + String filePath = in.getInsightFolder(); + File fileDir = new File(filePath); + if(!fileDir.exists()) { + fileDir.mkdirs(); + } + Iterator iteratorFileItems = fileItems.iterator(); // collect all of the data input on the form @@ -109,7 +110,7 @@ private List> getBaseUploadData(List fileItems) { if (!fi.isFormField()) { // Get the uploaded file parameters String fieldName = fi.getFieldName(); - String fileName = fi.getName(); + String name = fi.getName(); // we need the key to be file if(!fieldName.equals("file")) { @@ -118,218 +119,55 @@ private List> getBaseUploadData(List fileItems) { continue; } + String fileLocation = null; + String fileSuffix = null; + Date date = new Date(); String modifiedDate = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_SSSS").format(date); - String fileLocation = null; // account for upload of an h2 // the connection url requires it to end with .mv.db // otherwise it errors - if(fileName.endsWith(".mv.db")) { - fileLocation = this.filePath + FilenameUtils.getBaseName(fileName).trim().replace(".mv", "").replace(" ", "_") - + "_____UNIQUE" - + modifiedDate - + ".mv.db"; + if(name.endsWith(".mv.db")) { + fileSuffix = FilenameUtils.getBaseName(name).trim().replace(".mv", "").replace(" ", "_") + + "_____UNIQUE" + modifiedDate + ".mv.db"; } else { - fileLocation = this.filePath + FilenameUtils.getBaseName(fileName).trim().replace(" ", "_") - + "_____UNIQUE" - + modifiedDate - + "." - + FilenameUtils.getExtension(fileName); + fileSuffix = FilenameUtils.getBaseName(name).trim().replace(" ", "_") + + "_____UNIQUE" + modifiedDate + "." + FilenameUtils.getExtension(name); } + fileLocation = filePath + DIR_SEPARATOR + fileSuffix; File file = new File(fileLocation); writeFile(fi, file); - LOGGER.info("Saved Filename: " + fileName + " to "+ file); + LOGGER.info("Saved Filename: " + name + " to "+ file); Map fileMap = new HashMap(); - fileMap.put("fileName", fileName); - fileMap.put("fileLocation", fileLocation); + fileMap.put("fileName", name); + fileMap.put("fileLocation", Insight.INSIGHT_FILE_KEY + DIR_SEPARATOR + fileSuffix); retData.add(fileMap); - } - - // delete the field - fi.delete(); - } - - return retData; - } - - - @POST - @Path("determineDataTypesForFile") - public Response determineDataTypesForFile(@Context HttpServletRequest request) { - try { - List fileItems = processRequest(request, null); - // collect all of the data input on the form - Hashtable inputData = getInputData(fileItems); - Map retObj = generateDataTypes(inputData); - return WebUtility.getResponse(retObj, 200); - } catch(Exception e) { - e.printStackTrace(); - HashMap errorMap = new HashMap(); - errorMap.put("errorMessage", "Error processing new data"); - return WebUtility.getResponse(errorMap, 400); - } - } - - - /** - * - * @param inputData - * @return - * @throws IOException - */ - protected static Map generateDataTypes(Map inputData) throws IOException { - Map retObj = new HashMap(); - - String fileLoc = inputData.get("file"); - String uniqueStorageId = FileStore.getInstance().put(fileLoc); - retObj.put("uniqueFileKey", uniqueStorageId); - if(fileLoc.endsWith(".xlsx") || fileLoc.endsWith(".xlsm")) { - - // new approach - { - Map> newPayload = new HashMap>(); - - ExcelWorkbookFilePreProcessor preProcessor = new ExcelWorkbookFilePreProcessor(); - preProcessor.parse(fileLoc); - Map sProcessors = preProcessor.getSheetProcessors(); - for(String sheet : sProcessors.keySet()) { - ExcelSheetPreProcessor processor = sProcessors.get(sheet); - List blocks = processor.getAllBlocks(); - - Map rangeInfo = new HashMap(); - - for(ExcelBlock block : blocks) { - List ranges = block.getRanges(); - for(ExcelRange r : ranges) { - String rSyntax = r.getRangeSyntax(); - String[] origHeaders = processor.getRangeHeaders(r); - String[] cleanedHeaders = processor.getCleanedRangeHeaders(r); - - Object[][] rangeTypes = block.getRangeTypes(r); - Map[] retMaps = FileHelperUtil.generateDataTypeMapsFromPrediction(cleanedHeaders, rangeTypes); - Map typeMap = new HashMap(); - typeMap.put("dataTypes", retMaps[0]); - typeMap.put("additionalDataTypes", retMaps[1]); - - Map rangeMap = new HashMap(); - rangeMap.put("headers", origHeaders); - rangeMap.put("cleanHeaders", cleanedHeaders); - rangeMap.put("types", typeMap); - - rangeInfo.put(rSyntax, rangeMap); - } - } - - // add all ranges in the sheet - newPayload.put(sheet, rangeInfo); - } - - // put in return object - retObj.put("newPayload", newPayload); - preProcessor.clear(); - } - - // old - { - XLFileHelper helper = new XLFileHelper(); - helper.parse(fileLoc); - - String[] sheets = helper.getTables(); - for(int i = 0; i < sheets.length; i++) { - String sheetName = sheets[i]; - String[] headers = helper.getHeaders(sheetName); - Map[] retMaps = FileHelperUtil.generateDataTypeMapsFromPrediction(headers, helper.predictTypes(sheetName)); - - Map innerObj = new HashMap(); - innerObj.put("dataTypes", retMaps[0]); - innerObj.put("additionalDataTypes", retMaps[1]); - retObj.put(sheetName, innerObj); - } - - helper.clear(); - } - } else { - String delimiter = inputData.get("delimiter"); - // generate tinker frame from - if(inputData.get("delimiter") == null || inputData.get("delimiter").isEmpty()) { - delimiter = "\t"; - } - - CSVFileHelper helper = new CSVFileHelper(); - helper.setDelimiter(delimiter.charAt(0)); - helper.parse(fileLoc); - - String[] headers = helper.getHeaders(); - Map[] retMaps = FileHelperUtil.generateDataTypeMapsFromPrediction(headers, helper.predictTypes()); - - Map innerObj = new HashMap(); - innerObj.put("dataTypes", retMaps[0]); - innerObj.put("additionalDataTypes", retMaps[1]); - retObj.put(CSV_FILE_KEY, innerObj); - retObj.put("delimiter", delimiter); - helper.clear(); - } - - return retObj; - } - - - /** - * Extract the data to generate the file being passed from the user to the BE server - */ - @Override - protected Hashtable getInputData(List fileItems) - { - // Process the uploaded file items - Iterator iteratorFileItems = fileItems.iterator(); - - // collect all of the data input on the form - Hashtable inputData = new Hashtable(); - File file; - - while(iteratorFileItems.hasNext()) - { - FileItem fi = (FileItem) iteratorFileItems.next(); - // Get the uploaded file parameters - String fieldName = fi.getFieldName(); - String fileName = fi.getName(); - String value = fi.getString(); - if (!fi.isFormField()) { - if(fileName.equals("")) { - continue; - } - else { - if(fieldName.equals("file")) { - // need to clean the fileName to not have ";" since we split on that in upload data - fileName = fileName.replace(";", ""); - Date date = new Date(); - String modifiedDate = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_SSSS").format(date); - value = filePath + "\\\\" + fileName.substring(fileName.lastIndexOf("\\") + 1, fileName.lastIndexOf(".")).replace(" ", "") + "_____UNIQUE" + modifiedDate + fileName.substring(fileName.lastIndexOf(".")); - file = new File(value); - writeFile(fi, file); - LOGGER.info("Saved Filename: " + fileName + " to "+ file); - } - } - } else if(fieldName.equals("file")) { // its a file, but not in a form - System.err.println("Writing input string into file..."); + } else if(fi.getName().equals("file")) { + // its a file, but not in a form + // i.e. this is a person copy/pasting + // the values directly + LOGGER.info("Writing Input To File"); Date date = new Date(); String modifiedDate = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_SSSS").format(date); - value = filePath + "\\\\FileString_" + modifiedDate; - file = new File(value); + + String fileSuffix = "FileString_" + modifiedDate;; + String fileLocation = filePath + DIR_SEPARATOR + fileSuffix; + File file = new File(fileLocation); writeFile(fi, file); - LOGGER.info( "Created new file..."); - } - //need to handle multiple files getting selected for upload - if(inputData.get(fieldName) != null) - { - value = inputData.get(fieldName) + ";" + value; + LOGGER.info("Saved Pasted Data To "+ file); + + Map fileMap = new HashMap(); + fileMap.put("fileName", "FileString_" + modifiedDate); + fileMap.put("fileLocation", Insight.INSIGHT_FILE_KEY + DIR_SEPARATOR + fileSuffix); + retData.add(fileMap); } - inputData.put(fieldName, value); + + // delete the field fi.delete(); } - return inputData; + return retData; } } diff --git a/src/prerna/web/conf/UserSessionLoader.java b/src/prerna/web/conf/UserSessionLoader.java index 66df359f1..2adf2364b 100644 --- a/src/prerna/web/conf/UserSessionLoader.java +++ b/src/prerna/web/conf/UserSessionLoader.java @@ -12,17 +12,20 @@ import org.apache.log4j.Logger; import prerna.auth.SyncUserAppsThread; +import prerna.cache.ICache; import prerna.ds.py.PyExecutorThread; import prerna.ds.py.PyUtils; import prerna.om.Insight; import prerna.om.InsightStore; import prerna.util.Constants; +import prerna.util.DIHelper; import prerna.util.insight.InsightUtility; @WebListener public class UserSessionLoader implements HttpSessionListener { private static final Logger LOGGER = LogManager.getLogger(UserSessionLoader.class.getName()); + private static final String DIR_SEPARATOR = java.nio.file.FileSystems.getDefault().getSeparator(); public void sessionCreated(HttpSessionEvent sessionEvent) { @@ -55,6 +58,9 @@ public void sessionDestroyed(HttpSessionEvent sessionEvent) { insightIDs.removeAll(copy); } + String sessionStorage = DIHelper.getInstance().getProperty(Constants.INSIGHT_CACHE_DIR) + DIR_SEPARATOR + sessionId; + ICache.deleteFolder(sessionStorage); + // now drop the thread if(PyUtils.pyEnabled()) { LOGGER.info("Drop session py thread"); From 8ade2d3e4a52f23084f5a89665ce17ef729468dd Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 25 Jul 2019 15:09:35 +0000 Subject: [PATCH 0460/1906] UPDATE ::: Adding back META Job reactor UPDATE ::: Instead of passing in boolean to ignore first value, ignoring Job op type if it is first and if not the only operation returned git-svn-id: svn://107.170.10.188:8080/Monolith/dev@33756 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: d018ee3c3fdcf3c3c01881d6bd739a97109029af --- src/prerna/semoss/web/services/local/NameServer.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index 5b6f0b611..f202abf70 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -570,10 +570,10 @@ public Response runPixelSync(@Context HttpServletRequest request){ ThreadStore.setJobId(jobId); ThreadStore.setUser(user); -// String job = "META | Job(\"" + jobId + "\", \"" + insightId + "\", \"" + sessionId + "\");"; + String job = "META | Job(\"" + jobId + "\", \"" + insightId + "\", \"" + sessionId + "\");"; // // add the job first // // so we can do things like logging -// jt.addPixel(job); + jt.addPixel(job); // then add the expression jt.addPixel(expression); jt.setInsight(insight); From 1ec9ec2d23a9e3d70db1b9e555b454a2b57e3f0d Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 26 Jul 2019 00:04:40 +0000 Subject: [PATCH 0461/1906] BUGFIX ::: Fixing bug with not passing session id for playsheet insights git-svn-id: svn://107.170.10.188:8080/Monolith/dev@33780 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 8b83ba122cb6bc6aafc3da649add5ca7f8ec6565 --- src/prerna/semoss/web/services/local/EngineResource.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/prerna/semoss/web/services/local/EngineResource.java b/src/prerna/semoss/web/services/local/EngineResource.java index 76272e434..94c167e44 100644 --- a/src/prerna/semoss/web/services/local/EngineResource.java +++ b/src/prerna/semoss/web/services/local/EngineResource.java @@ -65,6 +65,7 @@ import prerna.sablecc2.om.ReactorKeysEnum; import prerna.sablecc2.om.nounmeta.NounMetadata; import prerna.sablecc2.reactor.PixelPlanner; +import prerna.sablecc2.reactor.job.JobReactor; import prerna.sablecc2.reactor.legacy.playsheets.GetPlaysheetParamsReactor; import prerna.sablecc2.reactor.legacy.playsheets.RunPlaysheetReactor; import prerna.util.Constants; @@ -206,7 +207,7 @@ public Response createOutput(MultivaluedMap form, @Context HttpS Insight dummyIn = new Insight(); InsightStore.getInstance().put(dummyIn); InsightStore.getInstance().addToSessionHash(session.getId(), dummyIn.getInsightId()); -// dummyIn.getVarStore().put(JobReactor.SESSION_KEY, new NounMetadata(session.getId(), PixelDataType.CONST_STRING)); + dummyIn.getVarStore().put(JobReactor.SESSION_KEY, new NounMetadata(session.getId(), PixelDataType.CONST_STRING)); dummyIn.setUser(user); playsheetRunReactor.setInsight(dummyIn); PixelPlanner planner = new PixelPlanner(); From ce31eaa8ee741a5d2e17e05ddd1276c8000aa86d Mon Sep 17 00:00:00 2001 From: davyzhang Date: Wed, 31 Jul 2019 19:12:15 +0000 Subject: [PATCH 0462/1906] BUGFIX ::: grabbing the right name when loading pasted data: fi.getName() --> fi.getFieldName() git-svn-id: svn://107.170.10.188:8080/Monolith/dev@33878 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 2f773fe1e33c5bae7bf965159b11ee789e7706bf --- src/prerna/upload/FileUploader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prerna/upload/FileUploader.java b/src/prerna/upload/FileUploader.java index 28a2d8353..2f5ff2eb8 100644 --- a/src/prerna/upload/FileUploader.java +++ b/src/prerna/upload/FileUploader.java @@ -144,7 +144,7 @@ private List> getBaseUploadData(List fileItems, In fileMap.put("fileName", name); fileMap.put("fileLocation", Insight.INSIGHT_FILE_KEY + DIR_SEPARATOR + fileSuffix); retData.add(fileMap); - } else if(fi.getName().equals("file")) { + } else if(fi.getFieldName().equals("file")) { // its a file, but not in a form // i.e. this is a person copy/pasting // the values directly From e84883f3f548e89ddcf1a8b8b2da950728d11278 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 5 Aug 2019 16:24:35 +0000 Subject: [PATCH 0463/1906] UPDATE ::: Adding ability to toggle between enabling anonymous users to upload data (file drag n drop) git-svn-id: svn://107.170.10.188:8080/Monolith/dev@33956 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 698fbf3e87bf50b42100919e61b761dfbc0ba550 --- WebContent/WEB-INF/web.xml | 4 ++++ src/prerna/upload/FileUploader.java | 2 +- src/prerna/web/conf/DBLoader.java | 8 +++++++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index 98a86d088..fdc7e68ba 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -215,6 +215,10 @@ anonymous-users-allowed false + + + anonymous-users-upload-data + false Location to store uploaded file diff --git a/src/prerna/upload/FileUploader.java b/src/prerna/upload/FileUploader.java index 2f5ff2eb8..8174e0a16 100644 --- a/src/prerna/upload/FileUploader.java +++ b/src/prerna/upload/FileUploader.java @@ -57,7 +57,7 @@ public Response uploadFile(@Context HttpServletRequest request, @QueryParam("ins return WebUtility.getResponse(errorMap, 400); } - if(user.isAnonymous()) { + if(user.isAnonymous() && !AbstractSecurityUtils.anonymousUserUploadData()) { HashMap errorMap = new HashMap(); errorMap.put("errorMessage", "Must be logged in to upload files "); return WebUtility.getResponse(errorMap, 400); diff --git a/src/prerna/web/conf/DBLoader.java b/src/prerna/web/conf/DBLoader.java index f536b1ae0..82f582bb5 100644 --- a/src/prerna/web/conf/DBLoader.java +++ b/src/prerna/web/conf/DBLoader.java @@ -96,7 +96,12 @@ public void contextInitialized(ServletContextEvent arg0) { anonymousUsersEnabled = "false"; } context.setInitParameter(Constants.ANONYMOUS_USER_ALLOWED, anonymousUsersEnabled); - + // see if anonymous users can upload data + String anonymousUsersUploadData = context.getInitParameter(Constants.ANONYMOUS_USER_UPLOAD_DATA); + if(anonymousUsersUploadData == null) { + anonymousUsersUploadData = "false"; + } + context.setInitParameter(Constants.ANONYMOUS_USER_UPLOAD_DATA, anonymousUsersUploadData); // get the session id key if(context.getSessionCookieConfig() != null) { @@ -128,6 +133,7 @@ public void contextInitialized(ServletContextEvent arg0) { DIHelper.getInstance().setLocalProperty(Constants.ADMIN_SET_PUBLIC, adminSetPublicOnly); DIHelper.getInstance().setLocalProperty(Constants.ADMIN_SET_PUBLISHER, adminSetPublisher); DIHelper.getInstance().setLocalProperty(Constants.ANONYMOUS_USER_ALLOWED, anonymousUsersEnabled); + DIHelper.getInstance().setLocalProperty(Constants.ANONYMOUS_USER_UPLOAD_DATA, anonymousUsersUploadData); DIHelper.getInstance().setLocalProperty(Constants.SESSION_ID_KEY, SESSION_ID_KEY); //Load empty engine list into DIHelper, then load engines from db folder From ea929df1bf7dce3c8fe463c0e9ac967b7cfa6283 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 5 Aug 2019 16:33:23 +0000 Subject: [PATCH 0464/1906] UPDATE ::: Also returning additional metadata around server configuration for anonymous users git-svn-id: svn://107.170.10.188:8080/Monolith/dev@33957 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 35ae728380cb7ab76d9e1bf1ef7ea0247c01dff2 --- .../web/services/config/ServerConfigurationResource.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/prerna/semoss/web/services/config/ServerConfigurationResource.java b/src/prerna/semoss/web/services/config/ServerConfigurationResource.java index fa1482482..6b190256c 100644 --- a/src/prerna/semoss/web/services/config/ServerConfigurationResource.java +++ b/src/prerna/semoss/web/services/config/ServerConfigurationResource.java @@ -70,7 +70,9 @@ private static Map getConfig(@Context HttpServletRequest request // security enabled config.put("security", AbstractSecurityUtils.securityEnabled()); - // r enabled + config.put("anonymousUsers", AbstractSecurityUtils.anonymousUsersEnabled()); + config.put("anonymousUserUploadData", AbstractSecurityUtils.anonymousUserUploadData()); + // admin set public enabled boolean adminSetPublic = false; String adminSetPublicStr = (String) DIHelper.getInstance().getLocalProp(Constants.ADMIN_SET_PUBLIC); if(adminSetPublicStr != null) { From ddbaef42b3de59c37a5a017b98d7df1a98e08126 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 5 Aug 2019 17:50:39 +0000 Subject: [PATCH 0465/1906] UPDATE ::: Not allowing users to upload files in saved insights git-svn-id: svn://107.170.10.188:8080/Monolith/dev@33959 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: a211a6bd8c48411a03c9b94f0ee28257e58a9bcd --- src/prerna/upload/FileUploader.java | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/prerna/upload/FileUploader.java b/src/prerna/upload/FileUploader.java index 8174e0a16..4463d29b2 100644 --- a/src/prerna/upload/FileUploader.java +++ b/src/prerna/upload/FileUploader.java @@ -23,6 +23,7 @@ import prerna.auth.User; import prerna.auth.utils.AbstractSecurityUtils; +import prerna.auth.utils.SecurityInsightUtils; import prerna.auth.utils.SecurityQueryUtils; import prerna.om.Insight; import prerna.om.InsightStore; @@ -59,13 +60,25 @@ public Response uploadFile(@Context HttpServletRequest request, @QueryParam("ins if(user.isAnonymous() && !AbstractSecurityUtils.anonymousUserUploadData()) { HashMap errorMap = new HashMap(); - errorMap.put("errorMessage", "Must be logged in to upload files "); + errorMap.put("errorMessage", "Must be logged in to upload files"); + return WebUtility.getResponse(errorMap, 400); + } + + if(user.isAnonymous() && in.isSavedInsight()) { + HashMap errorMap = new HashMap(); + errorMap.put("errorMessage", "Must be logged in to upload files to a saved insight"); + return WebUtility.getResponse(errorMap, 400); + } + + if(in.isSavedInsight() && !SecurityInsightUtils.userCanEditInsight(user, in.getEngineId(), in.getRdbmsId())) { + HashMap errorMap = new HashMap(); + errorMap.put("errorMessage", "User does not edit access for this insight"); return WebUtility.getResponse(errorMap, 400); } if(AbstractSecurityUtils.adminSetPublisher() && !SecurityQueryUtils.userIsPublisher(user)) { HashMap errorMap = new HashMap(); - errorMap.put("errorMessage", "User does not have permission to publish data"); + errorMap.put("errorMessage", "User does not have permission to publish data. Please reach out to the admin to get proper access"); return WebUtility.getResponse(errorMap, 400); } } From 5b388ec1da4b3f984f03a36e6e02642456acc4b1 Mon Sep 17 00:00:00 2001 From: kunalppatel9 Date: Tue, 6 Aug 2019 16:11:21 +0000 Subject: [PATCH 0466/1906] BUGFIX ::: Google OAuth Fix. Decoding return code before sending request for access token to prevent double encoding and malformed request code git-svn-id: svn://107.170.10.188:8080/Monolith/dev@33981 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: fd147ac62b3edcb91efcc2b87ca582a8aa507e78 --- src/prerna/semoss/web/services/local/UserResource.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index 4799822be..0bea42fe8 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -963,11 +963,12 @@ public Response loginGoogle(@Context HttpServletRequest request, @Context HttpSe String redirectUri = socialData.getProperty(prefix+"redirect_uri"); System.out.println(">> " + request.getQueryString()); - + //I need to decode the return code from google since the default param's are encoded on the post of getAccessToken + String codeDecode = URLDecoder.decode(outputs[0]); Hashtable params = new Hashtable(); params.put("client_id", clientId); params.put("redirect_uri", redirectUri); - params.put("code", outputs[0]); + params.put("code", codeDecode); params.put("grant_type", "authorization_code"); params.put("client_secret", clientSecret); @@ -1607,6 +1608,7 @@ private void setMainPageRedirect(@Context HttpServletRequest request, @Context H response.setStatus(302); try { Cookie cookie = new Cookie(DBLoader.getSessionIdKey(), request.getSession().getId()); + //cookie.setPath("/dev"); response.addCookie(cookie); if(redirect == null) { response.sendRedirect(socialData.getProperty("redirect")); From fd707e521f775d6e0c5da8f6d791f18e0fc6cf9b Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 14 Aug 2019 18:30:32 +0000 Subject: [PATCH 0467/1906] UPDATE ::: Adding pipeline translation to get back routines to paint on FE UPDATE ::: Fixing some locations where we return a null in a noun during lazy execution UPDATE ::: Adding new rest endpoint to get the pipeline portions for a new pixel execution git-svn-id: svn://107.170.10.188:8080/Monolith/dev@34192 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 638acbd1fe26e3399f2aec017fd692a69b8821c9 --- .../semoss/web/services/local/NameServer.java | 80 +++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index f202abf70..9009d6648 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -98,6 +98,7 @@ import prerna.sablecc.PKQLRunner; import prerna.sablecc2.PixelRunner; import prerna.sablecc2.PixelStreamUtility; +import prerna.sablecc2.PixelUtility; import prerna.sablecc2.comm.JobManager; import prerna.sablecc2.comm.JobThread; import prerna.semoss.web.services.remote.CentralNameServer; @@ -110,6 +111,7 @@ import prerna.util.DIHelper; import prerna.util.PlaySheetRDFMapBasedEnum; import prerna.util.Utility; +import prerna.util.gson.GsonUtility; import prerna.util.insight.InsightUtility; import prerna.web.conf.SessionCounter; import prerna.web.services.util.ResponseHashSingleton; @@ -585,6 +587,84 @@ public Response runPixelSync(@Context HttpServletRequest request){ } } + @POST + @Path("/getPipeline") + @Produces("application/json;charset=utf-8") + public Response getPixelPipelinePlan(@Context HttpServletRequest request){ + HttpSession session = null; + String sessionId = null; + User user = null; + PyExecutorThread jepThread = null; + + boolean securityEnabled = AbstractSecurityUtils.securityEnabled(); + //If security is enabled try to get an existing session. + //Otherwise get a session with the default user. + if(securityEnabled){ + session = request.getSession(false); + if(session != null){ + sessionId = session.getId(); + user = ((User) session.getAttribute(Constants.SESSION_USER)); + + // need to see if the user is enabling python here.. I will assume it is here + if(session.getAttribute(Constants.PYTHON) != null) { + jepThread = (PyExecutorThread)session.getAttribute(Constants.PYTHON); + } + } + + if(user == null) { + Map errorMap = new HashMap(); + errorMap.put("error", "User session is invalid"); + System.out.println("User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + } else { + session = request.getSession(true); + user = ((User) session.getAttribute(Constants.SESSION_USER)); + sessionId = session.getId(); + if(PyUtils.pyEnabled() && this.jepThread == null) { + this.jepThread = PyUtils.getInstance().getJep(); + } + jepThread = this.jepThread; + } + + String insightId = request.getParameter("insightId"); + String expression = request.getParameter("expression"); + Insight insight = InsightStore.getInstance().get(insightId); + if (insight == null) { + Map errorMap = new HashMap(); + errorMap.put("errorMessage", "Could not find the insight id"); + return WebUtility.getResponse(errorMap, 400); + } + // make sure we have the correct session trying to get this id + // #soMuchSecurity + // Set sessionStore = InsightStore.getInstance().getInsightIDsForSession(sessionId); + // if(sessionStore == null || !sessionStore.contains(insightId)) { + // Map errorMap = new HashMap(); + // errorMap.put("errorMessage", "Trying to access insight id from incorrect session"); + // return WebUtility.getResponse(errorMap, 400); + // } + synchronized(insight) { + // set the user + insight.setUser(user); + insight.setPy(jepThread); + + // set in thread + ThreadStore.setInsightId(insightId); + ThreadStore.setSessionId(sessionId); + ThreadStore.setUser(user); + + try { + return Response.status(200).entity( + GsonUtility.getDefaultGson().toJson(PixelUtility.generatePipeline(insight, expression)) + ).build(); + } catch(Exception e) { + Map errorMap = new HashMap(); + errorMap.put("errorMessage", e.getMessage()); + return WebUtility.getResponse(errorMap, 400); + } + } + } + @POST @Path("runPixelAsync") @Produces("application/json;charset=utf-8") From 313b6847508108103f84bdc53685e157d250a358 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 15 Aug 2019 19:06:39 +0000 Subject: [PATCH 0468/1906] UPDATE ::: Commenting out storm which is unused git-svn-id: svn://107.170.10.188:8080/Monolith/dev@34231 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 37a75782eef7d8d418b854310dd9f9644e4704a3 --- pom.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pom.xml b/pom.xml index 980569f80..3a52da980 100644 --- a/pom.xml +++ b/pom.xml @@ -280,10 +280,12 @@ + redshift http://redshift-maven-repository.s3-website-us-east-1.amazonaws.com/release From 087776ccc69669aaf1890a2370dc15efd6787d30 Mon Sep 17 00:00:00 2001 From: kunalppatel9 Date: Fri, 16 Aug 2019 15:40:49 +0000 Subject: [PATCH 0469/1906] UPDATE ::: Seeing if pom change is causing deploy issues git-svn-id: svn://107.170.10.188:8080/Monolith/dev@34257 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: ffd3037c59ddf36a4eeabea7c7ad4d688d128a63 --- pom.xml | 2 -- 1 file changed, 2 deletions(-) diff --git a/pom.xml b/pom.xml index 3a52da980..980569f80 100644 --- a/pom.xml +++ b/pom.xml @@ -280,12 +280,10 @@ - redshift http://redshift-maven-repository.s3-website-us-east-1.amazonaws.com/release From 20515162de7ce593819afdc8c90e6cbabdb0ca63 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 16 Aug 2019 19:00:38 +0000 Subject: [PATCH 0470/1906] UPDATE ::: Removing unnecessary repo git-svn-id: svn://107.170.10.188:8080/Monolith/dev@34264 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 13e901ef968c0965656a28791f25b2a024b19fee --- pom.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pom.xml b/pom.xml index 980569f80..ded09edac 100644 --- a/pom.xml +++ b/pom.xml @@ -280,10 +280,12 @@ + redshift http://redshift-maven-repository.s3-website-us-east-1.amazonaws.com/release From 38fb8af6d939bb3d038662c6021ed487ebbd02c7 Mon Sep 17 00:00:00 2001 From: kunalppatel9 Date: Thu, 22 Aug 2019 13:40:13 +0000 Subject: [PATCH 0471/1906] BUGFIX ::: Removing innacurate log message git-svn-id: svn://107.170.10.188:8080/Monolith/dev@34352 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: a548485effa47320780cf9fa183e1730e734d7e2 --- src/prerna/web/conf/UserSessionLoader.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/prerna/web/conf/UserSessionLoader.java b/src/prerna/web/conf/UserSessionLoader.java index 2adf2364b..b4a88c82a 100644 --- a/src/prerna/web/conf/UserSessionLoader.java +++ b/src/prerna/web/conf/UserSessionLoader.java @@ -63,7 +63,6 @@ public void sessionDestroyed(HttpSessionEvent sessionEvent) { // now drop the thread if(PyUtils.pyEnabled()) { - LOGGER.info("Drop session py thread"); PyExecutorThread pyThread = (PyExecutorThread) session.getAttribute(Constants.PYTHON); PyUtils.getInstance().killPyThread(pyThread); } From 1f5a1973bcfb4843e0e9cd9785eb95de2263db57 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 28 Aug 2019 17:54:42 +0000 Subject: [PATCH 0472/1906] UPDATE ::: Commenting out unused methods git-svn-id: svn://107.170.10.188:8080/Monolith/dev@34436 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 3343727200dcce7dbdc12d4928fd4bebd24b8bda --- .../semoss/web/services/local/NameServer.java | 134 +++++++++--------- .../services/remote/CentralNameServer.java | 84 +++++------ src/prerna/web/conf/CACFilter.java | 90 ++++++------ 3 files changed, 152 insertions(+), 156 deletions(-) diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index 9009d6648..e40756c0d 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -78,7 +78,6 @@ import com.google.gson.Gson; import com.google.gson.internal.StringMap; -import com.google.gson.reflect.TypeToken; import prerna.auth.User; import prerna.auth.utils.AbstractSecurityUtils; @@ -1170,9 +1169,6 @@ public StreamingOutput runPkql(MultivaluedMap form ) { return WebUtility.getSO(resultHash); } - - - //////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////// ////////////////////////////// START SEARCH BAR /////////////////////////////////// @@ -1243,70 +1239,70 @@ public StreamingOutput getSearchInsightsResults(MultivaluedMap f /////////////////////////////// END SEARCH BAR //////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////// - - @POST - @Path("central/context/getConnectedConcepts2") - @Produces("application/json") - public StreamingOutput getConnectedConcepts(MultivaluedMap form, @Context HttpServletRequest request) { - Gson gson = new Gson(); - List conceptLogicalNames = gson.fromJson(form.getFirst("conceptURI"), new TypeToken>() {}.getType()); - if(conceptLogicalNames == null || conceptLogicalNames.isEmpty()) { - return WebUtility.getSO(""); - } - return WebUtility.getSO(MasterDatabaseUtility.getConnectedConceptsRDBMS(conceptLogicalNames, null)); - } - - @POST - @Path("central/context/conceptProperties") - @Produces("application/json") - public Response getConceptProperties(MultivaluedMap form, @Context HttpServletRequest request) - { - Gson gson = new Gson(); - List conceptLogicalNames = gson.fromJson(form.getFirst("conceptURI"), new TypeToken>() {}.getType()); - if(conceptLogicalNames == null || conceptLogicalNames.isEmpty()) { - // return Response.status(200).entity(WebUtility.getSO("")).build(); - return WebUtility.getResponse("", 200); - } - // return Response.status(200).entity(WebUtility.getSO(DatabasePkqlService.getConceptProperties(conceptLogicalNames, null))).build(); - return WebUtility.getResponse(MasterDatabaseUtility.getConceptPropertiesRDBMS(conceptLogicalNames, null), 200); - } - - @POST - @Path("central/context/conceptLogicals") - @Produces("application/json") - public Response getAllLogicalNamesFromConceptual(MultivaluedMap form, @Context HttpServletRequest request) - { - Gson gson = new Gson(); - List conceptualName = gson.fromJson(form.getFirst("conceptURI"), new TypeToken>() {}.getType()); - if(conceptualName == null || conceptualName.isEmpty()) { - // return Response.status(200).entity(WebUtility.getSO("")).build(); - return WebUtility.getResponse("", 200); - } - int size = conceptualName.size(); - - // List parentConceptualName = gson.fromJson(form.getFirst("parentConcept"), new TypeToken>() {}.getType()); - // if(parentConceptualName != null) { - // // TODO: yell at FE - // // ugh, FE, why do you send parent as the string "undefined" - // // ugh, BE, how to tell FE that the prim key that is generated for metamodel view is fake - // List cleanParentConceptualName = new Vector(); - // for(int i = 0; i < size; i++) { - // String val = parentConceptualName.get(i); - // if(val == null) { - // cleanParentConceptualName.add(null); - // } else if(val.equals("undefined") || val.startsWith(TinkerFrame.PRIM_KEY) || val.isEmpty()) { - // cleanParentConceptualName.add(null); - // } else { - // cleanParentConceptualName.add(val); - // } - // } - // - // // override reference to parent conceptual name - // // can just keep it as null when we pass back the info to the FE - // parentConceptualName = cleanParentConceptualName; - // } - // return Response.status(200).entity(WebUtility.getSO(DatabasePkqlService.getAllLogicalNamesFromConceptual(conceptualName, parentConceptualName))).build(); - return WebUtility.getResponse(MasterDatabaseUtility.getAllLogicalNamesFromConceptualRDBMS(conceptualName), 200); - } +// +// @POST +// @Path("central/context/getConnectedConcepts2") +// @Produces("application/json") +// public StreamingOutput getConnectedConcepts(MultivaluedMap form, @Context HttpServletRequest request) { +// Gson gson = new Gson(); +// List conceptLogicalNames = gson.fromJson(form.getFirst("conceptURI"), new TypeToken>() {}.getType()); +// if(conceptLogicalNames == null || conceptLogicalNames.isEmpty()) { +// return WebUtility.getSO(""); +// } +// return WebUtility.getSO(MasterDatabaseUtility.getConnectedConceptsRDBMS(conceptLogicalNames, null)); +// } +// +// @POST +// @Path("central/context/conceptProperties") +// @Produces("application/json") +// public Response getConceptProperties(MultivaluedMap form, @Context HttpServletRequest request) +// { +// Gson gson = new Gson(); +// List conceptLogicalNames = gson.fromJson(form.getFirst("conceptURI"), new TypeToken>() {}.getType()); +// if(conceptLogicalNames == null || conceptLogicalNames.isEmpty()) { +// // return Response.status(200).entity(WebUtility.getSO("")).build(); +// return WebUtility.getResponse("", 200); +// } +// // return Response.status(200).entity(WebUtility.getSO(DatabasePkqlService.getConceptProperties(conceptLogicalNames, null))).build(); +// return WebUtility.getResponse(MasterDatabaseUtility.getConceptProperties(conceptLogicalNames, null), 200); +// } +// +// @POST +// @Path("central/context/conceptLogicals") +// @Produces("application/json") +// public Response getAllLogicalNamesFromConceptual(MultivaluedMap form, @Context HttpServletRequest request) +// { +// Gson gson = new Gson(); +// List conceptualName = gson.fromJson(form.getFirst("conceptURI"), new TypeToken>() {}.getType()); +// if(conceptualName == null || conceptualName.isEmpty()) { +// // return Response.status(200).entity(WebUtility.getSO("")).build(); +// return WebUtility.getResponse("", 200); +// } +// int size = conceptualName.size(); +// +// // List parentConceptualName = gson.fromJson(form.getFirst("parentConcept"), new TypeToken>() {}.getType()); +// // if(parentConceptualName != null) { +// // // TODO: yell at FE +// // // ugh, FE, why do you send parent as the string "undefined" +// // // ugh, BE, how to tell FE that the prim key that is generated for metamodel view is fake +// // List cleanParentConceptualName = new Vector(); +// // for(int i = 0; i < size; i++) { +// // String val = parentConceptualName.get(i); +// // if(val == null) { +// // cleanParentConceptualName.add(null); +// // } else if(val.equals("undefined") || val.startsWith(TinkerFrame.PRIM_KEY) || val.isEmpty()) { +// // cleanParentConceptualName.add(null); +// // } else { +// // cleanParentConceptualName.add(val); +// // } +// // } +// // +// // // override reference to parent conceptual name +// // // can just keep it as null when we pass back the info to the FE +// // parentConceptualName = cleanParentConceptualName; +// // } +// // return Response.status(200).entity(WebUtility.getSO(DatabasePkqlService.getAllLogicalNamesFromConceptual(conceptualName, parentConceptualName))).build(); +// return WebUtility.getResponse(MasterDatabaseUtility.getAllLogicalNamesFromConceptualRDBMS(conceptualName), 200); +// } } diff --git a/src/prerna/semoss/web/services/remote/CentralNameServer.java b/src/prerna/semoss/web/services/remote/CentralNameServer.java index 39d8da0e9..76628f94b 100644 --- a/src/prerna/semoss/web/services/remote/CentralNameServer.java +++ b/src/prerna/semoss/web/services/remote/CentralNameServer.java @@ -89,46 +89,46 @@ public void setCentralApi(String centralApi){ // return ns.getCentralContextInsights(form, request); // } // } - - @POST - @Path("context/getConnectedConcepts") - public StreamingOutput getConnectedConcepts( - MultivaluedMap form, - @Context HttpServletRequest request) - { - String conceptURI = form.getFirst("conceptURI"); - logger.info("LOCALLY have concept selected as ::: " + conceptURI); - - if(centralApi!=null) { - Hashtable params = new Hashtable(); - params.put("conceptURI", conceptURI); - return WebUtility.getSO(Utility.retrieveResult(centralApi + "/api/engine/central/context/getConnectedConcepts2", params)); - } else { - NameServer ns = new NameServer(); - form.put("localMasterDbName", localDb); - return ns.getConnectedConcepts(form, request); - } - } - - @POST - @Path("central/context/insights") - @Produces("application/json") - public StreamingOutput getCentralContextInsights( - MultivaluedMap form, - @Context HttpServletRequest request) - { - Gson gson = new Gson(); - ArrayList selectedUris = gson.fromJson(form.getFirst("selectedURI"), ArrayList.class); - logger.info("LOCALLY have instances selected for search ::: " + selectedUris); - - if(centralApi!=null) { - Hashtable params = new Hashtable(); - params.put("selectedURI", selectedUris); - return WebUtility.getSO(Utility.retrieveResult(centralApi + "/api/engine/central/context/getConnectedConcepts2", params)); - } else { - NameServer ns = new NameServer(); - form.put("localMasterDbName", localDb); - return ns.getConnectedConcepts(form, request); - } - } +// +// @POST +// @Path("context/getConnectedConcepts") +// public StreamingOutput getConnectedConcepts( +// MultivaluedMap form, +// @Context HttpServletRequest request) +// { +// String conceptURI = form.getFirst("conceptURI"); +// logger.info("LOCALLY have concept selected as ::: " + conceptURI); +// +// if(centralApi!=null) { +// Hashtable params = new Hashtable(); +// params.put("conceptURI", conceptURI); +// return WebUtility.getSO(Utility.retrieveResult(centralApi + "/api/engine/central/context/getConnectedConcepts2", params)); +// } else { +// NameServer ns = new NameServer(); +// form.put("localMasterDbName", localDb); +// return ns.getConnectedConcepts(form, request); +// } +// } +// +// @POST +// @Path("central/context/insights") +// @Produces("application/json") +// public StreamingOutput getCentralContextInsights( +// MultivaluedMap form, +// @Context HttpServletRequest request) +// { +// Gson gson = new Gson(); +// ArrayList selectedUris = gson.fromJson(form.getFirst("selectedURI"), ArrayList.class); +// logger.info("LOCALLY have instances selected for search ::: " + selectedUris); +// +// if(centralApi!=null) { +// Hashtable params = new Hashtable(); +// params.put("selectedURI", selectedUris); +// return WebUtility.getSO(Utility.retrieveResult(centralApi + "/api/engine/central/context/getConnectedConcepts2", params)); +// } else { +// NameServer ns = new NameServer(); +// form.put("localMasterDbName", localDb); +// return ns.getConnectedConcepts(form, request); +// } +// } } diff --git a/src/prerna/web/conf/CACFilter.java b/src/prerna/web/conf/CACFilter.java index 7e4b2eb49..25d8d1a21 100644 --- a/src/prerna/web/conf/CACFilter.java +++ b/src/prerna/web/conf/CACFilter.java @@ -159,7 +159,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 token.setName(name); // if we get here, we have a valid cac - updateCacUsersStorage(cacId, email); +// updateCacUsersStorage(cacId, email); break CERT_LOOP; } } // end rdn loop @@ -243,48 +243,48 @@ private void setInitParams(ServletRequest arg0) { } } - @Deprecated - /** - * We only have this because we need to update the way we store these users - */ - private void updateCacUsersStorage(String previousId, String email) { - String cleanEmail = RdbmsQueryBuilder.escapeForSQLStatement(email); - RDBMSNativeEngine securityDb = (RDBMSNativeEngine) Utility.getEngine(Constants.SECURITY_DB); - - // let us not try to run this multiple times... - String requireUpdateQuery = "SELECT * FROM USER WHERE ID='" + previousId +"'"; - IRawSelectWrapper wrapper = WrapperManager.getInstance().getRawWrapper(securityDb, requireUpdateQuery); - try { - // if we have next - // that means we need to update - // from id to email - if(wrapper.hasNext()) { - // need to update all the places the user id is used - String updateQuery = "UPDATE USER SET ID='" + cleanEmail +"', EMAIL='" + cleanEmail + "' WHERE ID='" + previousId + "'"; - try { - securityDb.insertData(updateQuery); - } catch (SQLException e) { - e.printStackTrace(); - } - - // need to update all the places the user id is used - updateQuery = "UPDATE ENGINEPERMISSION SET USERID='" + cleanEmail +"' WHERE USERID='" + previousId + "'"; - try { - securityDb.insertData(updateQuery); - } catch (SQLException e) { - e.printStackTrace(); - } - - // need to update all the places the user id is used - updateQuery = "UPDATE USERINSIGHTPERMISSION SET USERID='" + cleanEmail +"' WHERE USERID='" + previousId + "'"; - try { - securityDb.insertData(updateQuery); - } catch (SQLException e) { - e.printStackTrace(); - } - } - } finally { - wrapper.cleanUp(); - } - } +// @Deprecated +// /** +// * We only have this because we need to update the way we store these users +// */ +// private void updateCacUsersStorage(String previousId, String email) { +// String cleanEmail = RdbmsQueryBuilder.escapeForSQLStatement(email); +// RDBMSNativeEngine securityDb = (RDBMSNativeEngine) Utility.getEngine(Constants.SECURITY_DB); +// +// // let us not try to run this multiple times... +// String requireUpdateQuery = "SELECT * FROM USER WHERE ID='" + previousId +"'"; +// IRawSelectWrapper wrapper = WrapperManager.getInstance().getRawWrapper(securityDb, requireUpdateQuery); +// try { +// // if we have next +// // that means we need to update +// // from id to email +// if(wrapper.hasNext()) { +// // need to update all the places the user id is used +// String updateQuery = "UPDATE USER SET ID='" + cleanEmail +"', EMAIL='" + cleanEmail + "' WHERE ID='" + previousId + "'"; +// try { +// securityDb.insertData(updateQuery); +// } catch (SQLException e) { +// e.printStackTrace(); +// } +// +// // need to update all the places the user id is used +// updateQuery = "UPDATE ENGINEPERMISSION SET USERID='" + cleanEmail +"' WHERE USERID='" + previousId + "'"; +// try { +// securityDb.insertData(updateQuery); +// } catch (SQLException e) { +// e.printStackTrace(); +// } +// +// // need to update all the places the user id is used +// updateQuery = "UPDATE USERINSIGHTPERMISSION SET USERID='" + cleanEmail +"' WHERE USERID='" + previousId + "'"; +// try { +// securityDb.insertData(updateQuery); +// } catch (SQLException e) { +// e.printStackTrace(); +// } +// } +// } finally { +// wrapper.cleanUp(); +// } +// } } From 936de4fa35d6872c9ad7eafb7342918d5b9cceeb Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 3 Sep 2019 21:40:39 +0000 Subject: [PATCH 0473/1906] UPDATE ::: Using fileName (\d) to ensure that the file is unique upon dnd into an insight space that has the file. Otherwise keeping the file name as is and no longer adding "UNIQUE__\timestamp" to the file. git-svn-id: svn://107.170.10.188:8080/Monolith/dev@34541 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 9355d10e059a8dd6c61318cda157524b07f01b72 --- src/prerna/upload/FileUploader.java | 78 +++++++++++++++++++++-------- 1 file changed, 56 insertions(+), 22 deletions(-) diff --git a/src/prerna/upload/FileUploader.java b/src/prerna/upload/FileUploader.java index 4463d29b2..ecec5c575 100644 --- a/src/prerna/upload/FileUploader.java +++ b/src/prerna/upload/FileUploader.java @@ -132,55 +132,89 @@ private List> getBaseUploadData(List fileItems, In continue; } - String fileLocation = null; - String fileSuffix = null; - - Date date = new Date(); - String modifiedDate = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_SSSS").format(date); +// String fileLocation = null; +// String fileSuffix = null; +// Date date = new Date(); +// String modifiedDate = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_SSSS").format(date); // account for upload of an h2 // the connection url requires it to end with .mv.db // otherwise it errors - if(name.endsWith(".mv.db")) { - fileSuffix = FilenameUtils.getBaseName(name).trim().replace(".mv", "").replace(" ", "_") - + "_____UNIQUE" + modifiedDate + ".mv.db"; - } else { - fileSuffix = FilenameUtils.getBaseName(name).trim().replace(" ", "_") - + "_____UNIQUE" + modifiedDate + "." + FilenameUtils.getExtension(name); - } - fileLocation = filePath + DIR_SEPARATOR + fileSuffix; +// if(name.endsWith(".mv.db")) { +// fileSuffix = FilenameUtils.getBaseName(name).trim().replace(".mv", "").replace(" ", "_") +// + "_____UNIQUE" + modifiedDate + ".mv.db"; +// } else { +// fileSuffix = FilenameUtils.getBaseName(name).trim().replace(" ", "_") +// + "_____UNIQUE" + modifiedDate + "." + FilenameUtils.getExtension(name); +// } +// fileLocation = filePath + DIR_SEPARATOR + fileSuffix; + + String fileLocation = getUniquePath(filePath, name); File file = new File(fileLocation); + // instead of adding unique + // we will do what a normal OS system does + writeFile(fi, file); LOGGER.info("Saved Filename: " + name + " to "+ file); + String savedName = FilenameUtils.getName(fileLocation); Map fileMap = new HashMap(); - fileMap.put("fileName", name); - fileMap.put("fileLocation", Insight.INSIGHT_FILE_KEY + DIR_SEPARATOR + fileSuffix); + fileMap.put("fileName", savedName); + fileMap.put("fileLocation", filePath + DIR_SEPARATOR + savedName); retData.add(fileMap); } else if(fi.getFieldName().equals("file")) { // its a file, but not in a form // i.e. this is a person copy/pasting // the values directly LOGGER.info("Writing Input To File"); - Date date = new Date(); - String modifiedDate = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_SSSS").format(date); +// Date date = new Date(); +// String modifiedDate = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_SSSS").format(date); - String fileSuffix = "FileString_" + modifiedDate;; - String fileLocation = filePath + DIR_SEPARATOR + fileSuffix; +// String fileSuffix = "FileString_" + modifiedDate;; +// String fileLocation = filePath + DIR_SEPARATOR + fileSuffix; + + String fileLocation = getUniquePath(filePath, "AutoGeneratedFile.txt"); File file = new File(fileLocation); writeFile(fi, file); LOGGER.info("Saved Pasted Data To "+ file); + String savedName = FilenameUtils.getName(fileLocation); Map fileMap = new HashMap(); - fileMap.put("fileName", "FileString_" + modifiedDate); - fileMap.put("fileLocation", Insight.INSIGHT_FILE_KEY + DIR_SEPARATOR + fileSuffix); + fileMap.put("fileName", savedName); + fileMap.put("fileLocation", filePath + DIR_SEPARATOR + savedName); retData.add(fileMap); } - // delete the field fi.delete(); } return retData; } + + /** + * Makes sure that the file we are creating is in fact unique + * @param directory + * @param fileLocation + * @return + */ + private String getUniquePath(String directory, String fileLocation) { + String fileName = FilenameUtils.getBaseName(fileLocation).trim(); + String fileExtension = FilenameUtils.getExtension(fileLocation).trim(); + + // h2 is weird and will not work if it doesn't end in .mv.db + boolean isH2 = fileLocation.endsWith(".mv.db"); + File f = new File(directory + DIR_SEPARATOR + fileName + "." + fileExtension); + int counter = 2; + while(f.exists()) { + if(isH2) { + f = new File(directory + DIR_SEPARATOR + fileName.replace(".mv", "") + " (" + counter + ")" + ".mv.db"); + } else { + f = new File(directory + DIR_SEPARATOR + fileName + " (" + counter + ")" + "." + fileExtension); + } + counter++; + } + + return f.getAbsolutePath(); + } + } From 37cf0a0b2c58ae848eb1643a87eafb8588135c8f Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 4 Sep 2019 19:15:52 +0000 Subject: [PATCH 0474/1906] UPDATE ::: Sharing R variables in dashboard UPDATE ::: Defining ROOT variable to use for source files UPDATE ::: Removing ROOT variable value from output return git-svn-id: svn://107.170.10.188:8080/Monolith/dev@34560 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: e16ec83c27cf030e0137b95cb8dd2a166cd6495a --- src/prerna/upload/FileUploader.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/prerna/upload/FileUploader.java b/src/prerna/upload/FileUploader.java index ecec5c575..487a5ea8e 100644 --- a/src/prerna/upload/FileUploader.java +++ b/src/prerna/upload/FileUploader.java @@ -1,8 +1,6 @@ package prerna.upload; import java.io.File; -import java.text.SimpleDateFormat; -import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List; From 4a4d543a0a64b0084b188fc92dfd6da701bdb52c Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 5 Sep 2019 12:21:33 +0000 Subject: [PATCH 0475/1906] UPDATE ::: Adding back "$IF" instead of returning full path git-svn-id: svn://107.170.10.188:8080/Monolith/dev@34580 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 6a87f010173a8a86e16058cb894a3b9f1e6e8cd9 --- src/prerna/upload/FileUploader.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/prerna/upload/FileUploader.java b/src/prerna/upload/FileUploader.java index 487a5ea8e..582d2845d 100644 --- a/src/prerna/upload/FileUploader.java +++ b/src/prerna/upload/FileUploader.java @@ -158,7 +158,7 @@ private List> getBaseUploadData(List fileItems, In String savedName = FilenameUtils.getName(fileLocation); Map fileMap = new HashMap(); fileMap.put("fileName", savedName); - fileMap.put("fileLocation", filePath + DIR_SEPARATOR + savedName); + fileMap.put("fileLocation", "$IF" + DIR_SEPARATOR + savedName); retData.add(fileMap); } else if(fi.getFieldName().equals("file")) { // its a file, but not in a form @@ -179,7 +179,7 @@ private List> getBaseUploadData(List fileItems, In String savedName = FilenameUtils.getName(fileLocation); Map fileMap = new HashMap(); fileMap.put("fileName", savedName); - fileMap.put("fileLocation", filePath + DIR_SEPARATOR + savedName); + fileMap.put("fileLocation", "$IF" + DIR_SEPARATOR + savedName); retData.add(fileMap); } // delete the field From 80265fac0270e8a04d19f8c97174f194c7c19d81 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 6 Sep 2019 17:51:47 +0000 Subject: [PATCH 0476/1906] UPDATE ::: Pushing file uploader to return INSIGHT_FOLDER OR APP_FOLDER/INSIGHT_FOLDER (depending if loading into saved space) for previous commit in semoss git-svn-id: svn://107.170.10.188:8080/Monolith/dev@34610 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: a9d07483f2b6557ae91531fd577dd41697cdc0c1 --- src/prerna/upload/FileUploader.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/prerna/upload/FileUploader.java b/src/prerna/upload/FileUploader.java index 582d2845d..c8903df26 100644 --- a/src/prerna/upload/FileUploader.java +++ b/src/prerna/upload/FileUploader.java @@ -158,7 +158,7 @@ private List> getBaseUploadData(List fileItems, In String savedName = FilenameUtils.getName(fileLocation); Map fileMap = new HashMap(); fileMap.put("fileName", savedName); - fileMap.put("fileLocation", "$IF" + DIR_SEPARATOR + savedName); + fileMap.put("fileLocation", Insight.getInsightRelativeFolderKey(in) + DIR_SEPARATOR + savedName); retData.add(fileMap); } else if(fi.getFieldName().equals("file")) { // its a file, but not in a form @@ -179,7 +179,7 @@ private List> getBaseUploadData(List fileItems, In String savedName = FilenameUtils.getName(fileLocation); Map fileMap = new HashMap(); fileMap.put("fileName", savedName); - fileMap.put("fileLocation", "$IF" + DIR_SEPARATOR + savedName); + fileMap.put("fileLocation", Insight.getInsightRelativeFolderKey(in) + DIR_SEPARATOR + savedName); retData.add(fileMap); } // delete the field From 089b43f82ef5d1a16e7e8954e67ad5a233ccf0e0 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 9 Sep 2019 16:29:48 +0000 Subject: [PATCH 0477/1906] UPDATE ::: Adding execution of an insight via a rest endpoint and getting back grid data. This assumes you are using a single frame that is the "default frame". Rest endpoint format is: http://localhost:8080/Monolith_Dev/api/exec/a-{appId}/i-{rdbmsId}/getTableData git-svn-id: svn://107.170.10.188:8080/Monolith/dev@34631 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: a9621ad7b04c2ef36dfa4b4fb880d251746799e7 --- .../semoss/web/app/MonolithApplication.java | 8 +- .../local/ExecuteInsightResource.java | 100 ++++++++++++++++++ .../semoss/web/services/local/NameServer.java | 1 - .../{ShareInsight.java => RunInsight.java} | 30 +++++- .../services/local/ShareInsightResource.java | 4 +- 5 files changed, 133 insertions(+), 10 deletions(-) create mode 100644 src/prerna/semoss/web/services/local/ExecuteInsightResource.java rename src/prerna/semoss/web/services/local/{ShareInsight.java => RunInsight.java} (60%) diff --git a/src/prerna/semoss/web/app/MonolithApplication.java b/src/prerna/semoss/web/app/MonolithApplication.java index 0850cf456..1ff5fc95c 100644 --- a/src/prerna/semoss/web/app/MonolithApplication.java +++ b/src/prerna/semoss/web/app/MonolithApplication.java @@ -37,6 +37,7 @@ import prerna.semoss.web.services.config.ServerConfigurationResource; import prerna.semoss.web.services.local.AppResource; import prerna.semoss.web.services.local.AuthorizationResource; +import prerna.semoss.web.services.local.ExecuteInsightResource; import prerna.semoss.web.services.local.NameServer; import prerna.semoss.web.services.local.ShareInsightResource; import prerna.semoss.web.services.local.ThemeResource; @@ -61,12 +62,15 @@ public MonolithApplication() { singletons.add(new AdminAppAuthorizationResource()); singletons.add(new InsightAuthorizationResource()); singletons.add(new AdminInsightAuthorizationResource()); + // insight execution + singletons.add(new ExecuteInsightResource()); + singletons.add(new ShareInsightResource()); // other singletons.add(new ThemeResource()); - singletons.add(new ShareInsightResource()); - singletons.add(new FormResource()); singletons.add(new ServerConfigurationResource()); singletons.add(new RawSelectWrapperService()); + // legacy forms - still used in production - RDF specific + singletons.add(new FormResource()); } @Override diff --git a/src/prerna/semoss/web/services/local/ExecuteInsightResource.java b/src/prerna/semoss/web/services/local/ExecuteInsightResource.java new file mode 100644 index 000000000..7299e979b --- /dev/null +++ b/src/prerna/semoss/web/services/local/ExecuteInsightResource.java @@ -0,0 +1,100 @@ +package prerna.semoss.web.services.local; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.core.Context; + +import prerna.auth.User; +import prerna.auth.utils.AbstractSecurityUtils; +import prerna.auth.utils.SecurityInsightUtils; +import prerna.auth.utils.SecurityQueryUtils; +import prerna.cluster.util.ClusterUtil; +import prerna.engine.api.IEngine; +import prerna.nameserver.utility.MasterDatabaseUtility; +import prerna.om.Insight; +import prerna.om.InsightStore; +import prerna.util.Constants; +import prerna.util.Utility; +import prerna.web.services.util.WebUtility; + +@Path("exec") +public class ExecuteInsightResource { + + @Path("/test") + public Object test() { + Map ret = new HashMap(); + return WebUtility.getSO(ret); + } + + @Path("/a-{appId}/i-{insightId}") + public Object generateInsight(@Context HttpServletRequest request, + @PathParam("appId") String appId, + @PathParam("insightId") String rdbmsId) { + boolean securityEnabled = AbstractSecurityUtils.securityEnabled(); + User user = null; + + HttpSession session = null; + if(securityEnabled){ + session = request.getSession(false); + if(session == null) { + Map errorHash = new HashMap(); + errorHash.put("errorMessage", "Invalid session to retrieve insight data"); + return WebUtility.getResponse(errorHash, 400); + } + + user = ((User) session.getAttribute(Constants.SESSION_USER)); + if(user == null) { + Map errorMap = new HashMap(); + errorMap.put("error", "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + } else { + session = request.getSession(true); + user = ((User) session.getAttribute(Constants.SESSION_USER)); + } + + if(securityEnabled) { + appId = SecurityQueryUtils.testUserEngineIdForAlias(user, appId); + if(!SecurityInsightUtils.userCanViewInsight(user, appId, rdbmsId)) { + Map errorMap = new HashMap(); + errorMap.put("error", "User does not have access to this insight"); + return WebUtility.getResponse(errorMap, 401); + } + } else { + appId = MasterDatabaseUtility.testEngineIdIfAlias(appId); + } + + IEngine engine = Utility.getEngine(appId); + if(engine == null) { + throw new IllegalArgumentException("Cannot find app = " + appId); + } + Insight newInsight = null; + try { + List in = engine.getInsight(rdbmsId + ""); + newInsight = in.get(0); + } catch (ArrayIndexOutOfBoundsException e) { + ClusterUtil.reactorUpdateApp(appId); + try { + List in = engine.getInsight(rdbmsId + ""); + newInsight = in.get(0); + } catch (ArrayIndexOutOfBoundsException e2) { + Map errorMap = new HashMap(); + errorMap.put("error", "Insight does not exist"); + return WebUtility.getResponse(errorMap, 401); + } + } + + InsightStore.getInstance().put(newInsight); + newInsight.reRunPixelInsight(); + RunInsight runner = new RunInsight(newInsight); + runner.dropInsight(true); + return runner; + } + +} diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index e40756c0d..9bab9a624 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -506,7 +506,6 @@ public Response runPixelSync(@Context HttpServletRequest request){ if(user == null) { Map errorMap = new HashMap(); errorMap.put("error", "User session is invalid"); - System.out.println("User session is invalid"); return WebUtility.getResponse(errorMap, 401); } } else { diff --git a/src/prerna/semoss/web/services/local/ShareInsight.java b/src/prerna/semoss/web/services/local/RunInsight.java similarity index 60% rename from src/prerna/semoss/web/services/local/ShareInsight.java rename to src/prerna/semoss/web/services/local/RunInsight.java index c90190ca1..eb19ce082 100644 --- a/src/prerna/semoss/web/services/local/ShareInsight.java +++ b/src/prerna/semoss/web/services/local/RunInsight.java @@ -13,20 +13,41 @@ import prerna.om.Insight; import prerna.web.requests.OverrideParametersServletRequest; -public class ShareInsight { +public class RunInsight { - private Insight in; + private Insight in = null; + private boolean drop = false; - public ShareInsight(Insight in) { + public RunInsight(Insight in) { this.in = in; } + public void dropInsight(boolean drop) { + this.drop = drop; + } + @GET @Path("/getTableData") @Produces("application/json") public Response getInsightData(@Context HttpServletRequest request) { String pixel = "QueryAll()|Collect(-1);FrameHeaders();"; - + return runPixel(request, pixel); + } + + /** + * Utility method to execute the pixel on the insight + * @param request + * @param pixel + * @return + */ + private Response runPixel(@Context HttpServletRequest request, String pixel) { + if(this.drop) { + if(pixel.endsWith(";")) { + pixel = pixel + "DropInsight();"; + } else { + pixel = pixel + ";DropInsight();"; + } + } NameServer ns = new NameServer(); OverrideParametersServletRequest requestWrapper = new OverrideParametersServletRequest(request); Map paramMap = new HashMap(); @@ -35,5 +56,4 @@ public Response getInsightData(@Context HttpServletRequest request) { requestWrapper.setParameters(paramMap); return ns.runPixelSync(requestWrapper); } - } diff --git a/src/prerna/semoss/web/services/local/ShareInsightResource.java b/src/prerna/semoss/web/services/local/ShareInsightResource.java index 8531e9a4a..f625237d5 100644 --- a/src/prerna/semoss/web/services/local/ShareInsightResource.java +++ b/src/prerna/semoss/web/services/local/ShareInsightResource.java @@ -41,8 +41,8 @@ public Object validInsight(@Context HttpServletRequest request, @PathParam("insi return WebUtility.getResponse(errorMap, 400); } - ShareInsight share = new ShareInsight(in); - return share; + RunInsight runner = new RunInsight(in); + return runner; } } From e05798b7d8e2a59d745d82a094e47bb8d6169b98 Mon Sep 17 00:00:00 2001 From: rramirezjimenez Date: Mon, 9 Sep 2019 18:57:52 +0000 Subject: [PATCH 0478/1906] UPDATE ::: FileUpload endpoint allow upload to relative path in either insight folder or db folder git-svn-id: svn://107.170.10.188:8080/Monolith/dev@34638 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 7d57b82e98d16c879823aa450e70e6b82bdc3fea --- src/prerna/upload/FileUploader.java | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/src/prerna/upload/FileUploader.java b/src/prerna/upload/FileUploader.java index c8903df26..fcde7aa75 100644 --- a/src/prerna/upload/FileUploader.java +++ b/src/prerna/upload/FileUploader.java @@ -40,7 +40,8 @@ public class FileUploader extends Uploader { @POST @Path("baseUpload") - public Response uploadFile(@Context HttpServletRequest request, @QueryParam("insightId") String insightId) { + public Response uploadFile(@Context HttpServletRequest request, @QueryParam("insightId") String insightId, + @QueryParam("filePath") String relativePath, @QueryParam("app") boolean appDir) { Insight in = InsightStore.getInstance().get(insightId); if(in == null) { HashMap errorMap = new HashMap(); @@ -85,7 +86,7 @@ public Response uploadFile(@Context HttpServletRequest request, @QueryParam("ins try { List fileItems = processRequest(request, insightId); // collect all of the data input on the form - List> inputData = getBaseUploadData(fileItems, in); + List> inputData = getBaseUploadData(fileItems, in, relativePath, appDir); // clear the thread store return WebUtility.getResponse(inputData, 200); } catch(Exception e) { @@ -101,12 +102,24 @@ public Response uploadFile(@Context HttpServletRequest request, @QueryParam("ins /** * Method to parse just files and move to the server * @param fileItems a list of maps containing the file name and file location + * @param appDir * @return */ - private List> getBaseUploadData(List fileItems, Insight in) { - String filePath = in.getInsightFolder(); + private List> getBaseUploadData(List fileItems, Insight in, String relativePath, boolean appDir) { + // get base asset folder + String assetFolder = null; + if (appDir) { + assetFolder = in.getAppFolder(); + } else { + assetFolder = in.getInsightFolder(); + } + String filePath = assetFolder; + // add relative path + if (relativePath != null) { + filePath = assetFolder + DIR_SEPARATOR + relativePath; + } File fileDir = new File(filePath); - if(!fileDir.exists()) { + if (!fileDir.exists()) { fileDir.mkdirs(); } @@ -158,7 +171,7 @@ private List> getBaseUploadData(List fileItems, In String savedName = FilenameUtils.getName(fileLocation); Map fileMap = new HashMap(); fileMap.put("fileName", savedName); - fileMap.put("fileLocation", Insight.getInsightRelativeFolderKey(in) + DIR_SEPARATOR + savedName); + fileMap.put("fileLocation", filePath + DIR_SEPARATOR + savedName); retData.add(fileMap); } else if(fi.getFieldName().equals("file")) { // its a file, but not in a form @@ -179,7 +192,7 @@ private List> getBaseUploadData(List fileItems, In String savedName = FilenameUtils.getName(fileLocation); Map fileMap = new HashMap(); fileMap.put("fileName", savedName); - fileMap.put("fileLocation", Insight.getInsightRelativeFolderKey(in) + DIR_SEPARATOR + savedName); + fileMap.put("fileLocation", filePath + DIR_SEPARATOR + savedName); retData.add(fileMap); } // delete the field From 1edec5558ab1acdad7ba419892bf6c4fdf3fe8da Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 10 Sep 2019 15:37:07 +0000 Subject: [PATCH 0479/1906] UPDATE ::: Adding python thread to session and grabbing when appropriate UPDATE ::: Adding ROOT variable in python to be used UPDATE ::: Removing unnecessary direct execution and instead using the base execution git-svn-id: svn://107.170.10.188:8080/Monolith/dev@34658 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 25534d3f034405b4c447806f1c6331afaaa03e1c --- .../semoss/web/services/local/NameServer.java | 36 +++++++++---------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index 9bab9a624..296d090a1 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -128,8 +128,6 @@ public class NameServer { private static final String CANCEL_INVALIDATION = "cancelInvalidation"; private Object lock = new Object(); - private PyExecutorThread jepThread; - @Context protected ServletContext context; @@ -496,11 +494,6 @@ public Response runPixelSync(@Context HttpServletRequest request){ if(session != null){ sessionId = session.getId(); user = ((User) session.getAttribute(Constants.SESSION_USER)); - - // need to see if the user is enabling python here.. I will assume it is here - if(session.getAttribute(Constants.PYTHON) != null) { - jepThread = (PyExecutorThread)session.getAttribute(Constants.PYTHON); - } } if(user == null) { @@ -512,10 +505,14 @@ public Response runPixelSync(@Context HttpServletRequest request){ session = request.getSession(true); user = ((User) session.getAttribute(Constants.SESSION_USER)); sessionId = session.getId(); - if(PyUtils.pyEnabled() && this.jepThread == null) { - this.jepThread = PyUtils.getInstance().getJep(); - } - jepThread = this.jepThread; + } + // need to see if the user is enabling python here.. I will assume it is here + if(session.getAttribute(Constants.PYTHON) != null) { + jepThread = (PyExecutorThread)session.getAttribute(Constants.PYTHON); + } + if(PyUtils.pyEnabled() && jepThread == null) { + jepThread = PyUtils.getInstance().getJep(); + session.setAttribute(Constants.PYTHON, jepThread); } String jobId = ""; @@ -602,11 +599,6 @@ public Response getPixelPipelinePlan(@Context HttpServletRequest request){ if(session != null){ sessionId = session.getId(); user = ((User) session.getAttribute(Constants.SESSION_USER)); - - // need to see if the user is enabling python here.. I will assume it is here - if(session.getAttribute(Constants.PYTHON) != null) { - jepThread = (PyExecutorThread)session.getAttribute(Constants.PYTHON); - } } if(user == null) { @@ -619,10 +611,14 @@ public Response getPixelPipelinePlan(@Context HttpServletRequest request){ session = request.getSession(true); user = ((User) session.getAttribute(Constants.SESSION_USER)); sessionId = session.getId(); - if(PyUtils.pyEnabled() && this.jepThread == null) { - this.jepThread = PyUtils.getInstance().getJep(); - } - jepThread = this.jepThread; + } + // need to see if the user is enabling python here.. I will assume it is here + if(session.getAttribute(Constants.PYTHON) != null) { + jepThread = (PyExecutorThread)session.getAttribute(Constants.PYTHON); + } + if(PyUtils.pyEnabled() && jepThread == null) { + jepThread = PyUtils.getInstance().getJep(); + session.setAttribute(Constants.PYTHON, jepThread); } String insightId = request.getParameter("insightId"); From 0aa9c7d02556d06d9dfbe42af0dc2bde9084bb5e Mon Sep 17 00:00:00 2001 From: rramirezjimenez Date: Wed, 11 Sep 2019 15:45:08 +0000 Subject: [PATCH 0480/1906] UPDATE ::: Allow user to upload a file to app or insight space git-svn-id: svn://107.170.10.188:8080/Monolith/dev@34688 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: b83c81d68e36db2a5542cbcec5e9be69a9c0bdc8 --- src/prerna/upload/FileUploader.java | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/prerna/upload/FileUploader.java b/src/prerna/upload/FileUploader.java index fcde7aa75..0c3bb5993 100644 --- a/src/prerna/upload/FileUploader.java +++ b/src/prerna/upload/FileUploader.java @@ -21,8 +21,10 @@ import prerna.auth.User; import prerna.auth.utils.AbstractSecurityUtils; +import prerna.auth.utils.SecurityAppUtils; import prerna.auth.utils.SecurityInsightUtils; import prerna.auth.utils.SecurityQueryUtils; +import prerna.nameserver.utility.MasterDatabaseUtility; import prerna.om.Insight; import prerna.om.InsightStore; import prerna.om.ThreadStore; @@ -41,7 +43,7 @@ public class FileUploader extends Uploader { @POST @Path("baseUpload") public Response uploadFile(@Context HttpServletRequest request, @QueryParam("insightId") String insightId, - @QueryParam("filePath") String relativePath, @QueryParam("app") boolean appDir) { + @QueryParam("filePath") String relativePath, @QueryParam("appId") String appId) { Insight in = InsightStore.getInstance().get(insightId); if(in == null) { HashMap errorMap = new HashMap(); @@ -80,13 +82,20 @@ public Response uploadFile(@Context HttpServletRequest request, @QueryParam("ins errorMap.put("errorMessage", "User does not have permission to publish data. Please reach out to the admin to get proper access"); return WebUtility.getResponse(errorMap, 400); } + if (appId != null) { + if (!SecurityAppUtils.userCanEditEngine(in.getUser(), appId)) { + HashMap errorMap = new HashMap(); + errorMap.put("errorMessage", "User does not have permission for this app."); + return WebUtility.getResponse(errorMap, 400); + } + } } ThreadStore.setSessionId(request.getSession().getId()); try { List fileItems = processRequest(request, insightId); // collect all of the data input on the form - List> inputData = getBaseUploadData(fileItems, in, relativePath, appDir); + List> inputData = getBaseUploadData(fileItems, in, relativePath, appId); // clear the thread store return WebUtility.getResponse(inputData, 200); } catch(Exception e) { @@ -105,11 +114,12 @@ public Response uploadFile(@Context HttpServletRequest request, @QueryParam("ins * @param appDir * @return */ - private List> getBaseUploadData(List fileItems, Insight in, String relativePath, boolean appDir) { + private List> getBaseUploadData(List fileItems, Insight in, String relativePath, String appId) { // get base asset folder String assetFolder = null; - if (appDir) { - assetFolder = in.getAppFolder(); + if (appId != null) { + String appName = MasterDatabaseUtility.getEngineAliasForId(appId); + assetFolder = in.getAppFolder(appName, appId); } else { assetFolder = in.getInsightFolder(); } From 4a8b966c41bcf299dd1ae021e5fd85b7d8421cb7 Mon Sep 17 00:00:00 2001 From: rramirezjimenez Date: Wed, 11 Sep 2019 16:45:33 +0000 Subject: [PATCH 0481/1906] UPDATE ::: Reverting insight getAppFolder() git-svn-id: svn://107.170.10.188:8080/Monolith/dev@34695 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 36149439c9d6d23cc4a3723682eed2f33c0290c2 --- src/prerna/upload/FileUploader.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/prerna/upload/FileUploader.java b/src/prerna/upload/FileUploader.java index 0c3bb5993..7ec368d6a 100644 --- a/src/prerna/upload/FileUploader.java +++ b/src/prerna/upload/FileUploader.java @@ -28,6 +28,7 @@ import prerna.om.Insight; import prerna.om.InsightStore; import prerna.om.ThreadStore; +import prerna.util.AssetUtility; import prerna.web.services.util.WebUtility; public class FileUploader extends Uploader { @@ -119,7 +120,7 @@ private List> getBaseUploadData(List fileItems, In String assetFolder = null; if (appId != null) { String appName = MasterDatabaseUtility.getEngineAliasForId(appId); - assetFolder = in.getAppFolder(appName, appId); + assetFolder = AssetUtility.getAppAssetFolder(appName, appId); } else { assetFolder = in.getInsightFolder(); } From 5bc817b17a2ac10fe1f89482369f01d1d8feb163 Mon Sep 17 00:00:00 2001 From: rramirezjimenez Date: Wed, 11 Sep 2019 17:02:11 +0000 Subject: [PATCH 0482/1906] BUGFIX ::: FileUploader param key fix git-svn-id: svn://107.170.10.188:8080/Monolith/dev@34697 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 42431b68ae56082d7df006fb0ce114448c4df15c --- src/prerna/upload/FileUploader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prerna/upload/FileUploader.java b/src/prerna/upload/FileUploader.java index 7ec368d6a..227a9f226 100644 --- a/src/prerna/upload/FileUploader.java +++ b/src/prerna/upload/FileUploader.java @@ -44,7 +44,7 @@ public class FileUploader extends Uploader { @POST @Path("baseUpload") public Response uploadFile(@Context HttpServletRequest request, @QueryParam("insightId") String insightId, - @QueryParam("filePath") String relativePath, @QueryParam("appId") String appId) { + @QueryParam("path") String relativePath, @QueryParam("appId") String appId) { Insight in = InsightStore.getInstance().get(insightId); if(in == null) { HashMap errorMap = new HashMap(); From 0492f537b6260f15958d2b52b59d8b020a782bae Mon Sep 17 00:00:00 2001 From: rramirezjimenez Date: Wed, 11 Sep 2019 21:02:13 +0000 Subject: [PATCH 0483/1906] BUGFIX ::: Uploading to user asset folder git-svn-id: svn://107.170.10.188:8080/Monolith/dev@34701 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 094f6851ff5a0f8f7c63875b5a24c14a88ea36ea --- src/prerna/upload/FileUploader.java | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/prerna/upload/FileUploader.java b/src/prerna/upload/FileUploader.java index 227a9f226..f0849648e 100644 --- a/src/prerna/upload/FileUploader.java +++ b/src/prerna/upload/FileUploader.java @@ -83,13 +83,13 @@ public Response uploadFile(@Context HttpServletRequest request, @QueryParam("ins errorMap.put("errorMessage", "User does not have permission to publish data. Please reach out to the admin to get proper access"); return WebUtility.getResponse(errorMap, 400); } - if (appId != null) { - if (!SecurityAppUtils.userCanEditEngine(in.getUser(), appId)) { - HashMap errorMap = new HashMap(); - errorMap.put("errorMessage", "User does not have permission for this app."); - return WebUtility.getResponse(errorMap, 400); - } - } +// if (appId != null) { +// if (!SecurityAppUtils.userCanEditEngine(in.getUser(), appId)) { +// HashMap errorMap = new HashMap(); +// errorMap.put("errorMessage", "User does not have permission for this app."); +// return WebUtility.getResponse(errorMap, 400); +// } +// } } ThreadStore.setSessionId(request.getSession().getId()); @@ -119,8 +119,7 @@ private List> getBaseUploadData(List fileItems, In // get base asset folder String assetFolder = null; if (appId != null) { - String appName = MasterDatabaseUtility.getEngineAliasForId(appId); - assetFolder = AssetUtility.getAppAssetFolder(appName, appId); + assetFolder = AssetUtility.getAssetBasePath(in, appId); } else { assetFolder = in.getInsightFolder(); } From 3e43ae9fbbb5c6e88efc5fffd2fdfd1dc79ebfef Mon Sep 17 00:00:00 2001 From: rramirezjimenez Date: Wed, 11 Sep 2019 21:04:18 +0000 Subject: [PATCH 0484/1906] UPDATE ::: FileUpload asset folder security git-svn-id: svn://107.170.10.188:8080/Monolith/dev@34702 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: b16649104ae54e3d5f28500377efe7417bd24771 --- src/prerna/upload/FileUploader.java | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/prerna/upload/FileUploader.java b/src/prerna/upload/FileUploader.java index f0849648e..992075b4f 100644 --- a/src/prerna/upload/FileUploader.java +++ b/src/prerna/upload/FileUploader.java @@ -24,7 +24,6 @@ import prerna.auth.utils.SecurityAppUtils; import prerna.auth.utils.SecurityInsightUtils; import prerna.auth.utils.SecurityQueryUtils; -import prerna.nameserver.utility.MasterDatabaseUtility; import prerna.om.Insight; import prerna.om.InsightStore; import prerna.om.ThreadStore; @@ -83,13 +82,13 @@ public Response uploadFile(@Context HttpServletRequest request, @QueryParam("ins errorMap.put("errorMessage", "User does not have permission to publish data. Please reach out to the admin to get proper access"); return WebUtility.getResponse(errorMap, 400); } -// if (appId != null) { -// if (!SecurityAppUtils.userCanEditEngine(in.getUser(), appId)) { -// HashMap errorMap = new HashMap(); -// errorMap.put("errorMessage", "User does not have permission for this app."); -// return WebUtility.getResponse(errorMap, 400); -// } -// } + if (appId != null && !appId.equalsIgnoreCase("user")) { + if (!SecurityAppUtils.userCanEditEngine(in.getUser(), appId)) { + HashMap errorMap = new HashMap(); + errorMap.put("errorMessage", "User does not have permission for this app."); + return WebUtility.getResponse(errorMap, 400); + } + } } ThreadStore.setSessionId(request.getSession().getId()); From 8692b9dbfe0d1bc9827a04fab25748d60c26e092 Mon Sep 17 00:00:00 2001 From: rramirezjimenez Date: Thu, 12 Sep 2019 19:57:25 +0000 Subject: [PATCH 0485/1906] BUGFIX ::: Masking the path we send to the front end when we upload a file git-svn-id: svn://107.170.10.188:8080/Monolith/dev@34735 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 17b46c571439918155461bc157075085bbe09e1b --- src/prerna/upload/FileUploader.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/prerna/upload/FileUploader.java b/src/prerna/upload/FileUploader.java index 992075b4f..2503a2c8b 100644 --- a/src/prerna/upload/FileUploader.java +++ b/src/prerna/upload/FileUploader.java @@ -117,8 +117,10 @@ public Response uploadFile(@Context HttpServletRequest request, @QueryParam("ins private List> getBaseUploadData(List fileItems, Insight in, String relativePath, String appId) { // get base asset folder String assetFolder = null; + String fePath = in.getAppInsightFolderKey(); if (appId != null) { assetFolder = AssetUtility.getAssetBasePath(in, appId); + fePath = in.getAppRelativeFolderKey(); } else { assetFolder = in.getInsightFolder(); } @@ -126,6 +128,7 @@ private List> getBaseUploadData(List fileItems, In // add relative path if (relativePath != null) { filePath = assetFolder + DIR_SEPARATOR + relativePath; + fePath += relativePath; } File fileDir = new File(filePath); if (!fileDir.exists()) { @@ -180,7 +183,7 @@ private List> getBaseUploadData(List fileItems, In String savedName = FilenameUtils.getName(fileLocation); Map fileMap = new HashMap(); fileMap.put("fileName", savedName); - fileMap.put("fileLocation", filePath + DIR_SEPARATOR + savedName); + fileMap.put("fileLocation", fePath + DIR_SEPARATOR + savedName); retData.add(fileMap); } else if(fi.getFieldName().equals("file")) { // its a file, but not in a form @@ -201,7 +204,7 @@ private List> getBaseUploadData(List fileItems, In String savedName = FilenameUtils.getName(fileLocation); Map fileMap = new HashMap(); fileMap.put("fileName", savedName); - fileMap.put("fileLocation", filePath + DIR_SEPARATOR + savedName); + fileMap.put("fileLocation", fePath + DIR_SEPARATOR + savedName); retData.add(fileMap); } // delete the field From ac656e62e3badf72d24a1f1bc8cdbf1bbe15d65d Mon Sep 17 00:00:00 2001 From: rramirezjimenez Date: Thu, 12 Sep 2019 19:58:57 +0000 Subject: [PATCH 0486/1906] BUGFIX ::: Appending relative path to app or insight upload git-svn-id: svn://107.170.10.188:8080/Monolith/dev@34736 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 2954dcdcaedc131592575ad9d3c1009ac07d6dd9 --- src/prerna/upload/FileUploader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prerna/upload/FileUploader.java b/src/prerna/upload/FileUploader.java index 2503a2c8b..b3c994dd5 100644 --- a/src/prerna/upload/FileUploader.java +++ b/src/prerna/upload/FileUploader.java @@ -128,7 +128,7 @@ private List> getBaseUploadData(List fileItems, In // add relative path if (relativePath != null) { filePath = assetFolder + DIR_SEPARATOR + relativePath; - fePath += relativePath; + fePath += DIR_SEPARATOR + relativePath; } File fileDir = new File(filePath); if (!fileDir.exists()) { From 2a663bb7ab07b97d6e0f80ea6b8d1ea5926885a0 Mon Sep 17 00:00:00 2001 From: rramirezjimenez Date: Thu, 12 Sep 2019 20:10:51 +0000 Subject: [PATCH 0487/1906] BUGFIX ::: file upload get relative path for unsaved insight git-svn-id: svn://107.170.10.188:8080/Monolith/dev@34737 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 013eee87159d0388bb00669226eb4e6e980c0216 --- src/prerna/upload/FileUploader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prerna/upload/FileUploader.java b/src/prerna/upload/FileUploader.java index b3c994dd5..795436847 100644 --- a/src/prerna/upload/FileUploader.java +++ b/src/prerna/upload/FileUploader.java @@ -117,7 +117,7 @@ public Response uploadFile(@Context HttpServletRequest request, @QueryParam("ins private List> getBaseUploadData(List fileItems, Insight in, String relativePath, String appId) { // get base asset folder String assetFolder = null; - String fePath = in.getAppInsightFolderKey(); + String fePath = Insight.getInsightRelativeFolderKey(in); if (appId != null) { assetFolder = AssetUtility.getAssetBasePath(in, appId); fePath = in.getAppRelativeFolderKey(); From 2bbf1dce0edc478c64f2253e0cf8fc0dc793c5c4 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 12 Sep 2019 23:02:30 +0000 Subject: [PATCH 0488/1906] UPDATE ::: Modifying so downloadFile endpoint returns the file name. UPDATE ::: Modifying To*Reactors to generate a unique id as semoss export + use the insight folder UPDATE ::: Ensuring only 1 instance of Jep is started per session git-svn-id: svn://107.170.10.188:8080/Monolith/dev@34743 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 8267782cde5e8ccab4ff48f1dfde0a09f7852287 --- .../semoss/web/services/local/NameServer.java | 36 ++++++++++++++----- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index 296d090a1..5bdfb0473 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -33,7 +33,6 @@ import java.io.OutputStream; import java.io.PrintStream; import java.net.URLEncoder; -import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.Enumeration; @@ -426,10 +425,7 @@ public Response downloadFile(@QueryParam("insightId") String insightId, @QueryPa return WebUtility.getResponse(errorMap, 400); } - Date date = new Date(); - String modifiedDate = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_SSSS").format(date); - String exportName = "SEMOSS_Export_" + modifiedDate + "." + FilenameUtils.getExtension(filePath); - + String exportName = FilenameUtils.getName(filePath); return Response.status(200).entity(exportFile).header("Content-Disposition", "attachment; filename=" + exportName).build(); } @@ -510,9 +506,22 @@ public Response runPixelSync(@Context HttpServletRequest request){ if(session.getAttribute(Constants.PYTHON) != null) { jepThread = (PyExecutorThread)session.getAttribute(Constants.PYTHON); } + // need to see if the user is enabling python here.. I will assume it is here + if(session.getAttribute(Constants.PYTHON) != null) { + jepThread = (PyExecutorThread)session.getAttribute(Constants.PYTHON); + } if(PyUtils.pyEnabled() && jepThread == null) { - jepThread = PyUtils.getInstance().getJep(); - session.setAttribute(Constants.PYTHON, jepThread); + // i do not want to make more than 1 py thread per session + // and this method is called many times + synchronized(sessionId) { + if(session.getAttribute(Constants.PYTHON) != null) { + jepThread = (PyExecutorThread)session.getAttribute(Constants.PYTHON); + } + if(jepThread == null) { + jepThread = PyUtils.getInstance().getJep(); + session.setAttribute(Constants.PYTHON, jepThread); + } + } } String jobId = ""; @@ -617,8 +626,17 @@ public Response getPixelPipelinePlan(@Context HttpServletRequest request){ jepThread = (PyExecutorThread)session.getAttribute(Constants.PYTHON); } if(PyUtils.pyEnabled() && jepThread == null) { - jepThread = PyUtils.getInstance().getJep(); - session.setAttribute(Constants.PYTHON, jepThread); + // i do not want to make more than 1 py thread per session + // and this method is called many times + synchronized(sessionId) { + if(session.getAttribute(Constants.PYTHON) != null) { + jepThread = (PyExecutorThread)session.getAttribute(Constants.PYTHON); + } + if(jepThread == null) { + jepThread = PyUtils.getInstance().getJep(); + session.setAttribute(Constants.PYTHON, jepThread); + } + } } String insightId = request.getParameter("insightId"); From 67662e75813e25e1b90cf238a68309434900d952 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 17 Sep 2019 18:06:48 +0000 Subject: [PATCH 0489/1906] UPDATE ::: Adding tag filters in GetInsightsReactor UPDATE ::: Adding ability to get available tags filtered to set of engines git-svn-id: svn://107.170.10.188:8080/Monolith/dev@34835 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 38cdb29f7511198123f050fd2dd0f08093ea517c --- src/prerna/semoss/web/services/local/NameServer.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index 5bdfb0473..f820fb778 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -1238,9 +1238,9 @@ public StreamingOutput getSearchInsightsResults(MultivaluedMap f // filter insights based on what the user has access to HttpSession session = request.getSession(false); User user = ((User) session.getAttribute(Constants.SESSION_USER)); - queryResults = SecurityInsightUtils.searchUserInsights(user, null, searchString, limit, offset); + queryResults = SecurityInsightUtils.searchUserInsights(user, null, searchString, null, limit, offset); } else { - queryResults = SecurityInsightUtils.searchInsights(null, searchString, limit, offset); + queryResults = SecurityInsightUtils.searchInsights(null, searchString, null, limit, offset); } return WebUtility.getSO(queryResults); From bb3bfedbbfc9784f2e9e713d60252e9c702d4b6f Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Sun, 22 Sep 2019 15:40:58 +0000 Subject: [PATCH 0490/1906] BUGFIX ::: Adding ability to access assets in read only insights. Otherwise required edit access which should be reserved git-svn-id: svn://107.170.10.188:8080/Monolith/dev@35024 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: d93b394dc5f32bd45c812e91fd3544a3814ea9fd --- src/prerna/upload/FileUploader.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/prerna/upload/FileUploader.java b/src/prerna/upload/FileUploader.java index 795436847..81ce75f87 100644 --- a/src/prerna/upload/FileUploader.java +++ b/src/prerna/upload/FileUploader.java @@ -119,8 +119,8 @@ private List> getBaseUploadData(List fileItems, In String assetFolder = null; String fePath = Insight.getInsightRelativeFolderKey(in); if (appId != null) { - assetFolder = AssetUtility.getAssetBasePath(in, appId); - fePath = in.getAppRelativeFolderKey(); + assetFolder = AssetUtility.getAssetBasePath(in, appId, true); + fePath = Insight.getAppRelativeFolderKey(); } else { assetFolder = in.getInsightFolder(); } From 7544f061bcfa3ee712accc40ff9ecde38930f71a Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 23 Sep 2019 21:41:02 +0000 Subject: [PATCH 0491/1906] UPDATE ::: Adding proper error message if anonymous user git-svn-id: svn://107.170.10.188:8080/Monolith/dev@35051 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 8ea996116da03c05f9ba065cbed72a5cd83b7a5d --- src/prerna/upload/ImageUploader.java | 42 ++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/src/prerna/upload/ImageUploader.java b/src/prerna/upload/ImageUploader.java index 63a3c777d..0f6d00220 100644 --- a/src/prerna/upload/ImageUploader.java +++ b/src/prerna/upload/ImageUploader.java @@ -60,19 +60,32 @@ public Response uploadAppImage(@Context HttpServletRequest request) { HttpSession session = request.getSession(false); if(session != null){ User user = ((User) session.getAttribute(Constants.SESSION_USER)); + if(user == null) { + HashMap errorMap = new HashMap(); + errorMap.put("errorMessage", "Session could not be validated in order to upload the app image"); + return WebUtility.getResponse(errorMap, 400); + } + + if(user.isAnonymous()) { + HashMap errorMap = new HashMap(); + errorMap.put("errorMessage", "Must be logged in to upload an app image"); + return WebUtility.getResponse(errorMap, 400); + } + try { appId = SecurityQueryUtils.testUserEngineIdForAlias(user, appName); } catch(Exception e) { returnMap.put("errorMessage", e.getMessage()); - return WebUtility.getResponse(returnMap, 401); + return WebUtility.getResponse(returnMap, 400); } if(!SecurityAppUtils.userCanEditEngine(user, appId)) { - throw new IllegalArgumentException("Database " + appId + " does not exist or user does not have access to database"); + returnMap.put("errorMessage", "User does not have access to this app or the app id does not exist"); + return WebUtility.getResponse(returnMap, 400); } appName = SecurityQueryUtils.getEngineAliasForId(appId); } else { returnMap.put("errorMessage", "User session is invalid"); - return WebUtility.getResponse(returnMap, 401); + return WebUtility.getResponse(returnMap, 400); } } else { appId = MasterDatabaseUtility.testEngineIdIfAlias(appName); @@ -80,7 +93,7 @@ public Response uploadAppImage(@Context HttpServletRequest request) { String appDir = filePath + DIR_SEPARATOR + SmssUtilities.getUniqueName(appName, appId); if(!(new File(appDir).exists())) { returnMap.put("errorMessage", "Could not find app directory"); - return WebUtility.getResponse(returnMap, 401); + return WebUtility.getResponse(returnMap, 400); } } @@ -158,19 +171,32 @@ public Response uploadInsightImage(@Context HttpServletRequest request) { HttpSession session = request.getSession(false); if(session != null){ User user = ((User) session.getAttribute(Constants.SESSION_USER)); + if(user == null) { + HashMap errorMap = new HashMap(); + errorMap.put("errorMessage", "Session could not be validated in order to upload the insight image"); + return WebUtility.getResponse(errorMap, 400); + } + + if(user.isAnonymous()) { + HashMap errorMap = new HashMap(); + errorMap.put("errorMessage", "Must be logged in to upload files"); + return WebUtility.getResponse(errorMap, 400); + } + try { appId = SecurityQueryUtils.testUserEngineIdForAlias(user, appName); } catch(Exception e) { returnMap.put("errorMessage", e.getMessage()); - return WebUtility.getResponse(returnMap, 401); + return WebUtility.getResponse(returnMap, 400); } if(!SecurityInsightUtils.userCanEditInsight(user, appId, insightId)) { - throw new IllegalArgumentException("User does not have access to edit this insight within the app"); + returnMap.put("errorMessage", "User does not have access to edit this insight within the app"); + return WebUtility.getResponse(returnMap, 400); } appName = SecurityQueryUtils.getEngineAliasForId(appId); } else { returnMap.put("errorMessage", "User session is invalid"); - return WebUtility.getResponse(returnMap, 401); + return WebUtility.getResponse(returnMap, 400); } } else { appId = MasterDatabaseUtility.testEngineIdIfAlias(appName); @@ -178,7 +204,7 @@ public Response uploadInsightImage(@Context HttpServletRequest request) { String appDir = filePath + DIR_SEPARATOR + SmssUtilities.getUniqueName(appName, appId); if(!(new File(appDir).exists())) { returnMap.put("errorMessage", "Could not find app directory"); - return WebUtility.getResponse(returnMap, 401); + return WebUtility.getResponse(returnMap, 400); } } From 1e601ddd99deb01740e5423e6458120abc9bbc0c Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 23 Sep 2019 21:41:49 +0000 Subject: [PATCH 0492/1906] UPDATE ::: Updating language in return message git-svn-id: svn://107.170.10.188:8080/Monolith/dev@35052 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: dc3b380e5c336a3207139403df46cdaeb39d2c6d --- src/prerna/upload/ImageUploader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prerna/upload/ImageUploader.java b/src/prerna/upload/ImageUploader.java index 0f6d00220..2ffaad45b 100644 --- a/src/prerna/upload/ImageUploader.java +++ b/src/prerna/upload/ImageUploader.java @@ -179,7 +179,7 @@ public Response uploadInsightImage(@Context HttpServletRequest request) { if(user.isAnonymous()) { HashMap errorMap = new HashMap(); - errorMap.put("errorMessage", "Must be logged in to upload files"); + errorMap.put("errorMessage", "Must be logged in to upload an insight image"); return WebUtility.getResponse(errorMap, 400); } From 7b61c5da29796741b74aeae7d71d0eabddffb942 Mon Sep 17 00:00:00 2001 From: rramirezjimenez Date: Wed, 9 Oct 2019 17:18:04 +0000 Subject: [PATCH 0493/1906] BUGFIX ::: Send user map info when doing a native login git-svn-id: svn://107.170.10.188:8080/Monolith/dev@35307 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 946848e821853d4cdf305728eb141460bde78b19 --- src/prerna/semoss/web/services/local/UserResource.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index 0bea42fe8..6fc6afa38 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -1425,7 +1425,7 @@ public Response loginNative(@Context HttpServletRequest request, @Context HttpSe return WebUtility.getResponse(ret, 500); } - return null; + return WebUtility.getResponse(ret, 200); } /** From 3deedf622cc68e67b620b1f8001821dce07afb37 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 9 Oct 2019 21:46:15 +0000 Subject: [PATCH 0494/1906] UPDATE ::: Adding method overriding for interface change to get engine from wrapper git-svn-id: svn://107.170.10.188:8080/Monolith/dev@35322 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 23f97d38a519fa5c0d34ba3aca8d845534df2e74 --- src/prerna/cluster/RawSelectWrapperService.java | 5 +++++ src/prerna/upload/FileUploader.java | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/prerna/cluster/RawSelectWrapperService.java b/src/prerna/cluster/RawSelectWrapperService.java index 87610236d..30be41d48 100644 --- a/src/prerna/cluster/RawSelectWrapperService.java +++ b/src/prerna/cluster/RawSelectWrapperService.java @@ -221,6 +221,11 @@ public void setEngine(IEngine engine) { throw new IllegalStateException("Only overriding this method for reference."); } + @Override + public IEngine getEngine() { + throw new IllegalStateException("Only overriding this method for reference."); + } + /** * Set engine requires appId and wrapperId * @param request diff --git a/src/prerna/upload/FileUploader.java b/src/prerna/upload/FileUploader.java index 81ce75f87..b2260a70a 100644 --- a/src/prerna/upload/FileUploader.java +++ b/src/prerna/upload/FileUploader.java @@ -82,7 +82,8 @@ public Response uploadFile(@Context HttpServletRequest request, @QueryParam("ins errorMap.put("errorMessage", "User does not have permission to publish data. Please reach out to the admin to get proper access"); return WebUtility.getResponse(errorMap, 400); } - if (appId != null && !appId.equalsIgnoreCase("user")) { + + if(appId != null && !appId.equalsIgnoreCase("user")) { if (!SecurityAppUtils.userCanEditEngine(in.getUser(), appId)) { HashMap errorMap = new HashMap(); errorMap.put("errorMessage", "User does not have permission for this app."); From 2987f17c1fcf38cf2dd75e91492d17dba9ac376f Mon Sep 17 00:00:00 2001 From: kunalppatel9 Date: Thu, 17 Oct 2019 17:07:39 +0000 Subject: [PATCH 0495/1906] UPDATE ::: Adding clickhouse jdbc git-svn-id: svn://107.170.10.188:8080/Monolith/dev@35445 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 7d1e5d40a6fc5e6e86c7607d60b455e2d3b4f01d --- pom.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pom.xml b/pom.xml index ded09edac..4a4205036 100644 --- a/pom.xml +++ b/pom.xml @@ -2989,6 +2989,11 @@ snowflake-jdbc 3.7.0 + + ru.yandex.clickhouse + clickhouse-jdbc + 0.2 + me.xdrop fuzzywuzzy From 5cecad4a876f1a2aeeb95e896c7f3191f849ce5c Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 22 Oct 2019 13:12:42 +0000 Subject: [PATCH 0496/1906] UPDATE ::: Adding security on the app resource to download the app image + insight image git-svn-id: svn://107.170.10.188:8080/Monolith/dev@35523 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 58c1d195beb96a491d148732353189f8bd5e0cb0 --- .../web/services/local/AppResource.java | 126 +++++++++++++++--- 1 file changed, 110 insertions(+), 16 deletions(-) diff --git a/src/prerna/semoss/web/services/local/AppResource.java b/src/prerna/semoss/web/services/local/AppResource.java index cbb8e5c57..c386c90ff 100644 --- a/src/prerna/semoss/web/services/local/AppResource.java +++ b/src/prerna/semoss/web/services/local/AppResource.java @@ -32,6 +32,7 @@ import prerna.auth.User; import prerna.auth.utils.AbstractSecurityUtils; import prerna.auth.utils.SecurityAppUtils; +import prerna.auth.utils.SecurityInsightUtils; import prerna.auth.utils.SecurityQueryUtils; import prerna.cluster.util.ClusterUtil; import prerna.engine.api.IEngine; @@ -43,19 +44,12 @@ import prerna.util.insight.TextToGraphic; import prerna.web.services.util.WebUtility; -@Path("/app-{appName}") +@Path("/app-{appId}") public class AppResource { private static final String DIR_SEPARATOR = java.nio.file.FileSystems.getDefault().getSeparator(); - /** - * Utility method to get the app only if person has access to it - * @param user - * @param appId - * @return - * @throws IllegalAccessException - */ - private IEngine getApp(User user, String appId) throws IllegalAccessException { + private boolean canAccessApp(User user, String appId) throws IllegalAccessException { if(AbstractSecurityUtils.securityEnabled()) { appId = SecurityQueryUtils.testUserEngineIdForAlias(user, appId); if(!SecurityAppUtils.userCanViewEngine(user, appId)) { @@ -68,8 +62,75 @@ private IEngine getApp(User user, String appId) throws IllegalAccessException { } } + return true; + } + + private boolean canAccessInsight(User user, String appId, String insightId) throws IllegalAccessException { + if(AbstractSecurityUtils.securityEnabled()) { + appId = SecurityQueryUtils.testUserEngineIdForAlias(user, appId); + if(!SecurityInsightUtils.userCanViewInsight(user, appId, insightId)) { + throw new IllegalAccessException("Insight does not exist or user does not have access to view"); + } + } else { + appId = MasterDatabaseUtility.testEngineIdIfAlias(appId); + if(!MasterDatabaseUtility.getAllEngineIds().contains(appId)) { + throw new IllegalAccessException("App " + appId + " does not exist"); + } + } + + return true; + } + + /** + * Utility method to get the app only if person has access to it + * @param user + * @param appId + * @return + * @throws IllegalAccessException + */ + private IEngine getApp(User user, String appId) throws IllegalAccessException { + canAccessApp(user, appId); return Utility.getEngine(appId); } + + /////////////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////////////// + + /* + * Code below is around retrieving app assets + */ + + @GET + @Path("/appLanding") + @Produces({MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_SVG_XML}) + public Response getAppLandingPage(@Context final Request coreRequest, @Context HttpServletRequest request, @PathParam("appId") String app) { + File exportFile = getAppImageFile(app); + if(exportFile != null && exportFile.exists()) { + String exportName = app + "_Image." + FilenameUtils.getExtension(exportFile.getAbsolutePath()); + // want to cache this on browser if user has access + CacheControl cc = new CacheControl(); + cc.setMaxAge(86400); + cc.setPrivate(true); + EntityTag etag = new EntityTag(Integer.toString(exportFile.hashCode())); + ResponseBuilder builder = coreRequest.evaluatePreconditions(etag); + + // cached resource did not change + if(builder != null) { + return builder.build(); + } + + return Response.status(200).entity(exportFile).header("Content-Disposition", "attachment; filename=" + exportName) + .cacheControl(cc).tag(etag).lastModified(new Date(exportFile.lastModified())).build(); + } else { + Map errorMap = new HashMap(); + errorMap.put("errorMessage", "error sending image file"); + return WebUtility.getResponse(errorMap, 400); + } + } + /////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -84,10 +145,26 @@ private IEngine getApp(User user, String appId) throws IllegalAccessException { @GET @Path("/appImage/download") @Produces({MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_SVG_XML}) - public Response downloadAppImage(@Context final Request coreRequest, @Context HttpServletRequest request, @PathParam("appName") String app) { - File exportFile = getAppImageFile(app); + public Response downloadAppImage(@Context final Request coreRequest, @Context HttpServletRequest request, @PathParam("appId") String appId) { + User user = null; + try { + user = ResourceUtility.getUser(request); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap(); + errorMap.put("error", "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + try { + canAccessApp(user, appId); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap(); + errorMap.put("error", e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + + File exportFile = getAppImageFile(appId); if(exportFile != null && exportFile.exists()) { - String exportName = app + "_Image." + FilenameUtils.getExtension(exportFile.getAbsolutePath()); + String exportName = appId + "_Image." + FilenameUtils.getExtension(exportFile.getAbsolutePath()); // want to cache this on browser if user has access CacheControl cc = new CacheControl(); cc.setMaxAge(86400); @@ -150,16 +227,33 @@ protected File getAppImageFile(String app) { @GET @Path("/insightImage/download") @Produces({MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_SVG_XML}) - public Response downloadInsightImage(@Context final Request coreRequest, @Context HttpServletRequest request, @PathParam("appName") String app, @QueryParam("rdbmsId") String id, @QueryParam("params") String params) { + public Response downloadInsightImage(@Context final Request coreRequest, @Context HttpServletRequest request, @PathParam("appId") String appId, @QueryParam("rdbmsId") String id, @QueryParam("params") String params) { + User user = null; + try { + user = ResourceUtility.getUser(request); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap(); + errorMap.put("error", "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + try { + canAccessInsight(user, appId, id); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap(); + errorMap.put("error", e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + + boolean securityEnabled = AbstractSecurityUtils.securityEnabled(); String sessionId = null; if(securityEnabled){ sessionId = request.getSession(false).getId(); } - File exportFile = getInsightImageFile(app, id, request.getHeader("Referer"), params, sessionId); + File exportFile = getInsightImageFile(appId, id, request.getHeader("Referer"), params, sessionId); if(exportFile != null && exportFile.exists()) { - String exportName = app + "_Image." + FilenameUtils.getExtension(exportFile.getAbsolutePath()); + String exportName = appId + "_Image." + FilenameUtils.getExtension(exportFile.getAbsolutePath()); // want to cache this on browser if user has access CacheControl cc = new CacheControl(); cc.setMaxAge(86400); @@ -292,7 +386,7 @@ protected void closeStream(FileInputStream fis) { @GET @Path("/appWidget") @Produces(MediaType.APPLICATION_OCTET_STREAM) - public Response getAppWidget(@PathParam("appName") String app, @QueryParam("widget") String widgetName, @QueryParam("file") String fileName) { + public Response getAppWidget(@PathParam("appId") String app, @QueryParam("widget") String widgetName, @QueryParam("file") String fileName) { final String basePath = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER); String appWidgetDirLoc = basePath + DIR_SEPARATOR + "db" + DIR_SEPARATOR + app + From 9e2dd5ef7e1a8c401ac3a2d604256a976a04747a Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 22 Oct 2019 14:55:36 +0000 Subject: [PATCH 0497/1906] UPDATE ::: Building out method to return landing.html file from the app assets. Example REST call: http://localhost:8080/Monolith_Dev/api/app-c6f6f6c3-a963-4b45-a894-9ec12452262f/appLanding git-svn-id: svn://107.170.10.188:8080/Monolith/dev@35526 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 34344f8cafa5792580eba8434a2d6182dcb4a26f --- .../web/services/local/AppResource.java | 58 ++++++++++++++----- 1 file changed, 43 insertions(+), 15 deletions(-) diff --git a/src/prerna/semoss/web/services/local/AppResource.java b/src/prerna/semoss/web/services/local/AppResource.java index c386c90ff..5504b17e2 100644 --- a/src/prerna/semoss/web/services/local/AppResource.java +++ b/src/prerna/semoss/web/services/local/AppResource.java @@ -4,6 +4,8 @@ import java.io.FileFilter; import java.io.FileInputStream; import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; import java.util.Date; import java.util.HashMap; import java.util.List; @@ -105,16 +107,37 @@ private IEngine getApp(User user, String appId) throws IllegalAccessException { @GET @Path("/appLanding") - @Produces({MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_SVG_XML}) - public Response getAppLandingPage(@Context final Request coreRequest, @Context HttpServletRequest request, @PathParam("appId") String app) { - File exportFile = getAppImageFile(app); - if(exportFile != null && exportFile.exists()) { - String exportName = app + "_Image." + FilenameUtils.getExtension(exportFile.getAbsolutePath()); + @Produces(MediaType.TEXT_HTML) + public Response getAppLandingPage(@Context final Request coreRequest, @Context HttpServletRequest request, @PathParam("appId") String appId) { + User user = null; + try { + user = ResourceUtility.getUser(request); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap(); + errorMap.put("error", "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + try { + canAccessApp(user, appId); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap(); + errorMap.put("error", e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + + String propFileLoc = DIHelper.getInstance().getProperty(appId + "_" + Constants.STORE); + Properties prop = Utility.loadProperties(propFileLoc); + String appName = prop.getProperty(Constants.ENGINE_ALIAS); + + String baseFolder = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER); + String fileLocation = baseFolder + DIR_SEPARATOR + "db" + DIR_SEPARATOR + SmssUtilities.getUniqueName(appName, appId) + DIR_SEPARATOR + "version/assets/landing.html"; + File landingPageFile = new File(fileLocation); + if(landingPageFile != null && landingPageFile.exists()) { // want to cache this on browser if user has access CacheControl cc = new CacheControl(); cc.setMaxAge(86400); cc.setPrivate(true); - EntityTag etag = new EntityTag(Integer.toString(exportFile.hashCode())); + EntityTag etag = new EntityTag(Integer.toString(landingPageFile.hashCode())); ResponseBuilder builder = coreRequest.evaluatePreconditions(etag); // cached resource did not change @@ -122,16 +145,21 @@ public Response getAppLandingPage(@Context final Request coreRequest, @Context H return builder.build(); } - return Response.status(200).entity(exportFile).header("Content-Disposition", "attachment; filename=" + exportName) - .cacheControl(cc).tag(etag).lastModified(new Date(exportFile.lastModified())).build(); + try { + String html = new String(Files.readAllBytes(Paths.get(landingPageFile.getAbsolutePath()))); + return Response.status(200).entity(html).cacheControl(cc).tag(etag).lastModified(new Date(landingPageFile.lastModified())).build(); + } catch (IOException e) { + Map errorMap = new HashMap(); + errorMap.put("errorMessage", "Unable to load landing html file"); + return WebUtility.getResponse(errorMap, 400); + } } else { Map errorMap = new HashMap(); - errorMap.put("errorMessage", "error sending image file"); + errorMap.put("errorMessage", "No custom landing page found"); return WebUtility.getResponse(errorMap, 400); } } - /////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -169,6 +197,7 @@ public Response downloadAppImage(@Context final Request coreRequest, @Context Ht CacheControl cc = new CacheControl(); cc.setMaxAge(86400); cc.setPrivate(true); + cc.setMustRevalidate(true); EntityTag etag = new EntityTag(Integer.toString(exportFile.hashCode())); ResponseBuilder builder = coreRequest.evaluatePreconditions(etag); @@ -244,7 +273,6 @@ public Response downloadInsightImage(@Context final Request coreRequest, @Contex return WebUtility.getResponse(errorMap, 401); } - boolean securityEnabled = AbstractSecurityUtils.securityEnabled(); String sessionId = null; if(securityEnabled){ @@ -258,6 +286,7 @@ public Response downloadInsightImage(@Context final Request coreRequest, @Contex CacheControl cc = new CacheControl(); cc.setMaxAge(86400); cc.setPrivate(true); + cc.setMustRevalidate(true); EntityTag etag = new EntityTag(Integer.toString(exportFile.hashCode())); ResponseBuilder builder = coreRequest.evaluatePreconditions(etag); @@ -280,14 +309,13 @@ public Response downloadInsightImage(@Context final Request coreRequest, @Contex * @param app * @return */ - private File getInsightImageFile(String app, String id, String feUrl, String params, String sessionId) { - String appId = MasterDatabaseUtility.testEngineIdIfAlias(app); + private File getInsightImageFile(String appId, String id, String feUrl, String params, String sessionId) { String propFileLoc = DIHelper.getInstance().getProperty(appId + "_" + Constants.STORE); Properties prop = Utility.loadProperties(propFileLoc); - app = prop.getProperty(Constants.ENGINE_ALIAS); + String appName = prop.getProperty(Constants.ENGINE_ALIAS); String baseFolder = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER); - String fileLocation = baseFolder + DIR_SEPARATOR + "db" + DIR_SEPARATOR + SmssUtilities.getUniqueName(app, appId) + DIR_SEPARATOR + "version"; + String fileLocation = baseFolder + DIR_SEPARATOR + "db" + DIR_SEPARATOR + SmssUtilities.getUniqueName(appName, appId) + DIR_SEPARATOR + "version"; if(params != null && !params.isEmpty() && !params.equals("undefined")) { String encodedParams = Utility.encodeURIComponent(params); fileLocation = fileLocation + From 2eb6cd72a7340ea83fd1d6044a6eb62fda72ce2c Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 23 Oct 2019 14:18:56 +0000 Subject: [PATCH 0498/1906] UPDATE ::: End point to return files via relative paths UPDATE ::: Modifying the cache to be cache control based on the data contents and not the file object itself git-svn-id: svn://107.170.10.188:8080/Monolith/dev@35552 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: d1a8dab2c6ad60fcca048998123c0c3c25f721bb --- .../web/services/local/AppResource.java | 91 +++++++++++++++---- 1 file changed, 74 insertions(+), 17 deletions(-) diff --git a/src/prerna/semoss/web/services/local/AppResource.java b/src/prerna/semoss/web/services/local/AppResource.java index 5504b17e2..e1127b814 100644 --- a/src/prerna/semoss/web/services/local/AppResource.java +++ b/src/prerna/semoss/web/services/local/AppResource.java @@ -106,7 +106,7 @@ private IEngine getApp(User user, String appId) throws IllegalAccessException { */ @GET - @Path("/appLanding") + @Path("/landing") @Produces(MediaType.TEXT_HTML) public Response getAppLandingPage(@Context final Request coreRequest, @Context HttpServletRequest request, @PathParam("appId") String appId) { User user = null; @@ -131,23 +131,24 @@ public Response getAppLandingPage(@Context final Request coreRequest, @Context H String baseFolder = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER); String fileLocation = baseFolder + DIR_SEPARATOR + "db" + DIR_SEPARATOR + SmssUtilities.getUniqueName(appName, appId) + DIR_SEPARATOR + "version/assets/landing.html"; - File landingPageFile = new File(fileLocation); - if(landingPageFile != null && landingPageFile.exists()) { - // want to cache this on browser if user has access - CacheControl cc = new CacheControl(); - cc.setMaxAge(86400); - cc.setPrivate(true); - EntityTag etag = new EntityTag(Integer.toString(landingPageFile.hashCode())); - ResponseBuilder builder = coreRequest.evaluatePreconditions(etag); - - // cached resource did not change - if(builder != null) { - return builder.build(); - } - + File file = new File(fileLocation); + if(file != null && file.exists()) { try { - String html = new String(Files.readAllBytes(Paths.get(landingPageFile.getAbsolutePath()))); - return Response.status(200).entity(html).cacheControl(cc).tag(etag).lastModified(new Date(landingPageFile.lastModified())).build(); + String html = new String(Files.readAllBytes(Paths.get(file.getAbsolutePath()))); + + // want to cache this on browser if user has access + CacheControl cc = new CacheControl(); + cc.setMaxAge(1); + cc.setPrivate(true); + EntityTag etag = new EntityTag(Integer.toString(html.hashCode())); + ResponseBuilder builder = coreRequest.evaluatePreconditions(etag); + + // cached resource did not change + if(builder != null) { + return builder.build(); + } + + return Response.status(200).entity(html).cacheControl(cc).tag(etag).lastModified(new Date(file.lastModified())).build(); } catch (IOException e) { Map errorMap = new HashMap(); errorMap.put("errorMessage", "Unable to load landing html file"); @@ -160,6 +161,62 @@ public Response getAppLandingPage(@Context final Request coreRequest, @Context H } } + @GET + @Path("/{relPath}") + @Produces({MediaType.TEXT_HTML, MediaType.APPLICATION_OCTET_STREAM}) + public Response getAppFile(@Context final Request coreRequest, @Context HttpServletRequest request, @PathParam("appId") String appId, @PathParam("relPath") String relPath) { + User user = null; + try { + user = ResourceUtility.getUser(request); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap(); + errorMap.put("error", "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + try { + canAccessApp(user, appId); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap(); + errorMap.put("error", e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + + String propFileLoc = DIHelper.getInstance().getProperty(appId + "_" + Constants.STORE); + Properties prop = Utility.loadProperties(propFileLoc); + String appName = prop.getProperty(Constants.ENGINE_ALIAS); + + String baseFolder = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER); + String fileLocation = baseFolder + DIR_SEPARATOR + "db" + DIR_SEPARATOR + SmssUtilities.getUniqueName(appName, appId) + DIR_SEPARATOR + "version/assets/" + relPath; + File file = new File(fileLocation); + if(file != null && file.exists()) { + try { + String contents = new String(Files.readAllBytes(Paths.get(file.getAbsolutePath()))); + + // want to cache this on browser if user has access + CacheControl cc = new CacheControl(); + cc.setMaxAge(1); + cc.setPrivate(true); + EntityTag etag = new EntityTag(Integer.toString(contents.hashCode())); + ResponseBuilder builder = coreRequest.evaluatePreconditions(etag); + + // cached resource did not change + if(builder != null) { + return builder.build(); + } + + return Response.status(200).entity(contents).cacheControl(cc).tag(etag).lastModified(new Date(file.lastModified())).build(); + } catch (IOException e) { + Map errorMap = new HashMap(); + errorMap.put("errorMessage", "Unable to load file"); + return WebUtility.getResponse(errorMap, 400); + } + } else { + Map errorMap = new HashMap(); + errorMap.put("errorMessage", "No file found"); + return WebUtility.getResponse(errorMap, 400); + } + } + /////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////// From c94459288192b6e7b65c2ddecadcb5a8f0c283cd Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 25 Oct 2019 13:27:10 +0000 Subject: [PATCH 0499/1906] UPDATE ::: Sending the default frame type on the init call to the FE to (hopefully) start to use when the "default" is selected on frame importing git-svn-id: svn://107.170.10.188:8080/Monolith/dev@35636 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 7025fc1e0c743bc1dd94652ed065be8b1ce94059 --- .../services/config/ServerConfigurationResource.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/prerna/semoss/web/services/config/ServerConfigurationResource.java b/src/prerna/semoss/web/services/config/ServerConfigurationResource.java index 6b190256c..02b12b8dc 100644 --- a/src/prerna/semoss/web/services/config/ServerConfigurationResource.java +++ b/src/prerna/semoss/web/services/config/ServerConfigurationResource.java @@ -98,6 +98,18 @@ private static Map getConfig(@Context HttpServletRequest request // ignore } + // send the default frame type + String defaultFrameType = DIHelper.getInstance().getProperty(Constants.DEFAULT_FRAME_TYPE); + if(defaultFrameType != null) { + try { + config.put("defaultFrameType", defaultFrameType); + } catch(Exception e) { + // ignore + } + } else { + config.put("defaultFrameType", "GRID"); + } + // local mode boolean localMode = false; String localModeStr = DIHelper.getInstance().getProperty(Constants.LOCAL_DEPLOYMENT); From ed6195f2afcce7b4dfe3c58e2531f73c74387f7d Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 28 Oct 2019 14:14:48 +0000 Subject: [PATCH 0500/1906] UPDATE ::: Taking in app ids + tags if sent in a filter map when searching for insights via the REST endpoint git-svn-id: svn://107.170.10.188:8080/Monolith/dev@35666 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 7b2859383aa734b008dcb38db066641add5f10b7 --- .../semoss/web/services/local/NameServer.java | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index f820fb778..d07c8f890 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -1222,6 +1222,8 @@ public StreamingOutput getAutoCompleteResults(@QueryParam("completeTerm") String @Path("central/context/getSearchInsightsResults") @Produces("application/json") public StreamingOutput getSearchInsightsResults(MultivaluedMap form, @Context HttpServletRequest request) { + Gson gson = new Gson(); + // text searched in search bar String searchString = form.getFirst("searchString"); // offset for call @@ -1229,6 +1231,23 @@ public StreamingOutput getSearchInsightsResults(MultivaluedMap f // offset for call String limit = form.getFirst("limit"); + List appIds = null; + List tags = null; + + String filterStr = form.getFirst("filterData"); + if(filterStr != null) { + try { + Map> filterMap = gson.fromJson(filterStr, Map.class); + appIds = filterMap.get("app_id"); + tags = filterMap.get("tags"); + } catch(Exception e) { + e.printStackTrace(); + Map errorMap = new HashMap(); + errorMap.put("errorMessage", "Invalid fitler map"); + return WebUtility.getSO(errorMap); + } + } + // If security is enabled, remove the engines in the filters that aren't // accessible - if none in filters, add all accessible engines to filter // list @@ -1238,9 +1257,9 @@ public StreamingOutput getSearchInsightsResults(MultivaluedMap f // filter insights based on what the user has access to HttpSession session = request.getSession(false); User user = ((User) session.getAttribute(Constants.SESSION_USER)); - queryResults = SecurityInsightUtils.searchUserInsights(user, null, searchString, null, limit, offset); + queryResults = SecurityInsightUtils.searchUserInsights(user, appIds, searchString, tags, limit, offset); } else { - queryResults = SecurityInsightUtils.searchInsights(null, searchString, null, limit, offset); + queryResults = SecurityInsightUtils.searchInsights(appIds, searchString, tags, limit, offset); } return WebUtility.getSO(queryResults); From 91cb978cf624304a6388ab65760ce0b9339d0678 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 28 Oct 2019 14:20:26 +0000 Subject: [PATCH 0501/1906] BUGFIX ::: Fixing typo in error return git-svn-id: svn://107.170.10.188:8080/Monolith/dev@35667 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 619d85a325564ab9003cadb66e3e15826066393c --- src/prerna/semoss/web/services/local/NameServer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index d07c8f890..e688fcc5b 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -1243,7 +1243,7 @@ public StreamingOutput getSearchInsightsResults(MultivaluedMap f } catch(Exception e) { e.printStackTrace(); Map errorMap = new HashMap(); - errorMap.put("errorMessage", "Invalid fitler map"); + errorMap.put("errorMessage", "Invalid filter map"); return WebUtility.getSO(errorMap); } } From 9b625736f906660e23c9b98dc39188d2275d600a Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 28 Oct 2019 21:53:51 +0000 Subject: [PATCH 0502/1906] UPDATE ::: Adding url storage to route back to a GET post login git-svn-id: svn://107.170.10.188:8080/Monolith/dev@35689 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: d49180223b90f537c16c35ccfcea8558b180b4fd --- .../web/services/local/UserResource.java | 143 +++++++++++------- .../web/conf/NoUserInSessionFilter.java | 27 +++- 2 files changed, 110 insertions(+), 60 deletions(-) diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index 6fc6afa38..7dcbbc33d 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -147,6 +147,14 @@ private static void loadSocialProperties() { } } + /** + * Method to get the redirect URL if defined in the social properties + * @return + */ + public static String getLoginRedirect() { + return socialData.getProperty("redirect") + "/login"; + } + private static void setLoginsAllowed() { boolean nativeLogin = Boolean.parseBoolean(socialData.getProperty("native_login")); boolean githubLogin = Boolean.parseBoolean(socialData.getProperty("github_login")); @@ -201,7 +209,7 @@ public Response getAllLogins(@Context HttpServletRequest request) { @GET @Produces("application/json") @Path("/logout/{provider}") - public Response logout(@PathParam("provider") String provider, @Context HttpServletRequest request, @Context HttpServletResponse repsonse) throws IOException { + public Response logout(@PathParam("provider") String provider, @Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException { boolean noUser = false; boolean removed = false; @@ -266,11 +274,11 @@ public Void call() throws Exception { session.removeAttribute(Constants.SESSION_USER); // well, you have logged out and we always require a login // so i will redirect you - repsonse.setStatus(302); + response.setStatus(302); String redirectUrl = request.getHeader("referer"); redirectUrl = redirectUrl + "#!/login"; - repsonse.setHeader("redirect", redirectUrl); - repsonse.sendError(302, "Need to redirect to " + redirectUrl); + response.setHeader("redirect", redirectUrl); + response.sendError(302, "Need to redirect to " + redirectUrl); // remove the cookie from the browser // for the session id @@ -288,7 +296,7 @@ public Void call() throws Exception { nullC.setDomain(c.getDomain()); } nullC.setMaxAge(0); - repsonse.addCookie(nullC); + response.addCookie(nullC); } } } @@ -536,10 +544,7 @@ public Response loginSF(@Context HttpServletRequest request, @Context HttpServle */ User userObj = (User) request.getSession().getAttribute(Constants.SESSION_USER); - Hashtable ret = new Hashtable(); - String queryString = request.getQueryString(); - if(queryString != null && queryString.contains("code=")) { if(userObj == null || userObj.getAccessToken(AuthProvider.SF) == null) { String[] outputs = AbstractHttpHelper.getCodes(queryString); @@ -580,9 +585,10 @@ public Response loginSF(@Context HttpServletRequest request, @Context HttpServle // not authenticated response.setStatus(302); response.sendRedirect(getSFRedirect(request)); - } else { - setMainPageRedirect(request, response, null); + return null; } + + setMainPageRedirect(request, response); return null; } @@ -615,7 +621,6 @@ public Response loginSurveyMonkey(@Context HttpServletRequest request, @Context */ User userObj = (User) request.getSession().getAttribute(Constants.SESSION_USER); - String queryString = request.getQueryString(); if(queryString != null && queryString.contains("code=")) { if(userObj == null || userObj.getAccessToken(AuthProvider.SURVEYMONKEY) == null) { @@ -658,9 +663,10 @@ public Response loginSurveyMonkey(@Context HttpServletRequest request, @Context // not authenticated response.setStatus(302); response.sendRedirect(getSurveyMonkeyRedirect(request)); - } else { - setMainPageRedirect(request, response, null); + return null; } + + setMainPageRedirect(request, response); return null; } @@ -692,9 +698,7 @@ public Response loginGithub(@Context HttpServletRequest request, @Context HttpSe * Redirect the FE */ - Map ret = new Hashtable(); User userObj = (User) request.getSession().getAttribute(Constants.SESSION_USER); - String queryString = request.getQueryString(); if(queryString != null && queryString.contains("code=")) { if(userObj == null || userObj.getAccessToken(AuthProvider.GITHUB) == null) { @@ -744,9 +748,10 @@ public Response loginGithub(@Context HttpServletRequest request, @Context HttpSe // not authenticated response.setStatus(302); response.sendRedirect(getGithubRedirect(request)); - } else { - setMainPageRedirect(request, response, null); + return null; } + + setMainPageRedirect(request, response); return null; } @@ -780,9 +785,7 @@ public Response loginMS(@Context HttpServletRequest request, @Context HttpServle * Redirect the FE */ - Map ret = new Hashtable(); User userObj = (User) request.getSession().getAttribute(Constants.SESSION_USER); - String queryString = request.getQueryString(); if(queryString != null && queryString.contains("code=")) { if(userObj == null || ((User)userObj).getAccessToken(AuthProvider.MS) == null) { @@ -829,9 +832,10 @@ public Response loginMS(@Context HttpServletRequest request, @Context HttpServle // not authenticated response.setStatus(302); response.sendRedirect(getMSRedirect(request)); - } else { - setMainPageRedirect(request, response, null); - } + return null; + } + + setMainPageRedirect(request, response); return null; } @@ -868,9 +872,7 @@ public Response loginDropBox(@Context HttpServletRequest request, @Context HttpS * Redirect the FE */ - Map ret = new Hashtable(); User userObj = (User) request.getSession().getAttribute(Constants.SESSION_USER); - String queryString = request.getQueryString(); if(queryString != null && queryString.contains("code=")) { if(userObj == null || userObj.getAccessToken(AuthProvider.DROPBOX) == null) { @@ -912,9 +914,10 @@ public Response loginDropBox(@Context HttpServletRequest request, @Context HttpS // not authenticated response.setStatus(302); response.sendRedirect(getDBRedirect(request)); - } else { - setMainPageRedirect(request, response, null); - } + return null; + } + + setMainPageRedirect(request, response); return null; } @@ -949,9 +952,7 @@ public Response loginGoogle(@Context HttpServletRequest request, @Context HttpSe * Redirect the FE */ - Map ret = new Hashtable(); User userObj = (User) request.getSession().getAttribute(Constants.SESSION_USER); - String queryString = request.getQueryString(); if(queryString != null && queryString.contains("code=")) { if(userObj == null || userObj.getAccessToken(AuthProvider.GOOGLE) == null) { @@ -1004,9 +1005,10 @@ public Response loginGoogle(@Context HttpServletRequest request, @Context HttpSe // not authenticated response.setStatus(302); response.sendRedirect(getGoogleRedirect(request)); - } else { - setMainPageRedirect(request, response, null); + return null; } + + setMainPageRedirect(request, response); return null; } @@ -1099,7 +1101,6 @@ public Response loginProducthunt(@Context HttpServletRequest request, @Context H * Redirect the FE */ - Map ret = new Hashtable(); User userObj = (User) request.getSession().getAttribute(Constants.SESSION_USER); String queryString = request.getQueryString(); @@ -1143,9 +1144,10 @@ public Response loginProducthunt(@Context HttpServletRequest request, @Context H if(userObj == null || userObj.getAccessToken(AuthProvider.PRODUCT_HUNT) == null) { response.setStatus(302); response.sendRedirect(getProducthuntRedirect(request)); - } else { - setMainPageRedirect(request, response, null); + return null; } + + setMainPageRedirect(request, response); return null; } @@ -1179,9 +1181,7 @@ public Response loginIn(@Context HttpServletRequest request, @Context HttpServle * Redirect the FE */ - Map ret = new Hashtable(); User userObj = (User) request.getSession().getAttribute(Constants.SESSION_USER); - String queryString = request.getQueryString(); if(queryString != null && queryString.contains("code=")) { if(userObj == null || userObj.getAccessToken(AuthProvider.IN) == null) { @@ -1221,9 +1221,9 @@ public Response loginIn(@Context HttpServletRequest request, @Context HttpServle if(userObj == null || userObj.getAccessToken(AuthProvider.IN) == null) { response.setStatus(302); response.sendRedirect(getInRedirect(request)); - } else { - setMainPageRedirect(request, response, null); - } + } + + setMainPageRedirect(request, response); return null; } @@ -1268,18 +1268,14 @@ private String getInRedirect(HttpServletRequest request) throws UnsupportedEncod @Path("/login/twitter") public Response loginTwitter(@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException { - // redirect if query string not there - Object userObj = request.getSession().getAttribute(Constants.SESSION_USER); - Hashtable ret = new Hashtable(); - // getting the bearer token on twitter for app authentication is a lot simpler // need to just combine the id and secret // base 64 and send as authorization - //https://developer.github.com/apps/building-oauth-apps/authorization-options-for-oauth-apps/ + + User userObj = (User) request.getSession().getAttribute(Constants.SESSION_USER); String queryString = request.getQueryString(); - if(queryString != null && queryString.contains("code=")) { if(userObj == null || ((User)userObj).getAccessToken(AuthProvider.GITHUB) == null) { @@ -1303,6 +1299,13 @@ public Response loginTwitter(@Context HttpServletRequest request, @Context HttpS String url = "https://github.com/login/oauth/access_token"; AccessToken accessToken = AbstractHttpHelper.getAccessToken(url, params, false, true); + if(accessToken == null) { + // not authenticated + response.setStatus(302); + response.sendRedirect(getTwitterRedirect(request)); + return null; + } + accessToken.setProvider(AuthProvider.GITHUB); addAccessToken(accessToken, request); @@ -1315,10 +1318,11 @@ public Response loginTwitter(@Context HttpServletRequest request, @Context HttpS if(userObj == null || ((User)userObj).getAccessToken(AuthProvider.GITHUB) == null) { // not authenticated response.setStatus(302); - response.sendRedirect(getGithubRedirect(request)); - } else { - setMainPageRedirect(request, response, null); + response.sendRedirect(getTwitterRedirect(request)); + return null; } + + setMainPageRedirect(request, response); return null; } @@ -1395,6 +1399,7 @@ public Response loginNative(@Context HttpServletRequest request, @Context HttpSe String username = request.getParameter("username"); String password = request.getParameter("password"); String redirect = request.getParameter("redirect"); + Boolean disableRedirect = Boolean.parseBoolean(request.getParameter("enableRedirect") + ""); boolean emptyCredentials = (username == null || password == null || username.isEmpty() || password.isEmpty()); boolean canLogin = !emptyCredentials && NativeUserSecurityUtils.logIn(username, password); @@ -1414,7 +1419,9 @@ public Response loginNative(@Context HttpServletRequest request, @Context HttpSe authToken.setEmail(email); addAccessToken(authToken, request); - setMainPageRedirect(request, response, null); + if(!disableRedirect) { + setMainPageRedirect(request, response, redirect); + } } else { ret.put("error", "The user name or password are invalid."); return WebUtility.getResponse(ret, 401); @@ -1604,22 +1611,52 @@ public synchronized Response modifyLoginProperties(@PathParam("provider") String * Redirect the login back to the main app page * @param response */ - private void setMainPageRedirect(@Context HttpServletRequest request, @Context HttpServletResponse response, String redirect) { + private void setMainPageRedirect(@Context HttpServletRequest request, @Context HttpServletResponse response) { + setMainPageRedirect(request, response, null); + } + + /** + * Redirect the login back to the main app page + * @param response + */ + private void setMainPageRedirect(@Context HttpServletRequest request, @Context HttpServletResponse response, String customRedirect) { + // see if we have a location to redirect the user + // if so, we will send them back to that URL + // otherwise, we send them back to the FE + HttpSession session = request.getSession(); + boolean useCustom = customRedirect != null && !customRedirect.isEmpty(); + boolean endpoint = session.getAttribute(NoUserInSessionFilter.ENDPOINT_REDIRECT_KEY) != null; response.setStatus(302); try { Cookie cookie = new Cookie(DBLoader.getSessionIdKey(), request.getSession().getId()); //cookie.setPath("/dev"); response.addCookie(cookie); - if(redirect == null) { - response.sendRedirect(socialData.getProperty("redirect")); + if(useCustom) { + response.setHeader("redirect", customRedirect); + response.sendError(302, "Need to redirect to " + customRedirect); + } else if(endpoint) { + String redirectUrl = session.getAttribute(NoUserInSessionFilter.ENDPOINT_REDIRECT_KEY) + ""; + response.setHeader("redirect", redirectUrl); + response.sendError(302, "Need to redirect to " + redirectUrl); } else { - response.sendRedirect(redirect); + response.sendRedirect(socialData.getProperty("redirect")); } } catch (IOException e) { e.printStackTrace(); } } + /** + * Set the information in the JSON return after logging in + * @param token + * @param ret + */ + private void setAccessTokenDetails(AccessToken token, Map ret) { + ret.put("name", token.getName()); + ret.put("email", token.getEmail()); + ret.put("type", token.getToken_type()); + } + ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// diff --git a/src/prerna/web/conf/NoUserInSessionFilter.java b/src/prerna/web/conf/NoUserInSessionFilter.java index f3e6f4549..0bb0623ab 100644 --- a/src/prerna/web/conf/NoUserInSessionFilter.java +++ b/src/prerna/web/conf/NoUserInSessionFilter.java @@ -26,11 +26,18 @@ import prerna.auth.InsightToken; import prerna.auth.User; import prerna.auth.utils.AbstractSecurityUtils; +import prerna.semoss.web.services.local.UserResource; import prerna.util.Constants; import prerna.web.requests.MultiReadHttpServletRequest; public class NoUserInSessionFilter implements Filter { + // this is so if you are making a direct BE request + // after you sign in + // we can redirect you back to the original call + // instead of taking you to the base SemossWeb URL + public static final String ENDPOINT_REDIRECT_KEY = "ENDPOINT_REDIRECT_KEY"; + public static final String MONOLITH_ROUTE = "MONOLITH_ROUTE"; public static final String MONOLITH_PREFIX = "MONOLITH_PREFIX"; @@ -144,10 +151,10 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 else { setInvalidEntryRedirect(context, arg0, arg1, LOGIN); - // invalidate the session if necessary - if(session != null) { - session.invalidate(); - } +// // invalidate the session if necessary +// if(session != null) { +// session.invalidate(); +// } return; } } @@ -245,11 +252,17 @@ private void setInvalidEntryRedirect(ServletContext context, ServletRequest arg0 // if no referrer // then a person hit the endpoint directly if(redirectUrl == null) { + ((HttpServletRequest) arg0).getSession(true).setAttribute(ENDPOINT_REDIRECT_KEY, fullUrl); // this will be the deployment name of the app - String contextPath = context.getContextPath(); - redirectUrl = fullUrl.substring(0, fullUrl.indexOf(contextPath) + contextPath.length()) + NO_USER_HTML; + String loginRedirect = UserResource.getLoginRedirect(); ((HttpServletResponse) arg1).setStatus(302); - ((HttpServletResponse) arg1).sendRedirect(redirectUrl); + if(loginRedirect != null) { + ((HttpServletResponse) arg1).sendRedirect(loginRedirect); + } else { + String contextPath = context.getContextPath(); + redirectUrl = fullUrl.substring(0, fullUrl.indexOf(contextPath) + contextPath.length()) + NO_USER_HTML; + ((HttpServletResponse) arg1).sendRedirect(redirectUrl); + } } else { redirectUrl = redirectUrl + "#!/" + endpoint; ((HttpServletResponse) arg1).setHeader("redirect", redirectUrl); From 3a738406d1cc31def7e5eee6fe6f51482c8f9308 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 29 Oct 2019 12:16:37 +0000 Subject: [PATCH 0503/1906] UPDATE ::: Adding a forced redirection since FE has no way to know of the redirect occurring in the pop up git-svn-id: svn://107.170.10.188:8080/Monolith/dev@35692 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: f2810ed79e620fc2798dd4025826329da27bde9e --- src/prerna/web/conf/NoUserInSessionFilter.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/prerna/web/conf/NoUserInSessionFilter.java b/src/prerna/web/conf/NoUserInSessionFilter.java index 0bb0623ab..fc8295aed 100644 --- a/src/prerna/web/conf/NoUserInSessionFilter.java +++ b/src/prerna/web/conf/NoUserInSessionFilter.java @@ -21,6 +21,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; +import javax.ws.rs.core.Context; import prerna.auth.AuthProvider; import prerna.auth.InsightToken; @@ -159,6 +160,18 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 } } + // is the user logging in, but was previously at a different page? + // this is because even if i set the redirect URL in the + // {@link UserResource#setMainPageRedirect(@Context HttpServletRequest request, @Context HttpServletResponse response)} + // is sent to the pop-up for OAuth login + String endpointRedirectUrl = (String) session.getAttribute(NoUserInSessionFilter.ENDPOINT_REDIRECT_KEY); + if(endpointRedirectUrl != null && !endpointRedirectUrl.isEmpty()) { + ((HttpServletResponse) arg1).setHeader("redirect", endpointRedirectUrl); + ((HttpServletResponse) arg1).sendError(302, "Need to redirect to " + endpointRedirectUrl); + session.removeAttribute(NoUserInSessionFilter.ENDPOINT_REDIRECT_KEY); + return; + } + // so we have a user // let us look at the cookies // are we redirecting based on the above From fcf790ab3d34ef5f002964657b5f17f083f262fe Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 29 Oct 2019 12:17:56 +0000 Subject: [PATCH 0504/1906] UPDATE ::: Minor import cleanup + correct parameter ordering in comments git-svn-id: svn://107.170.10.188:8080/Monolith/dev@35693 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 6f00bd5d7408ced32ead8e9fb7deb7fa42e9073a --- src/prerna/web/conf/NoUserInSessionFilter.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/prerna/web/conf/NoUserInSessionFilter.java b/src/prerna/web/conf/NoUserInSessionFilter.java index fc8295aed..08b20c387 100644 --- a/src/prerna/web/conf/NoUserInSessionFilter.java +++ b/src/prerna/web/conf/NoUserInSessionFilter.java @@ -21,7 +21,6 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; -import javax.ws.rs.core.Context; import prerna.auth.AuthProvider; import prerna.auth.InsightToken; From e387ccf3a8fd9a71e65112910d990db825281589 Mon Sep 17 00:00:00 2001 From: kunalppatel9 Date: Thu, 31 Oct 2019 20:56:57 +0000 Subject: [PATCH 0505/1906] UPDATE ::: Adding sonar push on schedule git-svn-id: svn://107.170.10.188:8080/Monolith/dev@35765 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: d6525f52f441a69684e1e08ca91e4de3c07e12b3 --- .gitlab-ci.yml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7013416a9..f4c3fff12 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -50,6 +50,32 @@ build_monolith_dev: paths: - target/monolith-${VERSION}-SNAPSHOT.war +# Does not push to maven central +# Pushes to sonar +build_monolith_sonar: + stage: build_monolith + # See https://docs.gitlab.com/ee/ci/yaml/#only-and-except-simplified + only: + refs: + - schedules + except: + variables: + - $RELEASE == "TRUE" + script: + - apt-get update + - apt-get install -y openjfx + # So that the most up-to-date artifacts are pulled + - rm -rf .m2/repository/org/semoss + - mvn $MAVEN_CLI_OPTS clean install -Dci.version=${VERSION}-SNAPSHOT + - mvn sonar:sonar -Dsonar.projectKey=$PROJECT_KEY -Dsonar.projectVersion=${VERSION}-SNAPSHOT -Dsonar.host.url=$HOST_URL -Dsonar.login=$LOGIN_KEY + # So that the cache takes up less space + - rm -rf .m2/repository/org/semoss + artifacts: + paths: + - target/monolith-${VERSION}-SNAPSHOT.war + - target/sonar + + # Pushes to maven central build_monolith_deploy: stage: build_monolith From 26f91dcf8bccaddfa9301fd41b4fa4f108b3237f Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 12 Nov 2019 15:41:57 +0000 Subject: [PATCH 0506/1906] UPDATE ::: Pushing to newer version of Jep git-svn-id: svn://107.170.10.188:8080/Monolith/dev@35930 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: a4a924ab675bf596eeb8c98c8dd0a8ac57aa6773 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4a4205036..5eb3c4203 100644 --- a/pom.xml +++ b/pom.xml @@ -2736,7 +2736,7 @@ black.ninia jep - 3.7.0 + 3.9.0 From 4e584cac8cdbdfcc1a02e4571717fa0b77db1ae8 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 12 Nov 2019 17:57:46 +0000 Subject: [PATCH 0507/1906] UPDATE ::: Adding the ability to tell the FE which default scripting language to use in SEMOSS. (i.e. to shift to PYTHON or R when moving to clean or analytics menu from a grid or native frame) git-svn-id: svn://107.170.10.188:8080/Monolith/dev@35944 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 52c5ea38265e32179f44d4c7d0b21ba454c523a8 --- .../config/ServerConfigurationResource.java | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/prerna/semoss/web/services/config/ServerConfigurationResource.java b/src/prerna/semoss/web/services/config/ServerConfigurationResource.java index 02b12b8dc..e3c23bd0b 100644 --- a/src/prerna/semoss/web/services/config/ServerConfigurationResource.java +++ b/src/prerna/semoss/web/services/config/ServerConfigurationResource.java @@ -100,16 +100,17 @@ private static Map getConfig(@Context HttpServletRequest request // send the default frame type String defaultFrameType = DIHelper.getInstance().getProperty(Constants.DEFAULT_FRAME_TYPE); - if(defaultFrameType != null) { - try { - config.put("defaultFrameType", defaultFrameType); - } catch(Exception e) { - // ignore - } - } else { - config.put("defaultFrameType", "GRID"); + if(defaultFrameType == null) { + defaultFrameType = "GRID"; } + config.put("defaultFrameType", defaultFrameType); + String defaultScriptingLanguage = DIHelper.getInstance().getProperty(Constants.DEFAULT_SCRIPTING_LANGUAGE); + if(defaultScriptingLanguage == null) { + defaultScriptingLanguage = "R"; + } + config.put("defaultScriptingLanguage", defaultScriptingLanguage); + // local mode boolean localMode = false; String localModeStr = DIHelper.getInstance().getProperty(Constants.LOCAL_DEPLOYMENT); From 33d333cc405d1342518d57b355c1d5455dc8f421 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 15 Nov 2019 18:16:01 +0000 Subject: [PATCH 0508/1906] UPDATE ::: Adding placeholder/scaffold for IAS Authentication git-svn-id: svn://107.170.10.188:8080/Monolith/dev@36013 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: af2929494bf159f8e849f64b24ba55b5988446f5 --- src/prerna/web/conf/IASFilter.java | 48 ++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 src/prerna/web/conf/IASFilter.java diff --git a/src/prerna/web/conf/IASFilter.java b/src/prerna/web/conf/IASFilter.java new file mode 100644 index 000000000..3fcfb21da --- /dev/null +++ b/src/prerna/web/conf/IASFilter.java @@ -0,0 +1,48 @@ +package prerna.web.conf; + +import java.io.IOException; +import java.util.Enumeration; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; + +import org.apache.log4j.LogManager; +import org.apache.log4j.Logger; + +public class IASFilter implements Filter { + + private static final Logger LOGGER = LogManager.getLogger(IASFilter.class.getName()); + + @Override + public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { + try { + Enumeration headers = ((HttpServletRequest)arg0).getHeaderNames(); + while (headers.hasMoreElements()) { + String headerValue = headers.nextElement(); + LOGGER.info("IAS HEADER= " + headerValue + " ::: VALUE= " + ((HttpServletRequest)arg0).getHeader(headerValue)); + } + } catch(Exception e) { + e.printStackTrace(); + } + + arg2.doFilter(arg0, arg1); + } + + @Override + public void destroy() { + // TODO Auto-generated method stub + + } + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + // TODO Auto-generated method stub + + } + +} From c8bd6a671810cffd90952d04e83ca9cf132315f0 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 18 Nov 2019 19:55:28 +0000 Subject: [PATCH 0509/1906] UPDATE ::: Adding logging to determine if iAS is setup properly git-svn-id: svn://107.170.10.188:8080/Monolith/dev@36032 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 4f214fbb0420cccb5911fd426a6991e987639007 --- src/prerna/web/conf/IASFilter.java | 62 ++++++++++++++++++++++++++---- 1 file changed, 54 insertions(+), 8 deletions(-) diff --git a/src/prerna/web/conf/IASFilter.java b/src/prerna/web/conf/IASFilter.java index 3fcfb21da..b7a099256 100644 --- a/src/prerna/web/conf/IASFilter.java +++ b/src/prerna/web/conf/IASFilter.java @@ -1,7 +1,6 @@ package prerna.web.conf; import java.io.IOException; -import java.util.Enumeration; import javax.servlet.Filter; import javax.servlet.FilterChain; @@ -10,24 +9,71 @@ import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; import org.apache.log4j.LogManager; import org.apache.log4j.Logger; +import prerna.auth.AccessToken; +import prerna.auth.AuthProvider; +import prerna.auth.User; +import prerna.auth.utils.SecurityUpdateUtils; +import prerna.util.Constants; + public class IASFilter implements Filter { + private static final String DOD_ID = "DOD_EDI_PN_ID"; + private static final String EMAIL = "PRI_EMAIL"; + private static final String ID = "UNIQUE_ID"; + private static final Logger LOGGER = LogManager.getLogger(IASFilter.class.getName()); @Override public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { - try { - Enumeration headers = ((HttpServletRequest)arg0).getHeaderNames(); - while (headers.hasMoreElements()) { - String headerValue = headers.nextElement(); - LOGGER.info("IAS HEADER= " + headerValue + " ::: VALUE= " + ((HttpServletRequest)arg0).getHeader(headerValue)); + HttpSession session = ((HttpServletRequest)arg0).getSession(true); + + User user = (User) session.getAttribute(Constants.SESSION_USER); + if(user == null) { + user = new User(); + + String dodId = ((HttpServletRequest)arg0).getHeader(DOD_ID); + String email = ((HttpServletRequest)arg0).getHeader(EMAIL); + String id = ((HttpServletRequest)arg0).getHeader(ID); + + boolean valid = true; + if(dodId == null || email == null || id == null + || dodId.isEmpty() || email.isEmpty() || id.isEmpty() ) { + + LOGGER.info("REQUEST COMING WITH NO USER"); + LOGGER.info("REQUEST COMING WITH NO USER"); + LOGGER.info("REQUEST COMING WITH NO USER"); + LOGGER.info("REQUEST COMING WITH NO USER"); + LOGGER.info("REQUEST COMING WITH NO USER"); + valid = false; + } + + if(valid) { + AccessToken token = new AccessToken(); + token.setProvider(AuthProvider.CAC); + token.setId(id); + token.setEmail(email); + token.setName(email); + + SecurityUpdateUtils.addOAuthUser(token); + + user.setAccessToken(token); + session.setAttribute(Constants.SESSION_USER, user); + + LOGGER.info("NEW SESSION - USER ADDED WITH ID = " + id); + LOGGER.info("NEW SESSION - USER ADDED WITH ID = " + id); + LOGGER.info("NEW SESSION - USER ADDED WITH ID = " + id); + LOGGER.info("NEW SESSION - USER ADDED WITH ID = " + id); } - } catch(Exception e) { - e.printStackTrace(); + } else { + LOGGER.info("EXISTING SESSION WITH USER ALREADY PRESENT"); + LOGGER.info("EXISTING SESSION WITH USER ALREADY PRESENT"); + LOGGER.info("EXISTING SESSION WITH USER ALREADY PRESENT"); + LOGGER.info("EXISTING SESSION WITH USER ALREADY PRESENT"); } arg2.doFilter(arg0, arg1); From 3f247653c69b59e719c70c207fb753fcaa254c3f Mon Sep 17 00:00:00 2001 From: rramirezjimenez Date: Wed, 4 Dec 2019 15:14:08 +0000 Subject: [PATCH 0510/1906] UPDATE ::: Pom changes for neo4j jdbc connection git-svn-id: svn://107.170.10.188:8080/Monolith/dev@36201 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 8235300873834f20ecaa455c57fd13a394bcb32e --- pom.xml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/pom.xml b/pom.xml index 5eb3c4203..2416c0e24 100644 --- a/pom.xml +++ b/pom.xml @@ -2528,6 +2528,17 @@ neo4j-tinkerpop-api-impl 0.9-3.4.0 + + + org.neo4j.driver + neo4j-java-driver + 1.7.5 + + + org.neo4j + neo4j-jdbc-bolt + 3.4.0 + commons-validator From b58fb8b2c48bf28858354b5d55ec1fcf171bb0f5 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 4 Dec 2019 16:27:11 +0000 Subject: [PATCH 0511/1906] BUGFIX ::: Sending app and images when security is not enabled git-svn-id: svn://107.170.10.188:8080/Monolith/dev@36207 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 2a35a1043cdbc857348eb80fde1dcb637fba6c7a --- .../web/services/local/AppResource.java | 69 ++++++++++--------- 1 file changed, 35 insertions(+), 34 deletions(-) diff --git a/src/prerna/semoss/web/services/local/AppResource.java b/src/prerna/semoss/web/services/local/AppResource.java index e1127b814..f6ca8e1d6 100644 --- a/src/prerna/semoss/web/services/local/AppResource.java +++ b/src/prerna/semoss/web/services/local/AppResource.java @@ -231,20 +231,22 @@ public Response getAppFile(@Context final Request coreRequest, @Context HttpServ @Path("/appImage/download") @Produces({MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_SVG_XML}) public Response downloadAppImage(@Context final Request coreRequest, @Context HttpServletRequest request, @PathParam("appId") String appId) { - User user = null; - try { - user = ResourceUtility.getUser(request); - } catch (IllegalAccessException e) { - Map errorMap = new HashMap(); - errorMap.put("error", "User session is invalid"); - return WebUtility.getResponse(errorMap, 401); - } - try { - canAccessApp(user, appId); - } catch (IllegalAccessException e) { - Map errorMap = new HashMap(); - errorMap.put("error", e.getMessage()); - return WebUtility.getResponse(errorMap, 401); + if(AbstractSecurityUtils.securityEnabled()) { + User user = null; + try { + user = ResourceUtility.getUser(request); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap(); + errorMap.put("error", "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + try { + canAccessApp(user, appId); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap(); + errorMap.put("error", e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } } File exportFile = getAppImageFile(appId); @@ -314,28 +316,27 @@ protected File getAppImageFile(String app) { @Path("/insightImage/download") @Produces({MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_SVG_XML}) public Response downloadInsightImage(@Context final Request coreRequest, @Context HttpServletRequest request, @PathParam("appId") String appId, @QueryParam("rdbmsId") String id, @QueryParam("params") String params) { - User user = null; - try { - user = ResourceUtility.getUser(request); - } catch (IllegalAccessException e) { - Map errorMap = new HashMap(); - errorMap.put("error", "User session is invalid"); - return WebUtility.getResponse(errorMap, 401); - } - try { - canAccessInsight(user, appId, id); - } catch (IllegalAccessException e) { - Map errorMap = new HashMap(); - errorMap.put("error", e.getMessage()); - return WebUtility.getResponse(errorMap, 401); - } - - boolean securityEnabled = AbstractSecurityUtils.securityEnabled(); String sessionId = null; - if(securityEnabled){ + if(AbstractSecurityUtils.securityEnabled()) { + User user = null; + try { + user = ResourceUtility.getUser(request); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap(); + errorMap.put("error", "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + try { + canAccessInsight(user, appId, id); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap(); + errorMap.put("error", e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + sessionId = request.getSession(false).getId(); - } - + } + File exportFile = getInsightImageFile(appId, id, request.getHeader("Referer"), params, sessionId); if(exportFile != null && exportFile.exists()) { String exportName = appId + "_Image." + FilenameUtils.getExtension(exportFile.getAbsolutePath()); From eb44a1a8db797384cffefebf1c2d12257c6a7157 Mon Sep 17 00:00:00 2001 From: kunalppatel9 Date: Wed, 11 Dec 2019 19:48:08 +0000 Subject: [PATCH 0512/1906] UPDATE ::: Adding AWS jar git-svn-id: svn://107.170.10.188:8080/Monolith/dev@36339 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: ce8cc2f6362194a568f7f0b2776ee8973af8fb29 --- pom.xml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2416c0e24..1a4998118 100644 --- a/pom.xml +++ b/pom.xml @@ -3004,7 +3004,12 @@ ru.yandex.clickhouse clickhouse-jdbc 0.2 - + + + com.amazonaws + aws-java-sdk + 1.11.690 + me.xdrop fuzzywuzzy From 12ec2f79347aa82b2e0f4d6c55de387f4959d627 Mon Sep 17 00:00:00 2001 From: kunalppatel9 Date: Fri, 13 Dec 2019 00:54:06 +0000 Subject: [PATCH 0513/1906] ADDED ::: Adding Athena driver git-svn-id: svn://107.170.10.188:8080/Monolith/dev@36375 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 3e240f87349d6804e21b68ad3cc4fba06fb609d4 --- pom.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pom.xml b/pom.xml index 1a4998118..4211e4fdc 100644 --- a/pom.xml +++ b/pom.xml @@ -3010,6 +3010,11 @@ aws-java-sdk 1.11.690 + + com.syncron.amazonaws + simba-athena-jdbc-driver + 2.0.2 + me.xdrop fuzzywuzzy From 30e090726d5514b35db9b1131045a57299f904bc Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 17 Dec 2019 15:09:17 +0000 Subject: [PATCH 0514/1906] UPDATE ::: Updating new version of postgres drivers git-svn-id: svn://107.170.10.188:8080/Monolith/dev@36429 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 7f485be57f9d8f4e80c3674e8fb453711310ba3f --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 4211e4fdc..5b7d03338 100644 --- a/pom.xml +++ b/pom.xml @@ -2502,7 +2502,7 @@ org.postgresql postgresql - 42.1.1 + 42.2.8 + + + + + + + + + + + + + + + + + + + diff --git a/src/prerna/semoss/web/services/config/ServerConfigurationResource.java b/src/prerna/semoss/web/services/config/ServerConfigurationResource.java index e3c23bd0b..f5e535141 100644 --- a/src/prerna/semoss/web/services/config/ServerConfigurationResource.java +++ b/src/prerna/semoss/web/services/config/ServerConfigurationResource.java @@ -80,6 +80,10 @@ private static Map getConfig(@Context HttpServletRequest request } config.put("adminSetPublic", adminSetPublic); + // return a boolean if we want to use a dedicated logout page + // instead of redirecting to the login page + config.put("useLogoutPage", DBLoader.useLogoutPage()); + // max file transfer size String fileTransferMax = DIHelper.getInstance().getProperty(Constants.FILE_TRANSFER_LIMIT); if(fileTransferMax != null) { diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index 3bcbc69ce..ac096d56b 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -440,6 +440,8 @@ public Response downloadFile(@QueryParam("insightId") String insightId, @QueryPa return WebUtility.getResponse(errorMap, 400); } + // TODO: put file name cleanup + // cannot have things like "," in the name for the attachment String exportName = FilenameUtils.getName(filePath); return Response.status(200).entity(exportFile).header("Content-Disposition", "attachment; filename=" + exportName).build(); } diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index 7dcbbc33d..dc247593e 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -276,9 +276,25 @@ public Void call() throws Exception { // so i will redirect you response.setStatus(302); String redirectUrl = request.getHeader("referer"); - redirectUrl = redirectUrl + "#!/login"; - response.setHeader("redirect", redirectUrl); - response.sendError(302, "Need to redirect to " + redirectUrl); + if(DBLoader.useLogoutPage()) { + String scheme = request.getScheme(); // http + String serverName = request.getServerName(); // hostname.com + int serverPort = request.getServerPort(); // 8080 + String contextPath = request.getContextPath(); // /Monolith + + redirectUrl = ""; + redirectUrl += scheme + "://" + serverName; + if (serverPort != 80 && serverPort != 443) { + redirectUrl += ":" + serverPort; + } + redirectUrl += contextPath + "/logout/"; + response.setHeader("redirect", redirectUrl); + response.sendError(302, "Need to redirect to " + redirectUrl); + } else { + redirectUrl = redirectUrl + "#!/login"; + response.setHeader("redirect", redirectUrl); + response.sendError(302, "Need to redirect to " + redirectUrl); + } // remove the cookie from the browser // for the session id diff --git a/src/prerna/web/conf/DBLoader.java b/src/prerna/web/conf/DBLoader.java index 82f582bb5..f2ba6c1c9 100644 --- a/src/prerna/web/conf/DBLoader.java +++ b/src/prerna/web/conf/DBLoader.java @@ -63,7 +63,8 @@ public class DBLoader implements ServletContextListener { private static final Logger LOGGER = LogManager.getLogger(DBLoader.class.getName()); private static final String RDFMAP = "RDF-MAP"; private static String SESSION_ID_KEY = "JSESSIONID"; - + private static boolean USE_LOGOUT_PAGE = false; + // keep track of all the watcher threads to kill private static List watcherList = new Vector(); @@ -102,7 +103,15 @@ public void contextInitialized(ServletContextEvent arg0) { anonymousUsersUploadData = "false"; } context.setInitParameter(Constants.ANONYMOUS_USER_UPLOAD_DATA, anonymousUsersUploadData); - + + // see if we redirect to logout page or back to login screen + String useLogoutPage = context.getInitParameter(Constants.USE_LOGOUT_PAGE); + if(useLogoutPage == null) { + useLogoutPage = "false"; + } + context.setInitParameter(Constants.USE_LOGOUT_PAGE, useLogoutPage); + DBLoader.USE_LOGOUT_PAGE = Boolean.parseBoolean(useLogoutPage); + // get the session id key if(context.getSessionCookieConfig() != null) { SessionCookieConfig cookieConfig = context.getSessionCookieConfig(); @@ -134,6 +143,7 @@ public void contextInitialized(ServletContextEvent arg0) { DIHelper.getInstance().setLocalProperty(Constants.ADMIN_SET_PUBLISHER, adminSetPublisher); DIHelper.getInstance().setLocalProperty(Constants.ANONYMOUS_USER_ALLOWED, anonymousUsersEnabled); DIHelper.getInstance().setLocalProperty(Constants.ANONYMOUS_USER_UPLOAD_DATA, anonymousUsersUploadData); + DIHelper.getInstance().setLocalProperty(Constants.USE_LOGOUT_PAGE, useLogoutPage); DIHelper.getInstance().setLocalProperty(Constants.SESSION_ID_KEY, SESSION_ID_KEY); //Load empty engine list into DIHelper, then load engines from db folder @@ -271,4 +281,13 @@ public void contextDestroyed(ServletContextEvent arg0) { public static String getSessionIdKey() { return DBLoader.SESSION_ID_KEY; } + + /** + * Get if we should redirect to a dedicated logout page + * Or back to the login page + * @return + */ + public static boolean useLogoutPage() { + return DBLoader.USE_LOGOUT_PAGE; + } } diff --git a/src/prerna/web/conf/NoUserInSessionFilter.java b/src/prerna/web/conf/NoUserInSessionFilter.java index 08b20c387..df536c7ac 100644 --- a/src/prerna/web/conf/NoUserInSessionFilter.java +++ b/src/prerna/web/conf/NoUserInSessionFilter.java @@ -151,10 +151,10 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 else { setInvalidEntryRedirect(context, arg0, arg1, LOGIN); -// // invalidate the session if necessary -// if(session != null) { -// session.invalidate(); -// } + // invalidate the session if necessary + if(session != null) { + session.invalidate(); + } return; } } From f7f24929af8f05309df6f682e36f1e1144314f1b Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 11 Feb 2020 01:10:32 +0000 Subject: [PATCH 0522/1906] UPDATE ::: Adding logout page to the list of files to include in the war git-svn-id: svn://107.170.10.188:8080/Monolith/dev@37139 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 2de27dac433216d81f56924734f93c6024f3f1ab --- pom.xml | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/pom.xml b/pom.xml index 5b7d03338..e5e18064a 100644 --- a/pom.xml +++ b/pom.xml @@ -124,10 +124,11 @@ true ${basedir}/WebContent - setAdmin/**, - startUpFail/**, + logout/**, noUserFail/**, + setAdmin/**, share/**, + startUpFail/**, %regex[WEB-INF/lib/(?!semoss-${ci.version}).*.jar] @@ -917,17 +918,6 @@ compiler 0.9.2 - - com.h2database - h2 - 1.4.185 - - - * - * - - - com.github.stephenc.high-scale-lib @@ -1958,7 +1948,7 @@ com.univocity univocity-parsers - 2.4.1 + 2.8.4 * From c9ff99f90b44729d9bc893203cd2542273ea5751 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 11 Feb 2020 16:08:14 +0000 Subject: [PATCH 0523/1906] UPDATE ::: Adding invalidate session GET request git-svn-id: svn://107.170.10.188:8080/Monolith/dev@37146 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 2ff19b4940c31b368cb828bbdc466dd2f18340d6 --- .../semoss/web/services/local/NameServer.java | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index ac096d56b..a75ce436c 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -111,6 +111,7 @@ import prerna.util.Utility; import prerna.util.gson.GsonUtility; import prerna.util.insight.InsightUtility; +import prerna.web.conf.DBLoader; import prerna.web.conf.SessionCounter; import prerna.web.services.util.ResponseHashSingleton; import prerna.web.services.util.SemossExecutorSingleton; @@ -261,6 +262,43 @@ public Response cancelCleanSession(@Context HttpServletRequest request) { return WebUtility.getResponse(ret, 200); } + @GET + @Path("/invalidateSession") + @Produces("application/json;charset=utf-8") + public void invalidateSession(@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException { + String redirectUrl = request.getHeader("referer"); + response.setStatus(302); + + HttpSession session = request.getSession(false); + if(session == null) { + // redirect to the login page + redirectUrl = redirectUrl + "#!/login"; + response.setHeader("redirect", redirectUrl); + response.sendError(302, "Need to redirect to " + redirectUrl); + } else { + // redirect to login/logout page + if(DBLoader.useLogoutPage()) { + String scheme = request.getScheme(); // http + String serverName = request.getServerName(); // hostname.com + int serverPort = request.getServerPort(); // 8080 + String contextPath = request.getContextPath(); // /Monolith + + redirectUrl = ""; + redirectUrl += scheme + "://" + serverName; + if (serverPort != 80 && serverPort != 443) { + redirectUrl += ":" + serverPort; + } + redirectUrl += contextPath + "/logout/"; + response.setHeader("redirect", redirectUrl); + response.sendError(302, "Need to redirect to " + redirectUrl); + } else { + redirectUrl = redirectUrl + "#!/login"; + response.setHeader("redirect", redirectUrl); + response.sendError(302, "Need to redirect to " + redirectUrl); + } + } + } + @GET @Path("/insights") @Produces("application/json;charset=utf-8") From 488fd2691a5f2f1dd21691afc1507c7fb293eea8 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 11 Feb 2020 16:13:31 +0000 Subject: [PATCH 0524/1906] UPDATE ::: Adding session resource UDPATE ::: Adding request to invalidate the session when the FE timer times out UPDATE ::: Moving session requests to the session resource git-svn-id: svn://107.170.10.188:8080/Monolith/dev@37148 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 2597e88921ce83657bc9c063ee4824b0fe685b2a --- .../semoss/web/app/MonolithApplication.java | 2 + .../semoss/web/services/local/NameServer.java | 196 ---------------- .../web/services/local/SessionResource.java | 221 ++++++++++++++++++ 3 files changed, 223 insertions(+), 196 deletions(-) create mode 100644 src/prerna/semoss/web/services/local/SessionResource.java diff --git a/src/prerna/semoss/web/app/MonolithApplication.java b/src/prerna/semoss/web/app/MonolithApplication.java index 1ff5fc95c..08d807afb 100644 --- a/src/prerna/semoss/web/app/MonolithApplication.java +++ b/src/prerna/semoss/web/app/MonolithApplication.java @@ -39,6 +39,7 @@ import prerna.semoss.web.services.local.AuthorizationResource; import prerna.semoss.web.services.local.ExecuteInsightResource; import prerna.semoss.web.services.local.NameServer; +import prerna.semoss.web.services.local.SessionResource; import prerna.semoss.web.services.local.ShareInsightResource; import prerna.semoss.web.services.local.ThemeResource; import prerna.semoss.web.services.local.UserResource; @@ -56,6 +57,7 @@ public MonolithApplication() { singletons.add(new UserResource()); singletons.add(new NameServer()); singletons.add(new AppResource()); + singletons.add(new SessionResource()); // authorization resources singletons.add(new AuthorizationResource()); singletons.add(new AppAuthorizationResource()); diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index a75ce436c..7e6d1e0bd 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -34,14 +34,11 @@ import java.io.PrintStream; import java.net.URLEncoder; import java.util.ArrayList; -import java.util.Date; import java.util.Enumeration; import java.util.HashMap; -import java.util.HashSet; import java.util.Hashtable; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.UUID; import javax.servlet.ServletContext; @@ -71,8 +68,6 @@ import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; import org.jsoup.Jsoup; import com.google.gson.Gson; @@ -80,7 +75,6 @@ import prerna.auth.User; import prerna.auth.utils.AbstractSecurityUtils; -import prerna.auth.utils.SecurityAdminUtils; import prerna.auth.utils.SecurityAppUtils; import prerna.auth.utils.SecurityInsightUtils; import prerna.auth.utils.SecurityQueryUtils; @@ -110,9 +104,6 @@ import prerna.util.PlaySheetRDFMapBasedEnum; import prerna.util.Utility; import prerna.util.gson.GsonUtility; -import prerna.util.insight.InsightUtility; -import prerna.web.conf.DBLoader; -import prerna.web.conf.SessionCounter; import prerna.web.services.util.ResponseHashSingleton; import prerna.web.services.util.SemossExecutorSingleton; import prerna.web.services.util.SemossThread; @@ -124,198 +115,11 @@ public class NameServer { // get the directory separator protected static final String DIR_SEPARATOR = java.nio.file.FileSystems.getDefault().getSeparator(); - private static final Logger LOGGER = LogManager.getLogger(NameServer.class.getName()); - private static final String CANCEL_INVALIDATION = "cancelInvalidation"; - private Object lock = new Object(); - @Context protected ServletContext context; //////////////////////////////////////////////////////////////////////////////// - @GET - @Path("/active") - @Produces("application/json;charset=utf-8") - public Response getActiveSessions(@Context HttpServletRequest request) { - if(AbstractSecurityUtils.securityEnabled()) { - User user; - try { - user = ResourceUtility.getUser(request); - } catch (IllegalAccessException e) { - Map errorMap = new HashMap(); - errorMap.put("error", "User session is invalid"); - return WebUtility.getResponse(errorMap, 401); - } - if(!SecurityAdminUtils.userIsAdmin(user)) { - Map errorMap = new HashMap(); - errorMap.put("error", "User is not an admin"); - return WebUtility.getResponse(errorMap, 401); - } - } - - Map ret = new HashMap(); - ret.put("activeSessions", SessionCounter.getActiveSessions()); - return WebUtility.getResponse(ret, 200); - } - - /* - * End points for cleanup of the thread to account for closing/opening - */ - - @POST - @Path("/cleanSession") - @Produces("application/json;charset=utf-8") - public Response cleanSession(@Context HttpServletRequest request) { - // need to compare when this method was called - // to a potential cancellation - Date execTime = new Date(); - - HttpSession session = request.getSession(false); - if(session == null) { - LOGGER.info("Invalid session for cleaning"); - Map ret = new HashMap(); - ret.put("output", "Invalid session"); - return WebUtility.getResponse(ret, 400); - } - LOGGER.info("Start invalidation of session"); - String sessionId = session.getId(); - // clear up insight store - InsightStore inStore = InsightStore.getInstance(); - Set insightIDs = inStore.getInsightIDsForSession(sessionId); - if(insightIDs != null) { - Set copy = new HashSet(insightIDs); - for(String insightId : copy) { - Insight insight = InsightStore.getInstance().get(insightId); - if(insight == null) { - continue; - } - InsightUtility.dropInsight(insight); - } - LOGGER.info("Successfully removed insight information from session"); - - // clear the current session store - insightIDs.removeAll(copy); - } - - // wait 10 seconds - try { - Thread.sleep(10_000); - } catch (InterruptedException e1) { - e1.printStackTrace(); - } - - String output = null; - if(request.isRequestedSessionIdValid()) { - // did the FE at any point cancel this clean? - Date cancelTime = null; - synchronized(lock) { - cancelTime = (Date) session.getAttribute(CANCEL_INVALIDATION); - } - if(cancelTime == null) { - // kill the entire session - LOGGER.info("Invalidating session"); - session.invalidate(); - output = "invalidated"; - } else { - boolean isCancelled = execTime.before(cancelTime); - if(isCancelled) { - LOGGER.info("Cancelled invalidating session"); - output = "cancelled"; - } else { - // kill the entire session - LOGGER.info("Invalidating session"); - session.invalidate(); - output = "invalidated"; - } - } - } else { - // in case during the time this was called - // the session has been invalidated by some other means - // like a logout - LOGGER.info("Session has already been invalidated"); - output = "invalidated"; - } - - Map ret = new HashMap(); - ret.put("output", output); - return WebUtility.getResponse(ret, 200); - } - - @POST - @Path("/cancelCleanSession") - @Produces("application/json;charset=utf-8") - public Response cancelCleanSession(@Context HttpServletRequest request) { - HttpSession session = request.getSession(false); - if(session == null) { - Map ret = new HashMap(); - ret.put("output", "Invalid session"); - return WebUtility.getResponse(ret, 400); - } - LOGGER.info("Cancelling invalidation..."); - Date d = new Date(); - synchronized(lock) { - session.setAttribute(CANCEL_INVALIDATION, d); - } - - Map ret = new HashMap(); - ret.put("output", "cancel"); - return WebUtility.getResponse(ret, 200); - } - - @GET - @Path("/invalidateSession") - @Produces("application/json;charset=utf-8") - public void invalidateSession(@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException { - String redirectUrl = request.getHeader("referer"); - response.setStatus(302); - - HttpSession session = request.getSession(false); - if(session == null) { - // redirect to the login page - redirectUrl = redirectUrl + "#!/login"; - response.setHeader("redirect", redirectUrl); - response.sendError(302, "Need to redirect to " + redirectUrl); - } else { - // redirect to login/logout page - if(DBLoader.useLogoutPage()) { - String scheme = request.getScheme(); // http - String serverName = request.getServerName(); // hostname.com - int serverPort = request.getServerPort(); // 8080 - String contextPath = request.getContextPath(); // /Monolith - - redirectUrl = ""; - redirectUrl += scheme + "://" + serverName; - if (serverPort != 80 && serverPort != 443) { - redirectUrl += ":" + serverPort; - } - redirectUrl += contextPath + "/logout/"; - response.setHeader("redirect", redirectUrl); - response.sendError(302, "Need to redirect to " + redirectUrl); - } else { - redirectUrl = redirectUrl + "#!/login"; - response.setHeader("redirect", redirectUrl); - response.sendError(302, "Need to redirect to " + redirectUrl); - } - } - } - - @GET - @Path("/insights") - @Produces("application/json;charset=utf-8") - public Response getInsights(@Context HttpServletRequest request) { - HttpSession session = request.getSession(false); - if(session == null) { - Map ret = new HashMap(); - ret.put("output", "Invalid session"); - return WebUtility.getResponse(ret, 400); - } - String sessionId = session.getId(); - Set ids = InsightStore.getInstance().getInsightIDsForSession(sessionId); - return WebUtility.getResponse(ids, 200); - } - - //////////////////////////////////////////////////////////////////////////////// - // uploader functionality @Path("/uploadDatabase") public Uploader uploadDatabase(@Context HttpServletRequest request) { diff --git a/src/prerna/semoss/web/services/local/SessionResource.java b/src/prerna/semoss/web/services/local/SessionResource.java new file mode 100644 index 000000000..14d1455ac --- /dev/null +++ b/src/prerna/semoss/web/services/local/SessionResource.java @@ -0,0 +1,221 @@ +package prerna.semoss.web.services.local; + +import java.io.IOException; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.Response; + +import org.apache.log4j.LogManager; +import org.apache.log4j.Logger; + +import prerna.auth.User; +import prerna.auth.utils.AbstractSecurityUtils; +import prerna.auth.utils.SecurityAdminUtils; +import prerna.om.Insight; +import prerna.om.InsightStore; +import prerna.util.insight.InsightUtility; +import prerna.web.conf.DBLoader; +import prerna.web.conf.SessionCounter; +import prerna.web.services.util.WebUtility; + +@Path("/session") +public class SessionResource { + + private static final Logger LOGGER = LogManager.getLogger(SessionResource.class.getName()); + private static final String CANCEL_INVALIDATION = "cancelInvalidation"; + private Object lock = new Object(); + + @GET + @Path("/active") + @Produces("application/json;charset=utf-8") + public Response getActiveSessions(@Context HttpServletRequest request) { + if(AbstractSecurityUtils.securityEnabled()) { + User user; + try { + user = ResourceUtility.getUser(request); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap(); + errorMap.put("error", "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + if(!SecurityAdminUtils.userIsAdmin(user)) { + Map errorMap = new HashMap(); + errorMap.put("error", "User is not an admin"); + return WebUtility.getResponse(errorMap, 401); + } + } + + Map ret = new HashMap(); + ret.put("activeSessions", SessionCounter.getActiveSessions()); + return WebUtility.getResponse(ret, 200); + } + + /* + * End points for cleanup of the thread to account for closing/opening + */ + + @POST + @Path("/cleanSession") + @Produces("application/json;charset=utf-8") + public Response cleanSession(@Context HttpServletRequest request) { + // need to compare when this method was called + // to a potential cancellation + Date execTime = new Date(); + + HttpSession session = request.getSession(false); + if(session == null) { + LOGGER.info("Invalid session for cleaning"); + Map ret = new HashMap(); + ret.put("output", "Invalid session"); + return WebUtility.getResponse(ret, 400); + } + LOGGER.info("Start invalidation of session"); + String sessionId = session.getId(); + // clear up insight store + InsightStore inStore = InsightStore.getInstance(); + Set insightIDs = inStore.getInsightIDsForSession(sessionId); + if(insightIDs != null) { + Set copy = new HashSet(insightIDs); + for(String insightId : copy) { + Insight insight = InsightStore.getInstance().get(insightId); + if(insight == null) { + continue; + } + InsightUtility.dropInsight(insight); + } + LOGGER.info("Successfully removed insight information from session"); + + // clear the current session store + insightIDs.removeAll(copy); + } + + // wait 10 seconds + try { + Thread.sleep(10_000); + } catch (InterruptedException e1) { + e1.printStackTrace(); + } + + String output = null; + if(request.isRequestedSessionIdValid()) { + // did the FE at any point cancel this clean? + Date cancelTime = null; + synchronized(lock) { + cancelTime = (Date) session.getAttribute(CANCEL_INVALIDATION); + } + if(cancelTime == null) { + // kill the entire session + LOGGER.info("Invalidating session"); + session.invalidate(); + output = "invalidated"; + } else { + boolean isCancelled = execTime.before(cancelTime); + if(isCancelled) { + LOGGER.info("Cancelled invalidating session"); + output = "cancelled"; + } else { + // kill the entire session + LOGGER.info("Invalidating session"); + session.invalidate(); + output = "invalidated"; + } + } + } else { + // in case during the time this was called + // the session has been invalidated by some other means + // like a logout + LOGGER.info("Session has already been invalidated"); + output = "invalidated"; + } + + Map ret = new HashMap(); + ret.put("output", output); + return WebUtility.getResponse(ret, 200); + } + + @POST + @Path("/cancelCleanSession") + @Produces("application/json;charset=utf-8") + public Response cancelCleanSession(@Context HttpServletRequest request) { + HttpSession session = request.getSession(false); + if(session == null) { + Map ret = new HashMap(); + ret.put("output", "Invalid session"); + return WebUtility.getResponse(ret, 400); + } + LOGGER.info("Cancelling invalidation..."); + Date d = new Date(); + synchronized(lock) { + session.setAttribute(CANCEL_INVALIDATION, d); + } + + Map ret = new HashMap(); + ret.put("output", "cancel"); + return WebUtility.getResponse(ret, 200); + } + + @GET + @Path("/invalidateSession") + @Produces("application/json;charset=utf-8") + public void invalidateSession(@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException { + String redirectUrl = request.getHeader("referer"); + response.setStatus(302); + + HttpSession session = request.getSession(false); + if(session == null) { + // redirect to the login page + redirectUrl = redirectUrl + "#!/login"; + response.setHeader("redirect", redirectUrl); + response.sendError(302, "Need to redirect to " + redirectUrl); + } else { + // redirect to login/logout page + if(DBLoader.useLogoutPage()) { + String scheme = request.getScheme(); // http + String serverName = request.getServerName(); // hostname.com + int serverPort = request.getServerPort(); // 8080 + String contextPath = request.getContextPath(); // /Monolith + + redirectUrl = ""; + redirectUrl += scheme + "://" + serverName; + if (serverPort != 80 && serverPort != 443) { + redirectUrl += ":" + serverPort; + } + redirectUrl += contextPath + "/logout/"; + response.setHeader("redirect", redirectUrl); + response.sendError(302, "Need to redirect to " + redirectUrl); + } else { + redirectUrl = redirectUrl + "#!/login"; + response.setHeader("redirect", redirectUrl); + response.sendError(302, "Need to redirect to " + redirectUrl); + } + } + } + + @GET + @Path("/insights") + @Produces("application/json;charset=utf-8") + public Response getInsights(@Context HttpServletRequest request) { + HttpSession session = request.getSession(false); + if(session == null) { + Map ret = new HashMap(); + ret.put("output", "Invalid session"); + return WebUtility.getResponse(ret, 400); + } + String sessionId = session.getId(); + Set ids = InsightStore.getInstance().getInsightIDsForSession(sessionId); + return WebUtility.getResponse(ids, 200); + } + +} From 89aa059a55c6956482787bae184c5cfda05fe4be Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 11 Feb 2020 22:36:59 +0000 Subject: [PATCH 0525/1906] UPDATE ::: Modifying to allow the invalidate to occur even if session has actually been killed due to any FE delay and then redirect properly to logout page or login page based on settings git-svn-id: svn://107.170.10.188:8080/Monolith/dev@37154 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 45d8df5575dd923d2d5b55dee8e044beaf9cf4b8 --- .../web/services/local/SessionResource.java | 54 ++++++++++--------- .../web/conf/NoUserInSessionFilter.java | 5 +- 2 files changed, 33 insertions(+), 26 deletions(-) diff --git a/src/prerna/semoss/web/services/local/SessionResource.java b/src/prerna/semoss/web/services/local/SessionResource.java index 14d1455ac..5d540d84b 100644 --- a/src/prerna/semoss/web/services/local/SessionResource.java +++ b/src/prerna/semoss/web/services/local/SessionResource.java @@ -25,6 +25,7 @@ import prerna.auth.utils.SecurityAdminUtils; import prerna.om.Insight; import prerna.om.InsightStore; +import prerna.util.Constants; import prerna.util.insight.InsightUtility; import prerna.web.conf.DBLoader; import prerna.web.conf.SessionCounter; @@ -173,33 +174,38 @@ public void invalidateSession(@Context HttpServletRequest request, @Context Http String redirectUrl = request.getHeader("referer"); response.setStatus(302); - HttpSession session = request.getSession(false); - if(session == null) { - // redirect to the login page - redirectUrl = redirectUrl + "#!/login"; + // redirect to login/logout page + if(DBLoader.useLogoutPage()) { + LOGGER.info("Session ended. Redirect to logout page"); + + String scheme = request.getScheme(); // http + String serverName = request.getServerName(); // hostname.com + int serverPort = request.getServerPort(); // 8080 + String contextPath = request.getContextPath(); // /Monolith + + redirectUrl = ""; + redirectUrl += scheme + "://" + serverName; + if (serverPort != 80 && serverPort != 443) { + redirectUrl += ":" + serverPort; + } + redirectUrl += contextPath + "/logout/"; response.setHeader("redirect", redirectUrl); response.sendError(302, "Need to redirect to " + redirectUrl); } else { - // redirect to login/logout page - if(DBLoader.useLogoutPage()) { - String scheme = request.getScheme(); // http - String serverName = request.getServerName(); // hostname.com - int serverPort = request.getServerPort(); // 8080 - String contextPath = request.getContextPath(); // /Monolith - - redirectUrl = ""; - redirectUrl += scheme + "://" + serverName; - if (serverPort != 80 && serverPort != 443) { - redirectUrl += ":" + serverPort; - } - redirectUrl += contextPath + "/logout/"; - response.setHeader("redirect", redirectUrl); - response.sendError(302, "Need to redirect to " + redirectUrl); - } else { - redirectUrl = redirectUrl + "#!/login"; - response.setHeader("redirect", redirectUrl); - response.sendError(302, "Need to redirect to " + redirectUrl); - } + LOGGER.info("Session ended. Redirect to login page"); + + redirectUrl = redirectUrl + "#!/login"; + response.setHeader("redirect", redirectUrl); + response.sendError(302, "Need to redirect to " + redirectUrl); + } + + HttpSession session = request.getSession(false); + if(session != null) { + LOGGER.info("User is no longer logged in"); + LOGGER.info("Removing user object from session"); + session.removeAttribute(Constants.SESSION_USER); + + session.invalidate(); } } diff --git a/src/prerna/web/conf/NoUserInSessionFilter.java b/src/prerna/web/conf/NoUserInSessionFilter.java index df536c7ac..ec1ff4367 100644 --- a/src/prerna/web/conf/NoUserInSessionFilter.java +++ b/src/prerna/web/conf/NoUserInSessionFilter.java @@ -50,8 +50,9 @@ public class NoUserInSessionFilter implements Filter { // allow these for successful dropping of // sessions when browser is closed/refreshed // these do their own session checks - ignoreDueToFE.add("engine/cleanSession"); - ignoreDueToFE.add("engine/cancelCleanSession"); + ignoreDueToFE.add("session/cleanSession"); + ignoreDueToFE.add("session/cancelCleanSession"); + ignoreDueToFE.add("session/invalidateSession"); ignoreDueToFE.add("config"); ignoreDueToFE.add("auth/logins"); From 9316704515b4895e2f2b58ff9f27f0ca68b0137e Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 12 Feb 2020 01:39:44 +0000 Subject: [PATCH 0526/1906] UPDATE ::: Adding PIVFilter to account for PIV differences compared to CAC cards git-svn-id: svn://107.170.10.188:8080/Monolith/dev@37162 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 2b3c6aa0feef1fa73c59a3bab1f98b518c9d8179 --- WebContent/WEB-INF/web.xml | 27 ++++- src/prerna/auth/PIVReader.java | 179 ++++++++++++++++++++++++++++ src/prerna/web/conf/PIVFilter.java | 182 +++++++++++++++++++++++++++++ 3 files changed, 387 insertions(+), 1 deletion(-) create mode 100644 src/prerna/auth/PIVReader.java create mode 100644 src/prerna/web/conf/PIVFilter.java diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index 6455b2b9c..2388ff755 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -50,6 +50,7 @@ /api/* --> + + --> + + + + com.openhtmltopdf + openhtmltopdf-core + ${openhtml.version} + + + + com.openhtmltopdf + openhtmltopdf-pdfbox + ${openhtml.version} + + + + com.openhtmltopdf + openhtmltopdf-java2d + ${openhtml.version} + + + + com.openhtmltopdf + openhtmltopdf-slf4j + ${openhtml.version} + + + * + * + + + true + + + + com.openhtmltopdf + openhtmltopdf-log4j + ${openhtml.version} + + + * + * + + + true + \ No newline at end of file diff --git a/src/prerna/web/conf/DBLoader.java b/src/prerna/web/conf/DBLoader.java index f2ba6c1c9..420a40c70 100644 --- a/src/prerna/web/conf/DBLoader.java +++ b/src/prerna/web/conf/DBLoader.java @@ -51,8 +51,8 @@ import prerna.om.InsightStore; import prerna.rpa.quartz.SchedulerUtil; import prerna.sablecc2.reactor.frame.r.util.RJavaTranslatorFactory; -import prerna.sablecc2.reactor.utils.ImageCaptureReactor; import prerna.util.AbstractFileWatcher; +import prerna.util.ChromeDriverUtility; import prerna.util.Constants; import prerna.util.DIHelper; import prerna.util.Utility; @@ -161,7 +161,7 @@ public void contextInitialized(ServletContextEvent arg0) { // need to set the path // important for taking the image with security - ImageCaptureReactor.setContextPath(contextPath); + ChromeDriverUtility.setContextPath(contextPath); // if there was an issue starting up the server // we should do it here so that we can redirect the user From c926214bbecaa8d8a34f8ac34666a7558e426b98 Mon Sep 17 00:00:00 2001 From: rramirezjimenez Date: Wed, 12 Feb 2020 20:49:25 +0000 Subject: [PATCH 0528/1906] UPDATE ::: Maven central repo update to https git-svn-id: svn://107.170.10.188:8080/Monolith/dev@37174 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 17de2dedfe3f94340c7263fed7e50bb86bfa5213 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 7d39c495a..8b0a33f97 100644 --- a/pom.xml +++ b/pom.xml @@ -222,7 +222,7 @@ central Maven Repository Switchboard default - http://repo1.maven.org/maven2 + https://repo1.maven.org/maven2 false @@ -230,7 +230,7 @@ public Sonatype's Maven repository - http://oss.sonatype.org/content/groups/public + https://oss.sonatype.org/content/groups/public true From 83f491774822e35e09f72c9bdf24daf6c5346638 Mon Sep 17 00:00:00 2001 From: kunalppatel9 Date: Thu, 13 Feb 2020 20:07:58 +0000 Subject: [PATCH 0529/1906] UPDATE ::: removing unneeded LDS repo git-svn-id: svn://107.170.10.188:8080/Monolith/dev@37192 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 576e3346aa853f92d0ced330201c98a1dbf5de23 --- pom.xml | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/pom.xml b/pom.xml index 8b0a33f97..caa32abe9 100644 --- a/pom.xml +++ b/pom.xml @@ -249,17 +249,6 @@ true - - LDS repository - LDS Maven repository - https://code.lds.org/nexus/content/groups/main-repo - - true - - - false - - boilerpipe http://boilerpipe.googlecode.com/svn/repo/ From a1c6337d2ebbd07cb4b1669e8888b245e0427af8 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 17 Feb 2020 15:04:33 +0000 Subject: [PATCH 0530/1906] UPDATE ::: Allow the application to determine if we want to use an embed url logo and which file to use UPDATE ::: Adding rest endpoint to get the embed url logo - TODO: expose the ability to add app specific and insight specific embed urls git-svn-id: svn://107.170.10.188:8080/Monolith/dev@37217 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 8f3cff9c743ceb59f71a4e526ed3470e99daebc3 --- .../web/services/local/AppResource.java | 93 +++++++++++++++++-- 1 file changed, 87 insertions(+), 6 deletions(-) diff --git a/src/prerna/semoss/web/services/local/AppResource.java b/src/prerna/semoss/web/services/local/AppResource.java index f6ca8e1d6..5206d8a1b 100644 --- a/src/prerna/semoss/web/services/local/AppResource.java +++ b/src/prerna/semoss/web/services/local/AppResource.java @@ -50,6 +50,8 @@ public class AppResource { private static final String DIR_SEPARATOR = java.nio.file.FileSystems.getDefault().getSeparator(); + private static String defaultEmbedLogo = null; + private static boolean noLogo = false; private boolean canAccessApp(User user, String appId) throws IllegalAccessException { if(AbstractSecurityUtils.securityEnabled()) { @@ -152,12 +154,12 @@ public Response getAppLandingPage(@Context final Request coreRequest, @Context H } catch (IOException e) { Map errorMap = new HashMap(); errorMap.put("errorMessage", "Unable to load landing html file"); - return WebUtility.getResponse(errorMap, 400); + return WebUtility.getResponse(errorMap, 404); } } else { Map errorMap = new HashMap(); errorMap.put("errorMessage", "No custom landing page found"); - return WebUtility.getResponse(errorMap, 400); + return WebUtility.getResponse(errorMap, 404); } } @@ -208,15 +210,94 @@ public Response getAppFile(@Context final Request coreRequest, @Context HttpServ } catch (IOException e) { Map errorMap = new HashMap(); errorMap.put("errorMessage", "Unable to load file"); - return WebUtility.getResponse(errorMap, 400); + return WebUtility.getResponse(errorMap, 404); } } else { Map errorMap = new HashMap(); errorMap.put("errorMessage", "No file found"); - return WebUtility.getResponse(errorMap, 400); + return WebUtility.getResponse(errorMap, 404); } } + @GET + @Path("/embedLogo") + @Produces({MediaType.TEXT_HTML, MediaType.APPLICATION_OCTET_STREAM}) + public Response getEmbedUrl(@Context final Request coreRequest, @Context HttpServletRequest request, @PathParam("appId") String appId, @QueryParam("insightId") String insightId) { + User user = null; + if(AbstractSecurityUtils.securityEnabled()) { + try { + user = ResourceUtility.getUser(request); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap(); + errorMap.put("error", "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + try { + canAccessApp(user, appId); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap(); + errorMap.put("error", e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + } + + //TODO: ALLOW APP SPECIFIC EMBED IMAGES + //TODO: ALLOW INSIGHT SPECIFIC EMBED IMAGES + + String embedLogo = getEmbedLogo(); + if(AppResource.noLogo) { + Map errorMap = new HashMap(); + errorMap.put("error", "no defualt logo"); + return WebUtility.getResponse(errorMap, 404); + } + + File file = new File(embedLogo); + if(file != null && file.exists()) { + try { + String contents = new String(Files.readAllBytes(Paths.get(file.getAbsolutePath()))); + + // want to cache this on browser if user has access + CacheControl cc = new CacheControl(); + cc.setMaxAge(1); + cc.setPrivate(true); + EntityTag etag = new EntityTag(Integer.toString(contents.hashCode())); + ResponseBuilder builder = coreRequest.evaluatePreconditions(etag); + + // cached resource did not change + if(builder != null) { + return builder.build(); + } + + return Response.status(200).entity(contents).cacheControl(cc).tag(etag).lastModified(new Date(file.lastModified())).build(); + } catch (IOException e) { + Map errorMap = new HashMap(); + errorMap.put("errorMessage", "Unable to load file"); + return WebUtility.getResponse(errorMap, 400); + } + } else { + Map errorMap = new HashMap(); + errorMap.put("errorMessage", "Default logo file not found"); + return WebUtility.getResponse(errorMap, 404); + } + } + + private static String getEmbedLogo() { + if(AppResource.defaultEmbedLogo == null) { + String embedFileName = DIHelper.getInstance().getProperty(Constants.EMBED_URL_LOGO); + if(embedFileName.equalsIgnoreCase("NONE")) { + AppResource.noLogo = true; + AppResource.defaultEmbedLogo = "NONE"; + } else { + String baseFolder = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER); + String embedFolder = baseFolder + DIR_SEPARATOR + "images" + DIR_SEPARATOR + "embed"; + AppResource.defaultEmbedLogo = embedFolder + DIR_SEPARATOR + embedFileName; + AppResource.noLogo = false; + } + } + return AppResource.defaultEmbedLogo; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -357,8 +438,8 @@ public Response downloadInsightImage(@Context final Request coreRequest, @Contex .cacheControl(cc).tag(etag).lastModified(new Date(exportFile.lastModified())).build(); } else { Map errorMap = new HashMap(); - errorMap.put("errorMessage", "error sending image file"); - return WebUtility.getResponse(errorMap, 400); + errorMap.put("errorMessage", "Error sending image file"); + return WebUtility.getResponse(errorMap, 404); } } From 7767ac369c86fb12a18950b3da4ca2c3ed634dd8 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 20 Feb 2020 14:07:58 +0000 Subject: [PATCH 0531/1906] UPDATE ::: Removing the session details in the correct location git-svn-id: svn://107.170.10.188:8080/Monolith/dev@37272 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 2c4970714d322cc3e639be88f58434279054fcea --- src/prerna/semoss/web/services/local/UserResource.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index dc247593e..37bc5bf18 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -262,6 +262,10 @@ public Void call() throws Exception { SyncUserAppsThread sync = new SyncUserAppsThread(workspaceEngineId, assetEngineId); Thread t = new Thread(sync); t.start(); + + // put the new map for the user space + session.setAttribute(Constants.USER_WORKSPACE_IDS, thisUser.getWorkspaceEngineMap()); + session.setAttribute(Constants.USER_ASSET_IDS, thisUser.getAssetEngineMap()); } } @@ -317,10 +321,6 @@ public Void call() throws Exception { } } - // put the map in the space - session.setAttribute(Constants.USER_WORKSPACE_IDS, thisUser.getWorkspaceEngineMap()); - session.setAttribute(Constants.USER_ASSET_IDS, thisUser.getAssetEngineMap()); - // invalidate the session session.invalidate(); return null; From 9ca3b21c3de7d107241b17bc610058f1909d1e6d Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 20 Feb 2020 17:54:30 +0000 Subject: [PATCH 0532/1906] UPDATE ::: Adding ability to self define the logout URL git-svn-id: svn://107.170.10.188:8080/Monolith/dev@37278 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 855ec1f1645d1493aad76be2d1bda6db33644231 --- WebContent/WEB-INF/web.xml | 5 +++ .../web/services/local/SessionResource.java | 32 ++++++++------ .../web/services/local/UserResource.java | 43 +++++++++++-------- src/prerna/web/conf/DBLoader.java | 21 +++++++-- 4 files changed, 66 insertions(+), 35 deletions(-) diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index 2388ff755..6226f36c5 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -249,6 +249,11 @@ use-logout-page false + + + custom-logout-url + + Location to store uploaded file file-upload diff --git a/src/prerna/semoss/web/services/local/SessionResource.java b/src/prerna/semoss/web/services/local/SessionResource.java index 5d540d84b..c47a5c0d8 100644 --- a/src/prerna/semoss/web/services/local/SessionResource.java +++ b/src/prerna/semoss/web/services/local/SessionResource.java @@ -178,19 +178,25 @@ public void invalidateSession(@Context HttpServletRequest request, @Context Http if(DBLoader.useLogoutPage()) { LOGGER.info("Session ended. Redirect to logout page"); - String scheme = request.getScheme(); // http - String serverName = request.getServerName(); // hostname.com - int serverPort = request.getServerPort(); // 8080 - String contextPath = request.getContextPath(); // /Monolith - - redirectUrl = ""; - redirectUrl += scheme + "://" + serverName; - if (serverPort != 80 && serverPort != 443) { - redirectUrl += ":" + serverPort; - } - redirectUrl += contextPath + "/logout/"; - response.setHeader("redirect", redirectUrl); - response.sendError(302, "Need to redirect to " + redirectUrl); + String customUrl = DBLoader.getCustomLogoutUrl(); + if(customUrl != null && !customUrl.isEmpty()) { + response.setHeader("redirect", customUrl); + response.sendError(302, "Need to redirect to " + customUrl); + } else { + String scheme = request.getScheme(); // http + String serverName = request.getServerName(); // hostname.com + int serverPort = request.getServerPort(); // 8080 + String contextPath = request.getContextPath(); // /Monolith + + redirectUrl = ""; + redirectUrl += scheme + "://" + serverName; + if (serverPort != 80 && serverPort != 443) { + redirectUrl += ":" + serverPort; + } + redirectUrl += contextPath + "/logout/"; + response.setHeader("redirect", redirectUrl); + response.sendError(302, "Need to redirect to " + redirectUrl); + } } else { LOGGER.info("Session ended. Redirect to login page"); diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index 37bc5bf18..afbd20f6d 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -279,25 +279,32 @@ public Void call() throws Exception { // well, you have logged out and we always require a login // so i will redirect you response.setStatus(302); - String redirectUrl = request.getHeader("referer"); - if(DBLoader.useLogoutPage()) { - String scheme = request.getScheme(); // http - String serverName = request.getServerName(); // hostname.com - int serverPort = request.getServerPort(); // 8080 - String contextPath = request.getContextPath(); // /Monolith - - redirectUrl = ""; - redirectUrl += scheme + "://" + serverName; - if (serverPort != 80 && serverPort != 443) { - redirectUrl += ":" + serverPort; - } - redirectUrl += contextPath + "/logout/"; - response.setHeader("redirect", redirectUrl); - response.sendError(302, "Need to redirect to " + redirectUrl); + + String customUrl = DBLoader.getCustomLogoutUrl(); + if(customUrl != null && !customUrl.isEmpty()) { + response.setHeader("redirect", customUrl); + response.sendError(302, "Need to redirect to " + customUrl); } else { - redirectUrl = redirectUrl + "#!/login"; - response.setHeader("redirect", redirectUrl); - response.sendError(302, "Need to redirect to " + redirectUrl); + String redirectUrl = request.getHeader("referer"); + if(DBLoader.useLogoutPage()) { + String scheme = request.getScheme(); // http + String serverName = request.getServerName(); // hostname.com + int serverPort = request.getServerPort(); // 8080 + String contextPath = request.getContextPath(); // /Monolith + + redirectUrl = ""; + redirectUrl += scheme + "://" + serverName; + if (serverPort != 80 && serverPort != 443) { + redirectUrl += ":" + serverPort; + } + redirectUrl += contextPath + "/logout/"; + response.setHeader("redirect", redirectUrl); + response.sendError(302, "Need to redirect to " + redirectUrl); + } else { + redirectUrl = redirectUrl + "#!/login"; + response.setHeader("redirect", redirectUrl); + response.sendError(302, "Need to redirect to " + redirectUrl); + } } // remove the cookie from the browser diff --git a/src/prerna/web/conf/DBLoader.java b/src/prerna/web/conf/DBLoader.java index 420a40c70..634501efe 100644 --- a/src/prerna/web/conf/DBLoader.java +++ b/src/prerna/web/conf/DBLoader.java @@ -63,8 +63,9 @@ public class DBLoader implements ServletContextListener { private static final Logger LOGGER = LogManager.getLogger(DBLoader.class.getName()); private static final String RDFMAP = "RDF-MAP"; private static String SESSION_ID_KEY = "JSESSIONID"; - private static boolean USE_LOGOUT_PAGE = false; - + private static boolean useLogoutPage = false; + private static String customLogoutUrl = null; + // keep track of all the watcher threads to kill private static List watcherList = new Vector(); @@ -110,7 +111,15 @@ public void contextInitialized(ServletContextEvent arg0) { useLogoutPage = "false"; } context.setInitParameter(Constants.USE_LOGOUT_PAGE, useLogoutPage); - DBLoader.USE_LOGOUT_PAGE = Boolean.parseBoolean(useLogoutPage); + DBLoader.useLogoutPage = Boolean.parseBoolean(useLogoutPage); + + // see if we redirect to logout page or back to login screen + String customLogoutUrl = context.getInitParameter(Constants.CUSTOM_LOGOUT_URL); + if(customLogoutUrl != null && !customLogoutUrl.trim().isEmpty()) { + String trimmedUrl = customLogoutUrl.trim(); + context.setInitParameter(Constants.CUSTOM_LOGOUT_URL, trimmedUrl); + DBLoader.customLogoutUrl = trimmedUrl; + } // get the session id key if(context.getSessionCookieConfig() != null) { @@ -288,6 +297,10 @@ public static String getSessionIdKey() { * @return */ public static boolean useLogoutPage() { - return DBLoader.USE_LOGOUT_PAGE; + return DBLoader.useLogoutPage; + } + + public static String getCustomLogoutUrl() { + return DBLoader.customLogoutUrl; } } From 12a28826c5a93cd7c4df31398ea89297fb183a59 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 20 Feb 2020 21:00:45 +0000 Subject: [PATCH 0533/1906] UPDATE ::: Changing number styling git-svn-id: svn://107.170.10.188:8080/Monolith/dev@37284 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 3d3c5b32c42f6c1f1dae68ae36ac34aac0cabff5 --- src/prerna/upload/Uploader.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/prerna/upload/Uploader.java b/src/prerna/upload/Uploader.java index e6c9a808c..214b0f226 100644 --- a/src/prerna/upload/Uploader.java +++ b/src/prerna/upload/Uploader.java @@ -66,7 +66,7 @@ public abstract class Uploader extends HttpServlet { public static final String CSV_FILE_KEY = "CSV"; public static final String CSV_HELPER_MESSAGE = "HTML_RESPONSE"; - protected int maxFileSize = 10000000 * 1024; + protected int maxFileSize = 10_000_000 * 1024; protected int maxMemSize = 8 * 1024; protected String filePath; protected String tempFilePath = ""; @@ -127,7 +127,8 @@ protected List processRequest(@Context HttpServletRequest request, Str ServletFileUpload upload = new ServletFileUpload(factory); // maximum file size to be uploaded. upload.setSizeMax(maxFileSize); - + // set encoding as well for the request + upload.setHeaderEncoding("UTF-8"); // make sure the insight id is valid if present if(insightId != null) { if(InsightStore.getInstance().get(insightId) == null) { From 65c81d1ad29308723aa1a53b9cbe31e4e8e90940 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Sun, 23 Feb 2020 23:15:56 +0000 Subject: [PATCH 0534/1906] UPDATE ::: Updating the jar for jsqlparser UPDATE ::: Modifying the sql parser for raw rdbms queries on native frame to wrap the provided query as the from and modify that with filters/group bys to reduce the complexity of merging the provided query into the existing query struct. Highly recommend for now to always alias your columns in the sql directly UPDATE ::: Setting method in query util to determine if derived columns need to be wrapped in quotes and removed redundant methods from interpreters git-svn-id: svn://107.170.10.188:8080/Monolith/dev@37325 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 5fa0ee35be953618b69e25f82a49640a580026f5 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index caa32abe9..b50483365 100644 --- a/pom.xml +++ b/pom.xml @@ -1322,7 +1322,7 @@ com.github.jsqlparser jsqlparser - 1.1 + 3.1 * From 47498f459a775b24d26f13f6fbef6609fa30b408 Mon Sep 17 00:00:00 2001 From: rramirezjimenez Date: Wed, 26 Feb 2020 15:33:03 +0000 Subject: [PATCH 0535/1906] UPDATE ::: Updating pom poi dependecies for new excel and ppt export git-svn-id: svn://107.170.10.188:8080/Monolith/dev@37346 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: c3a0ff50cb7be8e179b32f45458941fd7ffc52dd --- pom.xml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pom.xml b/pom.xml index b50483365..9c871d5ef 100644 --- a/pom.xml +++ b/pom.xml @@ -402,7 +402,7 @@ org.apache.commons commons-collections4 - 4.1 + 4.4 * @@ -435,7 +435,7 @@ commons-codec commons-codec - 1.10 + 1.13 * @@ -555,7 +555,7 @@ org.apache.commons commons-math3 - 3.2 + 3.6.1 * @@ -1550,7 +1550,7 @@ org.apache.poi poi - 3.15 + 4.1.1 * @@ -1561,7 +1561,7 @@ org.apache.poi poi-ooxml - 3.15 + 4.1.1 * @@ -1573,7 +1573,7 @@ org.apache.poi poi-ooxml-schemas - 3.15 + 4.1.1 * @@ -2024,7 +2024,7 @@ org.apache.xmlbeans xmlbeans - 2.6.0 + 3.1.0 * @@ -2967,7 +2967,7 @@ org.apache.commons commons-compress - 1.16.1 + 1.19 * From a52c1449a7003b0a00e5ce527c6bf727531e3a78 Mon Sep 17 00:00:00 2001 From: kunalppatel9 Date: Wed, 26 Feb 2020 17:11:52 +0000 Subject: [PATCH 0536/1906] UPDATE ::: ading in Hive jdbc jars git-svn-id: svn://107.170.10.188:8080/Monolith/dev@37357 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: f211ea5f5e651817bc10a6528e449cb0d4ab7d09 --- pom.xml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pom.xml b/pom.xml index 9c871d5ef..a2582f505 100644 --- a/pom.xml +++ b/pom.xml @@ -3070,5 +3070,15 @@ true + + org.apache.hive + hive-jdbc + 2.3.2 + + + org.apache.hive + hive-common + 2.3.2 + \ No newline at end of file From eae5ac110817ee282b472066aa3ef2911e4fa384 Mon Sep 17 00:00:00 2001 From: rramirezjimenez Date: Wed, 26 Feb 2020 19:31:12 +0000 Subject: [PATCH 0537/1906] UPDATE ::: Removing hive dependencies git-svn-id: svn://107.170.10.188:8080/Monolith/dev@37360 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: e1feccfe8c24b90e2d7c101770f13b4bae17067e --- pom.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pom.xml b/pom.xml index a2582f505..60ba0e686 100644 --- a/pom.xml +++ b/pom.xml @@ -3070,6 +3070,7 @@ true + \ No newline at end of file From b2cc6514ffc894b880028eea9b234f4b8d6b015a Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 26 Feb 2020 21:41:37 +0000 Subject: [PATCH 0538/1906] UPDATE ::: Making sure app asset download doesn't interfere with other end points git-svn-id: svn://107.170.10.188:8080/Monolith/dev@37365 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 9bf60df8acc5568925eccc007ab4fd178dd09ac1 --- src/prerna/semoss/web/services/local/AppResource.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prerna/semoss/web/services/local/AppResource.java b/src/prerna/semoss/web/services/local/AppResource.java index 5206d8a1b..fd8f88b63 100644 --- a/src/prerna/semoss/web/services/local/AppResource.java +++ b/src/prerna/semoss/web/services/local/AppResource.java @@ -164,7 +164,7 @@ public Response getAppLandingPage(@Context final Request coreRequest, @Context H } @GET - @Path("/{relPath}") + @Path("/downloadAppAsset/{relPath}") @Produces({MediaType.TEXT_HTML, MediaType.APPLICATION_OCTET_STREAM}) public Response getAppFile(@Context final Request coreRequest, @Context HttpServletRequest request, @PathParam("appId") String appId, @PathParam("relPath") String relPath) { User user = null; From f511071d85859b93a1557f9c3930dbb4db36b59f Mon Sep 17 00:00:00 2001 From: pkapaleeswaran Date: Thu, 27 Feb 2020 14:27:55 +0000 Subject: [PATCH 0539/1906] Updates to accomodate PyServe NoUserInSessionTrustedToken - This is the trusted token git-svn-id: svn://107.170.10.188:8080/Monolith/dev@37382 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 92435cfd54326f69f7ac1912f32d71746379b7e3 --- .../semoss/web/services/local/NameServer.java | 36 ++- .../web/services/local/UserResource.java | 41 ++- .../web/conf/NoUserInSessionFilter.java | 10 + .../NoUserInSessionTrustedTokenFilter.java | 294 ++++++++++++++++++ src/prerna/web/conf/UserSessionLoader.java | 4 + 5 files changed, 380 insertions(+), 5 deletions(-) create mode 100644 src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index 7e6d1e0bd..49547430e 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -60,6 +60,7 @@ import javax.ws.rs.core.Response; import javax.ws.rs.core.StreamingOutput; +import org.apache.commons.io.FileUtils; import org.apache.commons.io.FilenameUtils; import org.apache.http.HttpEntity; import org.apache.http.client.ClientProtocolException; @@ -365,7 +366,7 @@ public Response runPixelSync(@Context HttpServletRequest request){ if(session.getAttribute(Constants.PYTHON) != null) { jepThread = (PyExecutorThread)session.getAttribute(Constants.PYTHON); } - if(PyUtils.pyEnabled() && jepThread == null) { + if(PyUtils.pyEnabled() && (jepThread == null || session.getAttribute("USER_TUPLE") == null)) { // i do not want to make more than 1 py thread per session // and this method is called many times synchronized(sessionId) { @@ -376,6 +377,10 @@ public Response runPixelSync(@Context HttpServletRequest request){ jepThread = PyUtils.getInstance().getJep(); session.setAttribute(Constants.PYTHON, jepThread); } + if(session.getAttribute("USER_TUPLE") == null) + { + session.setAttribute("USER_TUPLE", PyUtils.getInstance().getTempTupleSpace(user, DIHelper.getInstance().getProperty(Constants.INSIGHT_CACHE_DIR))); + } } } @@ -417,6 +422,14 @@ public Response runPixelSync(@Context HttpServletRequest request){ // set the user insight.setUser(user); insight.setPy(jepThread); + + if(insight.getTupleSpace() == null) + { + // try to see if the insight directory has been created in the tuplespace + String curTupleSpace = session.getAttribute("USER_TUPLE")+""; + insight.setTupleSpace(createInsightTupleSpace(curTupleSpace, insightId)); + } + JobManager manager = JobManager.getManager(); JobThread jt = manager.makeJob(insightId); jobId = jt.getJobId(); @@ -636,6 +649,7 @@ public StreamingOutput console(MultivaluedMap form, @Context Htt String jobId = form.getFirst("jobId"); // HttpSession session = request.getSession(true); // if(session.getAttribute(jobId) != null) { + //if(jobId != null) dataReturn = JobManager.getManager().getStdOut(jobId); // } return WebUtility.getSO(dataReturn); @@ -1115,6 +1129,26 @@ public StreamingOutput getSearchInsightsResults(MultivaluedMap f return WebUtility.getSO(queryResults); } + + private String createInsightTupleSpace(String baseFolder, String insightId) + { + baseFolder = baseFolder.replace("\\","/"); + String insightSpecificFolder = baseFolder + "/" + insightId; + File file = new File(insightSpecificFolder); + if(!file.exists()) + { + file.mkdir(); + String command = "addFolder@@" + insightSpecificFolder; + File cmdFile = new File(baseFolder + "/" + insightId +".admin"); + try { + FileUtils.writeStringToFile(cmdFile, command); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + return insightSpecificFolder; + } //////////////////////////////////////////////////////////////////////////////////// diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index afbd20f6d..8ed81056c 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -27,15 +27,20 @@ *******************************************************************************/ package prerna.semoss.web.services.local; +import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.Principal; +import java.util.ArrayList; +import java.util.Base64; import java.util.HashMap; import java.util.Hashtable; import java.util.List; @@ -65,17 +70,22 @@ import javax.ws.rs.core.Response; import javax.ws.rs.core.StreamingOutput; +import jodd.util.URLDecoder; + import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.PropertiesConfiguration; +import org.apache.http.NameValuePair; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.message.BasicNameValuePair; import org.apache.log4j.LogManager; import org.apache.log4j.Logger; import org.kohsuke.github.GHMyself; import org.kohsuke.github.GitHub; -import com.google.gson.Gson; -import com.google.gson.reflect.TypeToken; - -import jodd.util.URLDecoder; import prerna.auth.AccessToken; import prerna.auth.AppTokens; import prerna.auth.AuthProvider; @@ -86,6 +96,7 @@ import prerna.auth.utils.NativeUserSecurityUtils; import prerna.auth.utils.SecurityAdminUtils; import prerna.auth.utils.SecurityUpdateUtils; +import prerna.ds.py.PyExecutorThread; import prerna.ds.py.PyUtils; import prerna.engine.impl.r.IRUserConnection; import prerna.io.connector.IConnectorIOp; @@ -102,11 +113,15 @@ import prerna.util.BeanFiller; import prerna.util.Constants; import prerna.util.DIHelper; +import prerna.util.git.GitRepoUtils; import prerna.web.conf.DBLoader; import prerna.web.conf.NoUserInSessionFilter; import prerna.web.services.util.WebUtility; import waffle.servlet.WindowsPrincipal; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; + @Path("/auth") public class UserResource { @@ -239,6 +254,15 @@ public Void call() throws Exception { } } + // stop python too + if(PyUtils.pyEnabled()) { + PyExecutorThread pyThread = (PyExecutorThread) session.getAttribute(Constants.PYTHON); + PyUtils.getInstance().killPyThread(pyThread); + if(thisUser != null) + PyUtils.getInstance().killTempTupleSpace(thisUser); + } + + if(provider.equalsIgnoreCase("ALL")) { // remove the user from session call it a day request.getSession().removeAttribute(Constants.SESSION_USER); @@ -356,8 +380,15 @@ private void addAccessToken(AccessToken token, HttpServletRequest request) { // if security is not on, we have a single py thread for the entire instance // and we dont want to override those variables due to user login if(AbstractSecurityUtils.securityEnabled() && PyUtils.pyEnabled()) { + session.setAttribute(Constants.PYTHON, PyUtils.getInstance().getJep()); } + /*if(session.getAttribute("USER_TUPLE") == null) + { + String tupleSpace = PyUtils.getInstance().getTempTupleSpace(token.getName(), DIHelper.getInstance().getProperty(Constants.INSIGHT_CACHE_DIR)); + semossUser.setTupleSpace(tupleSpace); + session.setAttribute("USER_TUPLE", tupleSpace); + }*/ } semossUser.setAccessToken(token); semossUser.setAnonymous(false); @@ -752,6 +783,7 @@ public Response loginGithub(@Context HttpServletRequest request, @Context HttpSe } accessToken.setProvider(AuthProvider.GITHUB); + GitRepoUtils.addCertForDomain(url); // add specific Git values GHMyself myGit = GitHub.connectUsingOAuth(accessToken.getAccess_token()).getMyself(); accessToken.setId(myGit.getId() + ""); @@ -769,6 +801,7 @@ public Response loginGithub(@Context HttpServletRequest request, @Context HttpSe userObj = (User) request.getSession().getAttribute(Constants.SESSION_USER); if(userObj == null || userObj.getAccessToken(AuthProvider.GITHUB) == null) { // not authenticated + GitRepoUtils.addCertForDomain("https://github.com"); response.setStatus(302); response.sendRedirect(getGithubRedirect(request)); return null; diff --git a/src/prerna/web/conf/NoUserInSessionFilter.java b/src/prerna/web/conf/NoUserInSessionFilter.java index ec1ff4367..ef323de8b 100644 --- a/src/prerna/web/conf/NoUserInSessionFilter.java +++ b/src/prerna/web/conf/NoUserInSessionFilter.java @@ -89,10 +89,20 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 } // if no user + // need to make a check in terms of am I a part of trusted host scheme + // basically the RDF_map will have a list of IPs for trusted host who can make a call + // when that IP makes a call, we will transfer the session and give the user over + // RDF_MAP + // Trusted_token true // says this instance will work with trusted token + // Trusted_host + // Token_Prefix this is an optional piece - I am not going to implement right now + + if(user == null || (!AbstractSecurityUtils.anonymousUsersEnabled() && user.getLogins().isEmpty()) ) { // do a condition here if the session id request parameter is available // eventually this will be that and the tableau HttpServletRequest req = (HttpServletRequest) arg0; + if(req.getParameter(DBLoader.getSessionIdKey()) != null) { String sessionId = req.getParameter(DBLoader.getSessionIdKey()); // create the cookie add it and sent it back diff --git a/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java b/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java new file mode 100644 index 000000000..f111dc3da --- /dev/null +++ b/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java @@ -0,0 +1,294 @@ +package prerna.web.conf; + +import java.io.IOException; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Collections; +import java.util.Hashtable; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.Vector; +import java.util.stream.Collectors; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import prerna.auth.AuthProvider; +import prerna.auth.InsightToken; +import prerna.auth.User; +import prerna.auth.utils.AbstractSecurityUtils; +import prerna.semoss.web.services.local.UserResource; +import prerna.util.Constants; +import prerna.util.DIHelper; +import prerna.web.requests.MultiReadHttpServletRequest; + +public class NoUserInSessionTrustedTokenFilter implements Filter { + + // this is so if you are making a direct BE request + // after you sign in + // we can redirect you back to the original call + // instead of taking you to the base SemossWeb URL + public static final String ENDPOINT_REDIRECT_KEY = "ENDPOINT_REDIRECT_KEY"; + + public static final String MONOLITH_ROUTE = "MONOLITH_ROUTE"; + public static final String MONOLITH_PREFIX = "MONOLITH_PREFIX"; + + private static final String LOGIN = "login"; + + private static final String NO_USER_HTML = "/noUserFail/"; + protected static List ignoreDueToFE = new Vector(); + + // maps from the IP the user is coming in with the cookie + private static Map ipMapper = new Hashtable(); + + static { + // allow these for successful dropping of + // sessions when browser is closed/refreshed + // these do their own session checks + ignoreDueToFE.add("engine/cleanSession"); + ignoreDueToFE.add("engine/cancelCleanSession"); + + ignoreDueToFE.add("config"); + ignoreDueToFE.add("auth/logins"); + ignoreDueToFE.add("auth/loginsAllowed"); + //ignoreDueToFE.add("auth/login"); + ignoreDueToFE.add("auth/createUser"); + for(AuthProvider v : AuthProvider.values()) { + ignoreDueToFE.add("auth/userinfo/" + v.toString().toLowerCase()); + ignoreDueToFE.add("auth/login/" + v.toString().toLowerCase()); + } + } + + @Override + public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { + + + ServletContext context = arg0.getServletContext(); + + if(AbstractSecurityUtils.securityEnabled()) { + // this will be the full path of the request + // like http://localhost:8080/Monolith_Dev/api/engine/runPixel + String fullUrl = ((HttpServletRequest) arg0).getRequestURL().toString(); + String contextPath = ((HttpServletRequest) arg0).getContextPath(); + HttpSession session = ((HttpServletRequest) arg0).getSession(false); + //if(session != null) + // System.err.println(" Session id is " + session.getId()); + + // additional requirement + // the front end comes with + // api/engine/redirect?insight=something something&prefix_token = something + // need to see if there is a user if not, we redirect to the new url + // user is not available ipmapper has it, all set good to go + // user is there + // first time when this url comes - I dont have a session + // so do the filter get back and then redirect to this url + + // REALLY DISLIKE THIS CHECK!!! + // eventually I need to take this off + if(!isIgnored(fullUrl)) { + // due to FE being annoying + // we need to push a response for this one end point + // since security is embedded w/ normal semoss and not standalone + + User user = null; + if(session != null) { + //System.out.println("Session ID >> " + session.getId()); + user = (User) session.getAttribute(Constants.SESSION_USER); + } + + + // if no user + // need to make a check in terms of am I a part of trusted host scheme + // basically the RDF_map will have a list of IPs for trusted host who can make a call + // when that IP makes a call, we will transfer the session and give the user over + // RDF_MAP + // Trusted_token true // says this instance will work with trusted token + // Trusted_host + // Token_Prefix this is an optional piece - I am not going to implement right now + boolean isTrustedDomain = DIHelper.getInstance().getProperty("TRUSTED_TOKEN") != null; + + if(isTrustedDomain) + { + HttpServletRequest req = (HttpServletRequest) arg0; + String ipAddress = req.getHeader("X-FORWARDED-FOR"); + if (ipAddress == null) { + ipAddress = req.getRemoteAddr(); + } + + String tokenName = DIHelper.getInstance().getProperty("TRUSTED_TOKEN_PREFIX"); + + // if cookie is there - and session id is sent + // associate with the session id + String sessionId = null; + if(req.getMethod().equalsIgnoreCase("GET")) + sessionId = req.getParameter(tokenName); + + + if(sessionId != null && !ipMapper.containsKey(sessionId)) // && user != null + { + String [] trustedIPs = DIHelper.getInstance().getProperty("TRUSTED_TOKEN_DOMAIN").split(";"); + boolean allow = false; + for(int ipIndex = 0;ipIndex < trustedIPs.length;ipIndex++) + { + // let us do allow all as well + if(ipAddress.equalsIgnoreCase(trustedIPs[ipIndex]) || trustedIPs[ipIndex].equalsIgnoreCase("*")) + { + allow = true; + break; + } + } + + if(allow) + { + // this is the case where you associate + String cookieId = null; + + // try to see if I can get the session id directly + // if the user is coming in the first time + // create the session + /*if(session.isNew()) + { + session.invalidate(); + session = null; + }*/ + if(session == null) + { + session = req.getSession(true); + //session.setAttribute(Constants.SESSION_USER, user); + } + cookieId = session.getId(); + if(sessionId != null) + ipMapper.put(sessionId, cookieId); + + /*Cookie[] cookies = req.getCookies(); + if (cookies != null) { + for (Cookie c : cookies) { + if (c.getName().equals(DBLoader.getSessionIdKey())) { + cookieId = c.getValue(); + System.err.println("Cookie is set to.. " + cookieId); + ipMapper.put(sessionId, cookieId); + //break; + } + } + }*/ + } + } + else if(sessionId != null && ipMapper.containsKey(sessionId)) + { + + // this is the class where you redirect + // I dont think + + String cookieId = (String)ipMapper.get(sessionId); + Cookie k = new Cookie(DBLoader.getSessionIdKey(), cookieId); + k.setPath(contextPath); + ((HttpServletResponse)arg1).addCookie(k); + + Cookie[] cookies = req.getCookies(); + if (cookies != null) { + System.err.println("Forcing session value !"); + for (Cookie c : cookies) { + if (c.getName().equals(DBLoader.getSessionIdKey())) { + if(c.getName().equalsIgnoreCase(DBLoader.getSessionIdKey())) + c.setValue(cookieId); + //System.err.println("Cookie is set to.. " + cookieId); + ipMapper.put(sessionId, cookieId); + //break; + } + } + } + + if(req.getMethod().equalsIgnoreCase("GET")){ + ((HttpServletResponse) arg1).setStatus(302); + + // modify the prefix if necessary + Map envMap = System.getenv(); + if(envMap.containsKey(MONOLITH_PREFIX)) { + fullUrl = fullUrl.replace(contextPath, envMap.get(MONOLITH_PREFIX)); + } + String queryString = req.getQueryString(); + queryString = queryString.replace(tokenName, "dummy"); + ((HttpServletResponse) arg1).sendRedirect(fullUrl + "?" + queryString); + + return; + } + } + // else this is the regular flow - let us the user go through it + } + } + } + arg2.doFilter(arg0, arg1); + + } + + /** + * Method to determine where to redirect the user + * @param context + * @param arg0 + * @param arg1 + * @throws IOException + */ + private void setInvalidEntryRedirect(ServletContext context, ServletRequest arg0, ServletResponse arg1, String endpoint) throws IOException { + String fullUrl = ((HttpServletRequest) arg0).getRequestURL().toString(); + ((HttpServletResponse) arg1).setStatus(302); + String redirectUrl = ((HttpServletRequest) arg0).getHeader("referer"); + // if no referrer + // then a person hit the endpoint directly + if(redirectUrl == null) { + ((HttpServletRequest) arg0).getSession(true).setAttribute(ENDPOINT_REDIRECT_KEY, fullUrl); + // this will be the deployment name of the app + String loginRedirect = UserResource.getLoginRedirect(); + ((HttpServletResponse) arg1).setStatus(302); + if(loginRedirect != null) { + ((HttpServletResponse) arg1).sendRedirect(loginRedirect); + } else { + String contextPath = context.getContextPath(); + redirectUrl = fullUrl.substring(0, fullUrl.indexOf(contextPath) + contextPath.length()) + NO_USER_HTML; + ((HttpServletResponse) arg1).sendRedirect(redirectUrl); + } + } else { + redirectUrl = redirectUrl + "#!/" + endpoint; + ((HttpServletResponse) arg1).setHeader("redirect", redirectUrl); + ((HttpServletResponse) arg1).sendError(302, "Need to redirect to " + redirectUrl); + } + } + + @Override + public void destroy() { + // TODO Auto-generated method stub + + } + + @Override + public void init(FilterConfig arg0) throws ServletException { + // TODO Auto-generated method stub + + } + + /** + * Due to how the FE security is set up + * Need to ignore some URLs :( + * I REALLY DISLIKE THIS!!! + * @param fullUrl + * @return + */ + protected static boolean isIgnored(String fullUrl) { + for(String ignore : ignoreDueToFE) { + if(fullUrl.endsWith(ignore)) { + return true; + } + } + return false; + } + +} diff --git a/src/prerna/web/conf/UserSessionLoader.java b/src/prerna/web/conf/UserSessionLoader.java index b4a88c82a..93b98f195 100644 --- a/src/prerna/web/conf/UserSessionLoader.java +++ b/src/prerna/web/conf/UserSessionLoader.java @@ -12,6 +12,7 @@ import org.apache.log4j.Logger; import prerna.auth.SyncUserAppsThread; +import prerna.auth.User; import prerna.cache.ICache; import prerna.ds.py.PyExecutorThread; import prerna.ds.py.PyUtils; @@ -65,6 +66,9 @@ public void sessionDestroyed(HttpSessionEvent sessionEvent) { if(PyUtils.pyEnabled()) { PyExecutorThread pyThread = (PyExecutorThread) session.getAttribute(Constants.PYTHON); PyUtils.getInstance().killPyThread(pyThread); + User user = (User)session.getAttribute(Constants.SESSION_USER); + if(user != null) + PyUtils.getInstance().killTempTupleSpace(user); } } From bbb0afa57ed1aba544b312357472d6495f55cf8d Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 27 Feb 2020 14:56:47 +0000 Subject: [PATCH 0540/1906] UPDATE ::: Adding the content type in the response git-svn-id: svn://107.170.10.188:8080/Monolith/dev@37385 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 9da6f37e9d9f765dfb05023cfa79c3affe3016a3 --- src/prerna/semoss/web/services/local/AppResource.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/prerna/semoss/web/services/local/AppResource.java b/src/prerna/semoss/web/services/local/AppResource.java index fd8f88b63..384b70ffa 100644 --- a/src/prerna/semoss/web/services/local/AppResource.java +++ b/src/prerna/semoss/web/services/local/AppResource.java @@ -268,7 +268,8 @@ public Response getEmbedUrl(@Context final Request coreRequest, @Context HttpSer return builder.build(); } - return Response.status(200).entity(contents).cacheControl(cc).tag(etag).lastModified(new Date(file.lastModified())).build(); + String mimeType = Files.probeContentType(file.toPath()); + return Response.status(200).entity(contents).type(mimeType).cacheControl(cc).tag(etag).lastModified(new Date(file.lastModified())).build(); } catch (IOException e) { Map errorMap = new HashMap(); errorMap.put("errorMessage", "Unable to load file"); From e342548c431a30b49f279dcb3e687e0dcc2347e4 Mon Sep 17 00:00:00 2001 From: rramirezjimenez Date: Thu, 27 Feb 2020 15:04:24 +0000 Subject: [PATCH 0541/1906] UPDATE ::: PyWorker pom dependencies git-svn-id: svn://107.170.10.188:8080/Monolith/dev@37386 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: e4ac8ab947720d74bd5bcecf9dcaca976b17eebb --- pom.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pom.xml b/pom.xml index 60ba0e686..72f1f6cb8 100644 --- a/pom.xml +++ b/pom.xml @@ -3082,5 +3082,10 @@ 2.3.2 end of hive --> + + de.ruedigermoeller + fst + 2.56 + \ No newline at end of file From 3aba1fad8e0e854c5a51ff48d2920e042a197e59 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 2 Mar 2020 16:10:42 +0000 Subject: [PATCH 0542/1906] UPDATE ::: Adding pom changes for previous commit performing the graph layout logic git-svn-id: svn://107.170.10.188:8080/Monolith/dev@37423 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: a5c46c58ad696c84532051deb4fde74d68afb77f --- pom.xml | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 72f1f6cb8..6905b5b0f 100644 --- a/pom.xml +++ b/pom.xml @@ -3082,10 +3082,29 @@ 2.3.2 end of hive --> + - de.ruedigermoeller - fst - 2.56 + org.graphstream + gs-core + + + junit + junit + + + 1.3 + + + + org.graphstream + gs-algo + + + junit + junit + + + 1.3 \ No newline at end of file From c648afc30f41cdd6df4027cb8ff3e9e39f061b70 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Sun, 8 Mar 2020 13:44:03 +0000 Subject: [PATCH 0543/1906] UPDATE ::: Adding logic for the ability to take the user id as a token and redirect the user to the correct session git-svn-id: svn://107.170.10.188:8080/Monolith/dev@37549 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 577a8718a2b15e1fbf9e12cfbe0f2cd7f839d7b5 --- WebContent/WEB-INF/web.xml | 34 +- .../web/services/local/UserResource.java | 21 +- .../web/conf/NoUserInSessionFilter.java | 22 +- .../NoUserInSessionTrustedTokenFilter.java | 319 ++++++------------ .../NoUserInSessionTrustedTokenListener.java | 21 ++ 5 files changed, 178 insertions(+), 239 deletions(-) create mode 100644 src/prerna/web/conf/NoUserInSessionTrustedTokenListener.java diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index 6226f36c5..43b3d674a 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -161,6 +161,26 @@ --> + + + NoUserInSessionFilter prerna.web.conf.NoUserInSessionFilter @@ -174,10 +194,11 @@ AdminStartupFilter prerna.web.conf.AdminStartupFilter - + AdminStartupFilter /adminconfig/* + + --> @@ -252,7 +273,7 @@ custom-logout-url - + http://google.com Location to store uploaded file @@ -267,7 +288,7 @@ The place where the core RDF Map gets picked from RDF-MAP - C:\\workspace\\Semoss_Dev\\RDF_Map.prop + C:/workspace/Semoss_Dev/RDF_Map.prop @@ -279,6 +300,11 @@ prerna.web.conf.SessionCounter + 120 diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index 8ed81056c..55e67f396 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -27,20 +27,15 @@ *******************************************************************************/ package prerna.semoss.web.services.local; -import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.Principal; -import java.util.ArrayList; -import java.util.Base64; import java.util.HashMap; import java.util.Hashtable; import java.util.List; @@ -70,22 +65,17 @@ import javax.ws.rs.core.Response; import javax.ws.rs.core.StreamingOutput; -import jodd.util.URLDecoder; - import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.PropertiesConfiguration; -import org.apache.http.NameValuePair; -import org.apache.http.client.entity.UrlEncodedFormEntity; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.message.BasicNameValuePair; import org.apache.log4j.LogManager; import org.apache.log4j.Logger; import org.kohsuke.github.GHMyself; import org.kohsuke.github.GitHub; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; + +import jodd.util.URLDecoder; import prerna.auth.AccessToken; import prerna.auth.AppTokens; import prerna.auth.AuthProvider; @@ -119,9 +109,6 @@ import prerna.web.services.util.WebUtility; import waffle.servlet.WindowsPrincipal; -import com.google.gson.Gson; -import com.google.gson.reflect.TypeToken; - @Path("/auth") public class UserResource { diff --git a/src/prerna/web/conf/NoUserInSessionFilter.java b/src/prerna/web/conf/NoUserInSessionFilter.java index ef323de8b..e84e576e5 100644 --- a/src/prerna/web/conf/NoUserInSessionFilter.java +++ b/src/prerna/web/conf/NoUserInSessionFilter.java @@ -140,21 +140,33 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 // and now redirect back to the URL // if get, we can do it - if(req.getMethod().equalsIgnoreCase("GET")){ - ((HttpServletResponse) arg1).setStatus(302); - + String method = req.getMethod(); + if(method.equalsIgnoreCase("GET")) { // modify the prefix if necessary Map envMap = System.getenv(); if(envMap.containsKey(MONOLITH_PREFIX)) { fullUrl = fullUrl.replace(contextPath, envMap.get(MONOLITH_PREFIX)); } + ((HttpServletResponse) arg1).setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY); ((HttpServletResponse) arg1).sendRedirect(fullUrl + "?" + req.getQueryString()); + return; + } else if(method.equalsIgnoreCase("POST")) { + // modify the prefix if necessary + Map envMap = System.getenv(); + if(envMap.containsKey(MONOLITH_PREFIX)) { + fullUrl = fullUrl.replace(contextPath, envMap.get(MONOLITH_PREFIX)); + } + + ((HttpServletResponse) arg1).setStatus(HttpServletResponse.SC_TEMPORARY_REDIRECT); + ((HttpServletResponse) arg1).setHeader("Location", fullUrl); + return; } else { - // BE cannot redirect a POST - // send back an error and have the client remake the post + // don't know what i am redirecting + // send back an error and have the client remake the request setInvalidEntryRedirect(context, arg0, arg1, LOGIN); } + return; } // no jsession id as a param diff --git a/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java b/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java index f111dc3da..39716c217 100644 --- a/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java +++ b/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java @@ -1,20 +1,15 @@ package prerna.web.conf; import java.io.IOException; -import java.security.MessageDigest; -import java.security.NoSuchAlgorithmException; -import java.util.Collections; import java.util.Hashtable; +import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.Vector; -import java.util.stream.Collectors; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; -import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; @@ -23,57 +18,29 @@ import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; +import prerna.auth.AccessToken; import prerna.auth.AuthProvider; -import prerna.auth.InsightToken; import prerna.auth.User; import prerna.auth.utils.AbstractSecurityUtils; -import prerna.semoss.web.services.local.UserResource; +import prerna.auth.utils.SecurityQueryUtils; import prerna.util.Constants; -import prerna.util.DIHelper; -import prerna.web.requests.MultiReadHttpServletRequest; public class NoUserInSessionTrustedTokenFilter implements Filter { - // this is so if you are making a direct BE request - // after you sign in - // we can redirect you back to the original call - // instead of taking you to the base SemossWeb URL - public static final String ENDPOINT_REDIRECT_KEY = "ENDPOINT_REDIRECT_KEY"; - - public static final String MONOLITH_ROUTE = "MONOLITH_ROUTE"; - public static final String MONOLITH_PREFIX = "MONOLITH_PREFIX"; - - private static final String LOGIN = "login"; + private static String TRUSTED_TOKEN_PREFIX = "trustedTokenPrefix"; + private static String TRUSTED_TOKEN_DOMAIN = "trustedTokenDomain"; - private static final String NO_USER_HTML = "/noUserFail/"; - protected static List ignoreDueToFE = new Vector(); - - // maps from the IP the user is coming in with the cookie - private static Map ipMapper = new Hashtable(); + private static String tokenName = null; + private static List trustedDomains = null; - static { - // allow these for successful dropping of - // sessions when browser is closed/refreshed - // these do their own session checks - ignoreDueToFE.add("engine/cleanSession"); - ignoreDueToFE.add("engine/cancelCleanSession"); + // maps from the IP the user is coming in with the cookie + private static Map sessionMapper = new Hashtable(); - ignoreDueToFE.add("config"); - ignoreDueToFE.add("auth/logins"); - ignoreDueToFE.add("auth/loginsAllowed"); - //ignoreDueToFE.add("auth/login"); - ignoreDueToFE.add("auth/createUser"); - for(AuthProvider v : AuthProvider.values()) { - ignoreDueToFE.add("auth/userinfo/" + v.toString().toLowerCase()); - ignoreDueToFE.add("auth/login/" + v.toString().toLowerCase()); - } - } + private FilterConfig filterConfig; @Override public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { - - - ServletContext context = arg0.getServletContext(); + setInitParams(arg0); if(AbstractSecurityUtils.securityEnabled()) { // this will be the full path of the request @@ -81,186 +48,98 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 String fullUrl = ((HttpServletRequest) arg0).getRequestURL().toString(); String contextPath = ((HttpServletRequest) arg0).getContextPath(); HttpSession session = ((HttpServletRequest) arg0).getSession(false); - //if(session != null) - // System.err.println(" Session id is " + session.getId()); - // additional requirement - // the front end comes with - // api/engine/redirect?insight=something something&prefix_token = something - // need to see if there is a user if not, we redirect to the new url - // user is not available ipmapper has it, all set good to go - // user is there - // first time when this url comes - I dont have a session - // so do the filter get back and then redirect to this url - - // REALLY DISLIKE THIS CHECK!!! - // eventually I need to take this off - if(!isIgnored(fullUrl)) { - // due to FE being annoying - // we need to push a response for this one end point - // since security is embedded w/ normal semoss and not standalone + User user = null; + if(session != null) { + user = (User) session.getAttribute(Constants.SESSION_USER); + } - User user = null; - if(session != null) { - //System.out.println("Session ID >> " + session.getId()); - user = (User) session.getAttribute(Constants.SESSION_USER); - } + // if we have a user, there is nothing to do + if(user == null) { - - // if no user - // need to make a check in terms of am I a part of trusted host scheme - // basically the RDF_map will have a list of IPs for trusted host who can make a call - // when that IP makes a call, we will transfer the session and give the user over - // RDF_MAP - // Trusted_token true // says this instance will work with trusted token - // Trusted_host - // Token_Prefix this is an optional piece - I am not going to implement right now - boolean isTrustedDomain = DIHelper.getInstance().getProperty("TRUSTED_TOKEN") != null; + // the front end comes with + // fullUrl?prefix_token=userId + // check if the ip address is allowed + // check if the userId actually exists + // if first time, add the user + // if not, redirect the GET/POST call - if(isTrustedDomain) - { - HttpServletRequest req = (HttpServletRequest) arg0; - String ipAddress = req.getHeader("X-FORWARDED-FOR"); - if (ipAddress == null) { - ipAddress = req.getRemoteAddr(); - } - - String tokenName = DIHelper.getInstance().getProperty("TRUSTED_TOKEN_PREFIX"); - - // if cookie is there - and session id is sent - // associate with the session id - String sessionId = null; - if(req.getMethod().equalsIgnoreCase("GET")) - sessionId = req.getParameter(tokenName); - - - if(sessionId != null && !ipMapper.containsKey(sessionId)) // && user != null - { - String [] trustedIPs = DIHelper.getInstance().getProperty("TRUSTED_TOKEN_DOMAIN").split(";"); - boolean allow = false; - for(int ipIndex = 0;ipIndex < trustedIPs.length;ipIndex++) - { - // let us do allow all as well - if(ipAddress.equalsIgnoreCase(trustedIPs[ipIndex]) || trustedIPs[ipIndex].equalsIgnoreCase("*")) - { - allow = true; - break; + HttpServletRequest req = (HttpServletRequest) arg0; + // grab the token id + // if the token exists + String userId = req.getParameter(tokenName); + if(userId != null) { + if(!sessionMapper.containsKey(userId)) { + // grab the ip address + String ipAddress = req.getHeader("X-FORWARDED-FOR"); + if (ipAddress == null) { + ipAddress = req.getRemoteAddr(); + } + // check if the ip address is allowed + boolean allow = trustedDomains.contains("*"); + if(!allow) { + for(String domain : trustedDomains) { + if(ipAddress.matches(domain)) { + allow = true; + break; + } } } - - if(allow) - { - // this is the case where you associate - String cookieId = null; - - // try to see if I can get the session id directly - // if the user is coming in the first time - // create the session - /*if(session.isNew()) - { - session.invalidate(); - session = null; - }*/ - if(session == null) - { + if(allow && SecurityQueryUtils.checkUserExist(userId)) { + // you are allowed + // i just have to check if the token id exists + // and id you do, i make the user object + if(session == null) { session = req.getSession(true); - //session.setAttribute(Constants.SESSION_USER, user); } - cookieId = session.getId(); - if(sessionId != null) - ipMapper.put(sessionId, cookieId); - - /*Cookie[] cookies = req.getCookies(); - if (cookies != null) { - for (Cookie c : cookies) { - if (c.getName().equals(DBLoader.getSessionIdKey())) { - cookieId = c.getValue(); - System.err.println("Cookie is set to.. " + cookieId); - ipMapper.put(sessionId, cookieId); - //break; - } - } - }*/ - } - } - else if(sessionId != null && ipMapper.containsKey(sessionId)) - { - + user = new User(); + AccessToken token = new AccessToken(); + token.setProvider(AuthProvider.WINDOWS_USER); + token.setId(userId); + user.setAccessToken(token); + session.setAttribute(Constants.SESSION_USER, user); + + String sessionId = session.getId(); + sessionMapper.put(userId, sessionId); + } + } else { // this is the class where you redirect - // I dont think - - String cookieId = (String)ipMapper.get(sessionId); - Cookie k = new Cookie(DBLoader.getSessionIdKey(), cookieId); + String redirectSessionId = (String) sessionMapper.get(userId); + // add the session id cookie + Cookie k = new Cookie(DBLoader.getSessionIdKey(), redirectSessionId); k.setPath(contextPath); ((HttpServletResponse)arg1).addCookie(k); - + // replace any other session id cookies Cookie[] cookies = req.getCookies(); if (cookies != null) { System.err.println("Forcing session value !"); for (Cookie c : cookies) { if (c.getName().equals(DBLoader.getSessionIdKey())) { - if(c.getName().equalsIgnoreCase(DBLoader.getSessionIdKey())) - c.setValue(cookieId); - //System.err.println("Cookie is set to.. " + cookieId); - ipMapper.put(sessionId, cookieId); - //break; + if(c.getName().equalsIgnoreCase(DBLoader.getSessionIdKey())) { + c.setValue(redirectSessionId); + } } } } - if(req.getMethod().equalsIgnoreCase("GET")){ - ((HttpServletResponse) arg1).setStatus(302); - - // modify the prefix if necessary - Map envMap = System.getenv(); - if(envMap.containsKey(MONOLITH_PREFIX)) { - fullUrl = fullUrl.replace(contextPath, envMap.get(MONOLITH_PREFIX)); - } - String queryString = req.getQueryString(); - queryString = queryString.replace(tokenName, "dummy"); - ((HttpServletResponse) arg1).sendRedirect(fullUrl + "?" + queryString); - - return; - } + String method = req.getMethod(); + if(method.equalsIgnoreCase("GET")) { + ((HttpServletResponse) arg1).setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY); + ((HttpServletResponse) arg1).sendRedirect(fullUrl + "?" + req.getQueryString()); + return; + } else if(method.equalsIgnoreCase("POST")) { + ((HttpServletResponse) arg1).setStatus(HttpServletResponse.SC_TEMPORARY_REDIRECT); + ((HttpServletResponse) arg1).setHeader("Location", fullUrl); + return; + } } - // else this is the regular flow - let us the user go through it } } +// else { +// System.out.println("Have user = " + user.getAccessToken(user.getPrimaryLogin()).getId()); +// } } arg2.doFilter(arg0, arg1); - - } - - /** - * Method to determine where to redirect the user - * @param context - * @param arg0 - * @param arg1 - * @throws IOException - */ - private void setInvalidEntryRedirect(ServletContext context, ServletRequest arg0, ServletResponse arg1, String endpoint) throws IOException { - String fullUrl = ((HttpServletRequest) arg0).getRequestURL().toString(); - ((HttpServletResponse) arg1).setStatus(302); - String redirectUrl = ((HttpServletRequest) arg0).getHeader("referer"); - // if no referrer - // then a person hit the endpoint directly - if(redirectUrl == null) { - ((HttpServletRequest) arg0).getSession(true).setAttribute(ENDPOINT_REDIRECT_KEY, fullUrl); - // this will be the deployment name of the app - String loginRedirect = UserResource.getLoginRedirect(); - ((HttpServletResponse) arg1).setStatus(302); - if(loginRedirect != null) { - ((HttpServletResponse) arg1).sendRedirect(loginRedirect); - } else { - String contextPath = context.getContextPath(); - redirectUrl = fullUrl.substring(0, fullUrl.indexOf(contextPath) + contextPath.length()) + NO_USER_HTML; - ((HttpServletResponse) arg1).sendRedirect(redirectUrl); - } - } else { - redirectUrl = redirectUrl + "#!/" + endpoint; - ((HttpServletResponse) arg1).setHeader("redirect", redirectUrl); - ((HttpServletResponse) arg1).sendError(302, "Need to redirect to " + redirectUrl); - } } @Override @@ -268,27 +147,41 @@ public void destroy() { // TODO Auto-generated method stub } + + /** + * Remove the session from the mapper + * @param sessionId + */ + public static void removeSession(String sessionId) { + Iterator iterator = NoUserInSessionTrustedTokenFilter.sessionMapper.keySet().iterator(); + while(iterator.hasNext()) { + String key = iterator.next(); + if(NoUserInSessionTrustedTokenFilter.sessionMapper.get(key).equals(sessionId)) { + // remove this + iterator.remove(); + } + } + } @Override public void init(FilterConfig arg0) throws ServletException { - // TODO Auto-generated method stub - + this.filterConfig = arg0; } - /** - * Due to how the FE security is set up - * Need to ignore some URLs :( - * I REALLY DISLIKE THIS!!! - * @param fullUrl - * @return - */ - protected static boolean isIgnored(String fullUrl) { - for(String ignore : ignoreDueToFE) { - if(fullUrl.endsWith(ignore)) { - return true; + private void setInitParams(ServletRequest arg0) { + // the token name + if(NoUserInSessionTrustedTokenFilter.tokenName == null) { + NoUserInSessionTrustedTokenFilter.tokenName = this.filterConfig.getInitParameter(NoUserInSessionTrustedTokenFilter.TRUSTED_TOKEN_PREFIX); + } + + // the token domains + if(NoUserInSessionTrustedTokenFilter.trustedDomains == null) { + String [] trustedIPs = this.filterConfig.getInitParameter(NoUserInSessionTrustedTokenFilter.TRUSTED_TOKEN_DOMAIN).split(";"); + NoUserInSessionTrustedTokenFilter.trustedDomains = new Vector(); + for(String trustedIP : trustedIPs) { + NoUserInSessionTrustedTokenFilter.trustedDomains.add(trustedIP.toLowerCase()); } } - return false; } } diff --git a/src/prerna/web/conf/NoUserInSessionTrustedTokenListener.java b/src/prerna/web/conf/NoUserInSessionTrustedTokenListener.java new file mode 100644 index 000000000..20fcbee24 --- /dev/null +++ b/src/prerna/web/conf/NoUserInSessionTrustedTokenListener.java @@ -0,0 +1,21 @@ +package prerna.web.conf; + +import javax.servlet.http.HttpSessionEvent; +import javax.servlet.http.HttpSessionListener; + +public class NoUserInSessionTrustedTokenListener implements HttpSessionListener { + + @Override + public void sessionCreated(HttpSessionEvent se) { + // do nothing + + } + + @Override + public void sessionDestroyed(HttpSessionEvent se) { + // clean up the session map + String sessionId = se.getSession().getId(); + NoUserInSessionTrustedTokenFilter.removeSession(sessionId); + } + +} From 6b352722c3c1798075954fc3d9f4ce903c1fdd08 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Sun, 8 Mar 2020 13:53:21 +0000 Subject: [PATCH 0544/1906] BUGFIX ::: Adding the full path to the class git-svn-id: svn://107.170.10.188:8080/Monolith/dev@37550 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 810facd1c5d8a147e800475ad2b99809b2c63145 --- WebContent/WEB-INF/web.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index 43b3d674a..f3df5de9c 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -302,7 +302,7 @@ From f0c6459119c28e6de3f279e5825707c83a1daef0 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Sun, 8 Mar 2020 14:10:55 +0000 Subject: [PATCH 0545/1906] UPDATE ::: Removing custom logout url git-svn-id: svn://107.170.10.188:8080/Monolith/dev@37551 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 47b1a3aae7f9309b52c8797302f84841c4920ff7 --- WebContent/WEB-INF/web.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index f3df5de9c..a0f17b746 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -162,7 +162,7 @@ --> - + --> NoUserInSessionFilter @@ -273,7 +273,7 @@ custom-logout-url - http://google.com + Location to store uploaded file From 62b43b435ba1f1e12c372f830ccda9d2107d98d9 Mon Sep 17 00:00:00 2001 From: pkapaleeswaran Date: Sun, 8 Mar 2020 15:42:06 +0000 Subject: [PATCH 0546/1906] Updates to accomodate for Python Changes i.e. being able to swap between PyServe and JepThread git-svn-id: svn://107.170.10.188:8080/Monolith/dev@37553 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 1b2ec50d04f66b62700955f86d995a55d8ac69ba --- .../semoss/web/services/local/NameServer.java | 74 ++++++++++++++----- .../web/services/local/UserResource.java | 34 ++++++++- src/prerna/web/conf/UserSessionLoader.java | 19 +++-- 3 files changed, 98 insertions(+), 29 deletions(-) diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index 49547430e..ad4db5ec8 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -79,7 +79,9 @@ import prerna.auth.utils.SecurityAppUtils; import prerna.auth.utils.SecurityInsightUtils; import prerna.auth.utils.SecurityQueryUtils; +import prerna.ds.py.FilePyTranslator; import prerna.ds.py.PyExecutorThread; +import prerna.ds.py.PyTranslator; import prerna.ds.py.PyUtils; import prerna.engine.api.IEngine; import prerna.engine.impl.rdf.RemoteSemossSesameEngine; @@ -340,8 +342,12 @@ public Response runPixelSync(@Context HttpServletRequest request){ HttpSession session = null; String sessionId = null; User user = null; + + PyTranslator pyt = null; + Insight insight = null; PyExecutorThread jepThread = null; + boolean securityEnabled = AbstractSecurityUtils.securityEnabled(); //If security is enabled try to get an existing session. //Otherwise get a session with the default user. @@ -364,30 +370,39 @@ public Response runPixelSync(@Context HttpServletRequest request){ } // need to see if the user is enabling python here.. I will assume it is here if(session.getAttribute(Constants.PYTHON) != null) { - jepThread = (PyExecutorThread)session.getAttribute(Constants.PYTHON); + pyt = (PyTranslator)session.getAttribute(Constants.PYTHON); } - if(PyUtils.pyEnabled() && (jepThread == null || session.getAttribute("USER_TUPLE") == null)) { + + + if(PyUtils.pyEnabled() && pyt == null) { // i do not want to make more than 1 py thread per session // and this method is called many times synchronized(sessionId) { - if(session.getAttribute(Constants.PYTHON) != null) { - jepThread = (PyExecutorThread)session.getAttribute(Constants.PYTHON); - } - if(jepThread == null) { - jepThread = PyUtils.getInstance().getJep(); - session.setAttribute(Constants.PYTHON, jepThread); + boolean useFilePy = DIHelper.getInstance().getProperty("USE_PY_FILE") != null && DIHelper.getInstance().getProperty("USE_PY_FILE").equalsIgnoreCase("true"); + if(!useFilePy) + { + if(session.getAttribute(Constants.PYTHON) != null) { + pyt = (PyTranslator)session.getAttribute(Constants.PYTHON); + } + if(jepThread == null) { + jepThread = PyUtils.getInstance().getJep(); + pyt = new PyTranslator(); + pyt.setPy(jepThread); + } } - if(session.getAttribute("USER_TUPLE") == null) + // check to see if the py translator needs to be set ? + else if(useFilePy && session.getAttribute("USER_TUPLE") == null) { session.setAttribute("USER_TUPLE", PyUtils.getInstance().getTempTupleSpace(user, DIHelper.getInstance().getProperty(Constants.INSIGHT_CACHE_DIR))); + pyt = new FilePyTranslator(); } + session.setAttribute(Constants.PYTHON, pyt); } } String jobId = ""; String insightId = request.getParameter("insightId"); String expression = request.getParameter("expression"); - Insight insight = null; // figure out the type of insight // first is temp @@ -418,10 +433,12 @@ public Response runPixelSync(@Context HttpServletRequest request){ // return WebUtility.getResponse(errorMap, 400); // } } -// synchronized(insight) { + // synchronized(insight) { // set the user insight.setUser(user); - insight.setPy(jepThread); + //if(jepThread != null) + // insight.setPy(jepThread); + insight.setPyTranslator(pyt); if(insight.getTupleSpace() == null) { @@ -464,7 +481,8 @@ public Response getPixelPipelinePlan(@Context HttpServletRequest request){ String sessionId = null; User user = null; PyExecutorThread jepThread = null; - + PyTranslator pyt = null; + boolean securityEnabled = AbstractSecurityUtils.securityEnabled(); //If security is enabled try to get an existing session. //Otherwise get a session with the default user. @@ -488,19 +506,36 @@ public Response getPixelPipelinePlan(@Context HttpServletRequest request){ } // need to see if the user is enabling python here.. I will assume it is here if(session.getAttribute(Constants.PYTHON) != null) { - jepThread = (PyExecutorThread)session.getAttribute(Constants.PYTHON); + pyt = (PyTranslator)session.getAttribute(Constants.PYTHON); } - if(PyUtils.pyEnabled() && jepThread == null) { + if(PyUtils.pyEnabled() && pyt == null) { // i do not want to make more than 1 py thread per session // and this method is called many times synchronized(sessionId) { if(session.getAttribute(Constants.PYTHON) != null) { - jepThread = (PyExecutorThread)session.getAttribute(Constants.PYTHON); + pyt = (PyTranslator)session.getAttribute(Constants.PYTHON); } - if(jepThread == null) { - jepThread = PyUtils.getInstance().getJep(); - session.setAttribute(Constants.PYTHON, jepThread); + + boolean useFilePy = DIHelper.getInstance().getProperty("USE_PY_FILE") != null && DIHelper.getInstance().getProperty("USE_PY_FILE").equalsIgnoreCase("true"); + if(!useFilePy) + { + if(session.getAttribute(Constants.PYTHON) != null) { + pyt = (PyTranslator)session.getAttribute(Constants.PYTHON); + } + if(jepThread == null) { + jepThread = PyUtils.getInstance().getJep(); + pyt = new PyTranslator(); + pyt.setPy(jepThread); + } + } + // check to see if the py translator needs to be set ? + else if(useFilePy && session.getAttribute("USER_TUPLE") == null) + { + session.setAttribute("USER_TUPLE", PyUtils.getInstance().getTempTupleSpace(user, DIHelper.getInstance().getProperty(Constants.INSIGHT_CACHE_DIR))); + pyt = new FilePyTranslator(); } + session.setAttribute(Constants.PYTHON, pyt); + } } @@ -524,6 +559,7 @@ public Response getPixelPipelinePlan(@Context HttpServletRequest request){ // set the user insight.setUser(user); insight.setPy(jepThread); + insight.setPyTranslator(pyt); // set in thread ThreadStore.setInsightId(insightId); diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index 55e67f396..69b422877 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -86,7 +86,9 @@ import prerna.auth.utils.NativeUserSecurityUtils; import prerna.auth.utils.SecurityAdminUtils; import prerna.auth.utils.SecurityUpdateUtils; +import prerna.ds.py.FilePyTranslator; import prerna.ds.py.PyExecutorThread; +import prerna.ds.py.PyTranslator; import prerna.ds.py.PyUtils; import prerna.engine.impl.r.IRUserConnection; import prerna.io.connector.IConnectorIOp; @@ -243,8 +245,9 @@ public Void call() throws Exception { // stop python too if(PyUtils.pyEnabled()) { - PyExecutorThread pyThread = (PyExecutorThread) session.getAttribute(Constants.PYTHON); - PyUtils.getInstance().killPyThread(pyThread); + PyTranslator pyt= (PyTranslator) session.getAttribute(Constants.PYTHON); + if(!(pyt instanceof prerna.ds.py.FilePyTranslator)) + PyUtils.getInstance().killPyThread(pyt.getPy()); if(thisUser != null) PyUtils.getInstance().killTempTupleSpace(thisUser); } @@ -362,13 +365,36 @@ private void addAccessToken(AccessToken token, HttpServletRequest request) { semossUser = (User)user; } else { semossUser = new User(); - + PyTranslator pyt = null; // also add the python thread to this user // if security is not on, we have a single py thread for the entire instance // and we dont want to override those variables due to user login if(AbstractSecurityUtils.securityEnabled() && PyUtils.pyEnabled()) { - session.setAttribute(Constants.PYTHON, PyUtils.getInstance().getJep()); + if(session.getAttribute(Constants.PYTHON) != null) { + pyt = (PyTranslator)session.getAttribute(Constants.PYTHON); + } + + boolean useFilePy = DIHelper.getInstance().getProperty("USE_PY_FILE") != null && DIHelper.getInstance().getProperty("USE_PY_FILE").equalsIgnoreCase("true"); + if(!useFilePy) + { + PyExecutorThread jepThread = null; + if(session.getAttribute(Constants.PYTHON) != null) { + pyt = (PyTranslator)session.getAttribute(Constants.PYTHON); + } + if(jepThread == null) { + jepThread = PyUtils.getInstance().getJep(); + pyt = new PyTranslator(); + pyt.setPy(jepThread); + } + } + // check to see if the py translator needs to be set ? + else if(useFilePy && session.getAttribute("USER_TUPLE") == null) + { + session.setAttribute("USER_TUPLE", PyUtils.getInstance().getTempTupleSpace(semossUser, DIHelper.getInstance().getProperty(Constants.INSIGHT_CACHE_DIR))); + pyt = new FilePyTranslator(); + } + session.setAttribute(Constants.PYTHON, pyt); } /*if(session.getAttribute("USER_TUPLE") == null) { diff --git a/src/prerna/web/conf/UserSessionLoader.java b/src/prerna/web/conf/UserSessionLoader.java index 93b98f195..62b28b1f4 100644 --- a/src/prerna/web/conf/UserSessionLoader.java +++ b/src/prerna/web/conf/UserSessionLoader.java @@ -14,7 +14,8 @@ import prerna.auth.SyncUserAppsThread; import prerna.auth.User; import prerna.cache.ICache; -import prerna.ds.py.PyExecutorThread; +import prerna.ds.py.FilePyTranslator; +import prerna.ds.py.PyTranslator; import prerna.ds.py.PyUtils; import prerna.om.Insight; import prerna.om.InsightStore; @@ -64,11 +65,17 @@ public void sessionDestroyed(HttpSessionEvent sessionEvent) { // now drop the thread if(PyUtils.pyEnabled()) { - PyExecutorThread pyThread = (PyExecutorThread) session.getAttribute(Constants.PYTHON); - PyUtils.getInstance().killPyThread(pyThread); - User user = (User)session.getAttribute(Constants.SESSION_USER); - if(user != null) - PyUtils.getInstance().killTempTupleSpace(user); + PyTranslator pyThread = (PyTranslator) session.getAttribute(Constants.PYTHON); + + if(!(pyThread instanceof FilePyTranslator)) + PyUtils.getInstance().killPyThread(pyThread.getPy()); + else + { + User user = (User)session.getAttribute(Constants.SESSION_USER); + if(user != null) + PyUtils.getInstance().killTempTupleSpace(user); + } + LOGGER.info("Dropped all python"); } } From 8b134e5f954be5597f5073a17f8875eb93c77646 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 9 Mar 2020 13:48:09 +0000 Subject: [PATCH 0547/1906] UPDATE ::: Adding null checks that python has been loaded git-svn-id: svn://107.170.10.188:8080/Monolith/dev@37559 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 82d6b7713b468b790729703afdc845c5617e97b6 --- src/prerna/web/conf/UserSessionLoader.java | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/prerna/web/conf/UserSessionLoader.java b/src/prerna/web/conf/UserSessionLoader.java index 62b28b1f4..0665982a0 100644 --- a/src/prerna/web/conf/UserSessionLoader.java +++ b/src/prerna/web/conf/UserSessionLoader.java @@ -66,14 +66,17 @@ public void sessionDestroyed(HttpSessionEvent sessionEvent) { // now drop the thread if(PyUtils.pyEnabled()) { PyTranslator pyThread = (PyTranslator) session.getAttribute(Constants.PYTHON); - - if(!(pyThread instanceof FilePyTranslator)) - PyUtils.getInstance().killPyThread(pyThread.getPy()); - else - { - User user = (User)session.getAttribute(Constants.SESSION_USER); - if(user != null) - PyUtils.getInstance().killTempTupleSpace(user); + if(pyThread != null ) { + if(!(pyThread instanceof FilePyTranslator)) { + if(pyThread.getPy() != null) { + PyUtils.getInstance().killPyThread(pyThread.getPy()); + } + } else { + User user = (User)session.getAttribute(Constants.SESSION_USER); + if(user != null) { + PyUtils.getInstance().killTempTupleSpace(user); + } + } } LOGGER.info("Dropped all python"); } From 004edc6e751f53131a511d1d21a4a6005d0a7445 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 11 Mar 2020 21:47:49 +0000 Subject: [PATCH 0548/1906] UPDATE ::: Also setting the name as the ID so R works properly git-svn-id: svn://107.170.10.188:8080/Monolith/dev@37627 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: cee07081e7371182dcb6d196d2c83d3381fc24c3 --- src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java b/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java index 39716c217..76697cff9 100644 --- a/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java +++ b/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java @@ -96,6 +96,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 AccessToken token = new AccessToken(); token.setProvider(AuthProvider.WINDOWS_USER); token.setId(userId); + token.setName(userId); user.setAccessToken(token); session.setAttribute(Constants.SESSION_USER, user); From ac5a45d166258ad687775548291b83e3308c166f Mon Sep 17 00:00:00 2001 From: kunalppatel9 Date: Fri, 13 Mar 2020 19:29:50 +0000 Subject: [PATCH 0549/1906] BUGFIX ::: Moving log message to execute only when python thread exists; cleans up uneeded logs during health checks git-svn-id: svn://107.170.10.188:8080/Monolith/dev@37653 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 4e23030a69352a51a6780db517cff599d942c03a --- src/prerna/web/conf/UserSessionLoader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prerna/web/conf/UserSessionLoader.java b/src/prerna/web/conf/UserSessionLoader.java index 0665982a0..f144abc41 100644 --- a/src/prerna/web/conf/UserSessionLoader.java +++ b/src/prerna/web/conf/UserSessionLoader.java @@ -77,8 +77,8 @@ public void sessionDestroyed(HttpSessionEvent sessionEvent) { PyUtils.getInstance().killTempTupleSpace(user); } } + LOGGER.info("Dropped all python"); } - LOGGER.info("Dropped all python"); } } From e2a6791767cbd621abfb7f4003b28d861b570bc6 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 17 Mar 2020 13:42:09 +0000 Subject: [PATCH 0550/1906] UPDATE ::: Adding netty jar git-svn-id: svn://107.170.10.188:8080/Monolith/dev@37672 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 79c70e0d28688f4db56e476e9ad4f278c8ec469a --- pom.xml | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/pom.xml b/pom.xml index 6905b5b0f..8d71b4aba 100644 --- a/pom.xml +++ b/pom.xml @@ -1512,18 +1512,13 @@ - - netty-all - 4.1.22.Final - - - * - * - - - + 4.1.47.Final + compile + + org.bouncycastle + bcpkix-jdk15on + + @@ -2777,16 +2783,16 @@ google-api-services-drive v3-rev105-1.23.0 - + + + + com.amazonaws + aws-java-sdk-s3 + 1.11.690 com.syncron.amazonaws From a3eaf3f81c77c52250f245eb47c8d2af8ff581b4 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Sat, 21 Mar 2020 19:17:52 +0000 Subject: [PATCH 0552/1906] UPDATE ::: Updating the mail jar and adding properties for ssl git-svn-id: svn://107.170.10.188:8080/Monolith/dev@37775 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: b1ca2ac669f5bd60d352a5f974f142b8d1566d57 --- pom.xml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index ed43842f6..1d0749638 100644 --- a/pom.xml +++ b/pom.xml @@ -2457,10 +2457,11 @@ quartz-jobs 2.2.1 + - javax.mail - mail - 1.4 + javax.mail + mail + 1.5.0-b01 - + - + getAllUserApps; moved to AdminAppAuthorizationResource & standardized git-svn-id: svn://107.170.10.188:8080/Monolith/dev@38051 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 7b2be8628ed4c198b9e6c39d06e8dcf17601d5d6 --- .../services/local/AuthorizationResource.java | 24 ---------- .../auth/AdminAppAuthorizationResource.java | 47 +++++++------------ 2 files changed, 18 insertions(+), 53 deletions(-) diff --git a/src/prerna/semoss/web/services/local/AuthorizationResource.java b/src/prerna/semoss/web/services/local/AuthorizationResource.java index b6bb1e128..9a1899122 100644 --- a/src/prerna/semoss/web/services/local/AuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/AuthorizationResource.java @@ -207,30 +207,6 @@ public Response getAllUsers(@Context HttpServletRequest request) { return WebUtility.getResponse(ret, 200); } - @GET - @Path("/getAllUserDbs") - @Produces("application/json") - public Response getAllUserDbs(@Context HttpServletRequest request, @QueryParam("userId") String userId) { - User user = null; - try { - user = ResourceUtility.getUser(request); - } catch (IllegalAccessException e) { - Map errorMap = new HashMap(); - errorMap.put("error", "User session is invalid"); - return WebUtility.getResponse(errorMap, 401); - } - - SecurityAdminUtils adminUtils = SecurityAdminUtils.getInstance(user); - if(adminUtils == null) { - Map retMap = new Hashtable(); - retMap.put("error", "User does not have admin priviledges"); - return WebUtility.getResponse(retMap, 400); - } - - List> ret = adminUtils.getAllUserDbs(userId); - return WebUtility.getResponse(ret, 200); - } - @POST @Produces("application/json") @Path("requestAccess") diff --git a/src/prerna/semoss/web/services/local/auth/AdminAppAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/AdminAppAuthorizationResource.java index a9286a91f..f698f4183 100644 --- a/src/prerna/semoss/web/services/local/auth/AdminAppAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/AdminAppAuthorizationResource.java @@ -1,8 +1,6 @@ package prerna.semoss.web.services.local.auth; import java.util.HashMap; -import java.util.Hashtable; -import java.util.List; import java.util.Map; import javax.servlet.ServletContext; @@ -16,7 +14,6 @@ import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; -import prerna.auth.User; import prerna.auth.utils.SecurityAdminUtils; import prerna.semoss.web.services.local.ResourceUtility; import prerna.web.services.util.WebUtility; @@ -48,6 +45,24 @@ public Response getUserApps(@Context HttpServletRequest request) { return WebUtility.getResponse(adminUtils.getAllDatabaseSettings(), 200); } + @POST + @Path("/getAllUserApps") + @Produces("application/json") + public Response getAllUserDbs(@Context HttpServletRequest request, MultivaluedMap form) { + String userId = form.getFirst("userId"); + SecurityAdminUtils adminUtils = null; + + try { + adminUtils = performAdminCheck(request); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + + return WebUtility.getResponse(adminUtils.getAllUserDbs(userId), 200); + } + /** * Get the app users and their permissions * @param request @@ -70,32 +85,6 @@ public Response getAppUsers(@Context HttpServletRequest request, @QueryParam("ap return WebUtility.getResponse(adminUtils.getAppUsers(appId), 200); } - @POST - @Produces("application/json") - @Path("/getAllUserApps") - public Response getAllUserApps(@Context HttpServletRequest request, MultivaluedMap form) { - User user = null; - try { - user = ResourceUtility.getUser(request); - } catch (IllegalAccessException e) { - Map errorMap = new HashMap(); - errorMap.put("error", "User session is invalid"); - return WebUtility.getResponse(errorMap, 401); - } - - String existingUserId = form.getFirst("id"); - - SecurityAdminUtils adminUtils = SecurityAdminUtils.getInstance(user); - if(adminUtils == null) { - Map retMap = new Hashtable(); - retMap.put("error", "User does not have admin priviledges"); - return WebUtility.getResponse(retMap, 400); - } - - List> ret = adminUtils.getAllUserDbs(existingUserId); - return WebUtility.getResponse(ret, 200); - } - /** * Add a user to an app * @param request From 6ac440da948816aba4743702ab133cf20f016c0d Mon Sep 17 00:00:00 2001 From: kunalppatel9 Date: Mon, 30 Mar 2020 18:24:23 +0000 Subject: [PATCH 0560/1906] UPDATE ::: Removing extra netty conflicting netty jars in order to user proper netty for python TCP UPDATE ::: Removing conflicting bouncycastle jar from latest graphstream jar git-svn-id: svn://107.170.10.188:8080/Monolith/dev@38055 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 05438ea32a86a36f30b99ab7a6378d68216d39a8 --- pom.xml | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 1d0749638..a61956db4 100644 --- a/pom.xml +++ b/pom.xml @@ -2370,6 +2370,14 @@ com.sun.jersey jersey-core + + io.netty + netty + + + io.netty + netty-all + @@ -2508,7 +2516,15 @@ org.bouncycastle bcpkix-jdk15on - + + io.netty + netty + + + io.netty + netty-all + + @@ -2736,6 +2752,20 @@ com.datastax.dse dse-java-driver-graph 1.4.0 + + + io.netty + netty + + + io.netty + netty-all + + + io.netty + netty-handler + + @@ -3110,6 +3140,14 @@ junit junit + + bouncycastle + bcmail-jdk14 + + + bouncycastle + bcprov-jdk14 + 1.3 From 4c0563bee8d7833f21177e3d886e68c8af4c314c Mon Sep 17 00:00:00 2001 From: kunalppatel9 Date: Thu, 2 Apr 2020 19:53:10 +0000 Subject: [PATCH 0561/1906] UPDATE ::: Cleaning up sonar pushes git-svn-id: svn://107.170.10.188:8080/Monolith/dev@38104 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 0e46693a536ca42325f50dec9b52dd3d806ba4f1 --- .gitlab-ci.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f4c3fff12..ac86f5d43 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -21,6 +21,7 @@ build_semoss: except: variables: - $RELEASE == "TRUE" + - $SONARPUSH == "TRUE" image: $IMAGE script: - date +%s @@ -58,6 +59,8 @@ build_monolith_sonar: only: refs: - schedules + variables: + - $SONARPUSH == "TRUE" except: variables: - $RELEASE == "TRUE" From febef14ee26e1ef0b2a4112364bbf0250a4d8a19 Mon Sep 17 00:00:00 2001 From: kunalppatel9 Date: Mon, 20 Apr 2020 19:25:03 +0000 Subject: [PATCH 0562/1906] UPDATE ::: Fixing github user call based on api deprecation git-svn-id: svn://107.170.10.188:8080/Monolith/dev@38321 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 5d50db53824e579b74d7ac58d077de0f39020c5c --- src/prerna/semoss/web/services/local/UserResource.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index d6b4fcfee..c28452d4c 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -609,10 +609,9 @@ public Response userinfoGithub(@Context HttpServletRequest request) { } String url = "https://api.github.com/user"; - Hashtable params = new Hashtable(); - params.put("access_token", accessString); + - String output = AbstractHttpHelper.makeGetCall(url, accessString, params, false); + String output = AbstractHttpHelper.makeGetCall(url, accessString, null, true); AccessToken accessToken2 = (AccessToken)BeanFiller.fillFromJson(output, jsonPattern, beanProps, new AccessToken()); try { ret.put("name", accessToken2.getProfile()); From 6315c29aa7b7f709f9c7329b20b42ca025ee23f4 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 21 Apr 2020 16:49:40 +0000 Subject: [PATCH 0563/1906] UPDATE ::: Adding null check for the image to be passed git-svn-id: svn://107.170.10.188:8080/Monolith/dev@38360 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: ba31c1690f988be034f3d545e27cc447109c449e --- src/prerna/upload/ImageUploader.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/prerna/upload/ImageUploader.java b/src/prerna/upload/ImageUploader.java index 2ffaad45b..57521e170 100644 --- a/src/prerna/upload/ImageUploader.java +++ b/src/prerna/upload/ImageUploader.java @@ -167,6 +167,11 @@ public Response uploadInsightImage(@Context HttpServletRequest request) { } } + if(imageFile == null) { + returnMap.put("errorMessage", "Could not find the file to upload for the insight in the request"); + return WebUtility.getResponse(returnMap, 200); + } + if(this.securityEnabled) { HttpSession session = request.getSession(false); if(session != null){ From 4f5cc4788d393289ac7ecb8cd9b094d9ec964a78 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 21 Apr 2020 16:51:10 +0000 Subject: [PATCH 0564/1906] BUGFIX ::: More null checks for uploading insight image git-svn-id: svn://107.170.10.188:8080/Monolith/dev@38361 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: feb506023fb5d4e4b298bfbcfdefd0a0c0f4dd18 --- src/prerna/upload/ImageUploader.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/prerna/upload/ImageUploader.java b/src/prerna/upload/ImageUploader.java index 57521e170..2e1b69fbd 100644 --- a/src/prerna/upload/ImageUploader.java +++ b/src/prerna/upload/ImageUploader.java @@ -169,7 +169,10 @@ public Response uploadInsightImage(@Context HttpServletRequest request) { if(imageFile == null) { returnMap.put("errorMessage", "Could not find the file to upload for the insight in the request"); - return WebUtility.getResponse(returnMap, 200); + return WebUtility.getResponse(returnMap, 400); + } else if(appName == null || insightId == null) { + returnMap.put("errorMessage", "Need to pass the proper app and insight ids to upload the image"); + return WebUtility.getResponse(returnMap, 400); } if(this.securityEnabled) { From f6273a3d9292bc562d199e38a208b3b94a265ce5 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 24 Apr 2020 14:55:23 +0000 Subject: [PATCH 0565/1906] UPDATE ::: Adding new jar for escaping malicious values in log messages UPDATE ::: Fixing utility method to require that the date be exact and not startswith since DATETIME is a popular timestamp option git-svn-id: svn://107.170.10.188:8080/Monolith/dev@38393 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 09528378fcc50f38cd9a56ece4cfcd278ada8a08 --- pom.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pom.xml b/pom.xml index a61956db4..9f392f935 100644 --- a/pom.xml +++ b/pom.xml @@ -2403,6 +2403,11 @@ esapi 2.1.0.1 + + org.owasp.encoder + encoder + 1.2.2 + net.lingala.zip4j zip4j From cc9c74c5521bd7401d0c2c0f0294208296c15835 Mon Sep 17 00:00:00 2001 From: pkapaleeswaran Date: Mon, 27 Apr 2020 15:27:45 +0000 Subject: [PATCH 0566/1906] Update to pass the appnames to user git-svn-id: svn://107.170.10.188:8080/Monolith/dev@38423 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 4e91be3cbd211d69d7ae18e6ed6731916f2b1501 --- src/prerna/semoss/web/services/local/NameServer.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index a7b7c7165..7bbabd1d2 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -994,10 +994,11 @@ public StreamingOutput printEngines(@Context HttpServletRequest request) { return WebUtility.getSO("Not properly authenticated"); } engines = SecurityQueryUtils.getUserDatabaseList(user); + user.setEngines(engines); } else { engines = SecurityQueryUtils.getAllDatabaseList(); } - + return WebUtility.getSO(engines); } From edb9c5cac76b89cbd4ccfe22fb624505f74e598c Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 27 Apr 2020 16:17:09 +0000 Subject: [PATCH 0567/1906] UPDATE ::: Pushing first set of updates for fortify scans - critical changes include proper encoding and normalizing paths git-svn-id: svn://107.170.10.188:8080/Monolith/dev@38426 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 21dcc536e2276444cf42dfdcdc6228317186a906 --- .../services/config/AdminConfigService.java | 29 +- .../config/ServerConfigurationResource.java | 85 +- .../semoss/web/services/local/NameServer.java | 746 ++++++----- .../web/services/local/SessionResource.java | 129 +- .../web/services/local/UserResource.java | 1186 ++++++++--------- src/prerna/upload/DatabaseUploader.java | 93 +- src/prerna/upload/ImageUploader.java | 187 +-- src/prerna/upload/Uploader.java | 53 +- src/prerna/web/conf/AdminStartupFilter.java | 30 +- src/prerna/web/conf/DBLoader.java | 165 +-- src/prerna/web/conf/IASFilter.java | 29 +- .../web/conf/NoUserInSessionFilter.java | 159 +-- src/prerna/web/conf/PIVFilter.java | 38 +- src/prerna/web/conf/UserExistsFilter.java | 41 +- src/prerna/web/conf/util/UserFileLogUtil.java | 37 +- .../web/services/util/InstanceStreamer.java | 326 +++-- 16 files changed, 1773 insertions(+), 1560 deletions(-) diff --git a/src/prerna/semoss/web/services/config/AdminConfigService.java b/src/prerna/semoss/web/services/config/AdminConfigService.java index 48710deb9..91dc5c459 100644 --- a/src/prerna/semoss/web/services/config/AdminConfigService.java +++ b/src/prerna/semoss/web/services/config/AdminConfigService.java @@ -1,6 +1,5 @@ package prerna.semoss.web.services.config; - import java.io.IOException; import java.util.HashMap; import java.util.List; @@ -14,6 +13,7 @@ import javax.ws.rs.core.Context; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; +import org.owasp.encoder.Encode; import com.google.gson.Gson; @@ -23,35 +23,36 @@ @Path("/adminconfig") public class AdminConfigService { - private static final Gson GSON = new Gson(); public static final String ADMIN_REDIRECT_KEY = "ADMIN_REDIRECT_KEY"; - + @POST @Path("/setInitialAdmins") - public Response setInitialAdmins(@Context HttpServletRequest request, @Context HttpServletResponse response, MultivaluedMap form) throws IOException { + public Response setInitialAdmins(@Context HttpServletRequest request, @Context HttpServletResponse response, + MultivaluedMap form) throws IOException { HttpSession session = request.getSession(false); - + String idString = form.getFirst("ids"); - if(idString == null || idString.isEmpty()) { - Map errorMessage = new HashMap(); + if (idString == null || idString.isEmpty()) { + Map errorMessage = new HashMap<>(); errorMessage.put("errorMessage", "Need to send valid ids"); return WebUtility.getResponse(errorMessage, 200); } List ids = GSON.fromJson(idString, List.class); - - for(String id : ids) { + + for (String id : ids) { SecurityUpdateUtils.registerUser(id, true, true); } - if(session.getAttribute(ADMIN_REDIRECT_KEY) != null) { + if (session.getAttribute(ADMIN_REDIRECT_KEY) != null) { String originalRedirect = session.getAttribute(ADMIN_REDIRECT_KEY) + ""; - response.setHeader("redirect", originalRedirect); - response.sendError(302, "Need to redirect to " + originalRedirect); - AdminStartupFilter.setSuccessfulRedirectUrl(originalRedirect); + String encodedRedirectUrl = Encode.forHtml(originalRedirect); + response.setHeader("redirect", encodedRedirectUrl); + response.sendError(302, "Need to redirect to " + encodedRedirectUrl); + AdminStartupFilter.setSuccessfulRedirectUrl(encodedRedirectUrl); } return WebUtility.getResponse("success", 200); } - + } diff --git a/src/prerna/semoss/web/services/config/ServerConfigurationResource.java b/src/prerna/semoss/web/services/config/ServerConfigurationResource.java index f5e535141..b67f1e0da 100644 --- a/src/prerna/semoss/web/services/config/ServerConfigurationResource.java +++ b/src/prerna/semoss/web/services/config/ServerConfigurationResource.java @@ -32,10 +32,11 @@ public class ServerConfigurationResource { private static Map config = null; - + /** - * Generate the configuration options for this instance - * Only need to make this once + * Generate the configuration options for this instance Only need to make this + * once + * * @param request * @return */ @@ -48,91 +49,92 @@ private static Map getConfig(@Context HttpServletRequest request } catch (IllegalAccessException e) { // ignore } - - if(config == null) { + + if (config == null) { // make thread safe - synchronized(ServerConfigurationResource.class) { - if(config == null) { - config = new HashMap(); + synchronized (ServerConfigurationResource.class) { + if (config == null) { + config = new HashMap<>(); // session timeout config.put("timeout", (double) session.getMaxInactiveInterval() / 60); - + // r enabled boolean useR = true; - String useRStr = DIHelper.getInstance().getProperty(Constants.USE_R); - if(useRStr != null) { + String useRStr = DIHelper.getInstance().getProperty(Constants.USE_R); + if (useRStr != null) { useR = Boolean.parseBoolean(useRStr); } config.put("r", useR); - + // python enabled config.put("python", PyUtils.pyEnabled()); - + // security enabled config.put("security", AbstractSecurityUtils.securityEnabled()); config.put("anonymousUsers", AbstractSecurityUtils.anonymousUsersEnabled()); config.put("anonymousUserUploadData", AbstractSecurityUtils.anonymousUserUploadData()); // admin set public enabled boolean adminSetPublic = false; - String adminSetPublicStr = (String) DIHelper.getInstance().getLocalProp(Constants.ADMIN_SET_PUBLIC); - if(adminSetPublicStr != null) { + String adminSetPublicStr = (String) DIHelper.getInstance().getLocalProp(Constants.ADMIN_SET_PUBLIC); + if (adminSetPublicStr != null) { adminSetPublic = Boolean.parseBoolean(adminSetPublicStr); } config.put("adminSetPublic", adminSetPublic); - - // return a boolean if we want to use a dedicated logout page + + // return a boolean if we want to use a dedicated logout page // instead of redirecting to the login page config.put("useLogoutPage", DBLoader.useLogoutPage()); // max file transfer size String fileTransferMax = DIHelper.getInstance().getProperty(Constants.FILE_TRANSFER_LIMIT); - if(fileTransferMax != null) { + if (fileTransferMax != null) { try { config.put("file-limit", Integer.parseInt(fileTransferMax)); - } catch(Exception e) { + } catch (Exception e) { // ignore } } - + // version of the application try { Map versionMap = VersionReactor.getVersionMap(); config.put("version", versionMap); - } catch(Exception e) { + } catch (Exception e) { // ignore } - + // send the default frame type String defaultFrameType = DIHelper.getInstance().getProperty(Constants.DEFAULT_FRAME_TYPE); - if(defaultFrameType == null) { + if (defaultFrameType == null) { defaultFrameType = "GRID"; } config.put("defaultFrameType", defaultFrameType); - - String defaultScriptingLanguage = DIHelper.getInstance().getProperty(Constants.DEFAULT_SCRIPTING_LANGUAGE); - if(defaultScriptingLanguage == null) { + + String defaultScriptingLanguage = DIHelper.getInstance() + .getProperty(Constants.DEFAULT_SCRIPTING_LANGUAGE); + if (defaultScriptingLanguage == null) { defaultScriptingLanguage = "R"; } config.put("defaultScriptingLanguage", defaultScriptingLanguage); // local mode boolean localMode = false; - String localModeStr = DIHelper.getInstance().getProperty(Constants.LOCAL_DEPLOYMENT); - if(localModeStr != null) { + String localModeStr = DIHelper.getInstance().getProperty(Constants.LOCAL_DEPLOYMENT); + if (localModeStr != null) { localMode = Boolean.parseBoolean(localModeStr); } config.put("localDeployment", localMode); } } } - + // do not keep this session // if no user and it is new - if(session.isNew() && user == null) { + if (session.isNew() && user == null) { session.invalidate(); } - - Map myConfiguration = new HashMap(); + + Map myConfiguration = new HashMap<>(); myConfiguration.putAll(config); // append values that can change without restarting the server // logins allowed @@ -143,12 +145,12 @@ private static Map getConfig(@Context HttpServletRequest request myConfiguration.put("theme", AdminThemeUtils.getActiveAdminTheme()); return myConfiguration; } - + @GET @Path("/") @Produces("application/json") public Response getServerConfig(@Context HttpServletRequest request, @Context HttpServletResponse response) { - List newCookies = new Vector(); + List newCookies = new Vector<>(); try { ResourceUtility.getUser(request); @@ -158,18 +160,19 @@ public Response getServerConfig(@Context HttpServletRequest request, @Context Ht // since FE only calls this method on browser startup // clean up any invalid cookies on the browser Cookie[] cookies = request.getCookies(); - if(cookies != null) { - for(Cookie c : cookies) { - if(DBLoader.getSessionIdKey().equals(c.getName())) { + if (cookies != null) { + for (Cookie c : cookies) { + if (DBLoader.getSessionIdKey().equals(c.getName())) { // we need to null this out - NewCookie nullC = new NewCookie(c.getName(), c.getValue(), c.getPath(), c.getDomain(), c.getComment(), 0, c.getSecure()); + NewCookie nullC = new NewCookie(c.getName(), c.getValue(), c.getPath(), c.getDomain(), + c.getComment(), 0, c.getSecure()); newCookies.add(nullC); } } } } - - return WebUtility.getResponse(getConfig(request), 200, newCookies.toArray(new NewCookie[]{})); + + return WebUtility.getResponse(getConfig(request), 200, newCookies.toArray(new NewCookie[] {})); } - + } diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index 7bbabd1d2..9960908c8 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -69,6 +69,8 @@ import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; +import org.apache.log4j.LogManager; +import org.apache.log4j.Logger; import org.jsoup.Jsoup; import com.google.gson.Gson; @@ -116,10 +118,15 @@ @Path("/engine") public class NameServer { + + private static final Logger logger = LogManager.getLogger(NameServer.class); + private static final String ERROR_MESSAGE = "errorMessage"; + private static final String STACKTRACE = "StackTrace: "; // get the directory separator protected static final String DIR_SEPARATOR = java.nio.file.FileSystems.getDefault().getSeparator(); + @Context protected ServletContext context; @@ -167,7 +174,7 @@ public Uploader uploadImage(@Context HttpServletRequest request) { @Path("playsheets") @Produces("application/json") public StreamingOutput getPlaySheets(@Context HttpServletRequest request) { - Hashtable hashTable = new Hashtable(); + Hashtable hashTable = new Hashtable<>(); List sheetNames = PlaySheetRDFMapBasedEnum.getAllSheetNames(); for (int i = 0; i < sheetNames.size(); i++) { @@ -185,78 +192,85 @@ public Object modifyInsight(@Context HttpServletRequest request) { } @Path("i-{insightID}") - public Object getInsightDataFrame(@PathParam("insightID") String insightID, @QueryParam("dataFrameType") String dataFrameType, @Context HttpServletRequest request) { + public Object getInsightDataFrame(@PathParam("insightID") String insightID, + @QueryParam("dataFrameType") String dataFrameType, @Context HttpServletRequest request) { // eventually I want to pick this from session // but for now let us pick it from the insight store - System.out.println("Came into this point.. " + insightID); + logger.debug("Came into this point.. " + insightID); Insight existingInsight = null; if (insightID != null && !insightID.isEmpty() && !insightID.startsWith("new")) { existingInsight = InsightStore.getInstance().get(insightID); - if (existingInsight == null) { - Map errorHash = new HashMap(); - errorHash.put("errorMessage", "Existing insight based on passed insightID is not found"); - // return Response.status(400).entity(WebUtility.getSO(errorHash)).build(); + if (existingInsight == null) { + Map errorHash = new HashMap<>(); + errorHash.put(ERROR_MESSAGE, "Existing insight based on passed insightID is not found"); + // return Response.status(400).entity(WebUtility.getSO(errorHash)).build(); return WebUtility.getResponse(errorHash, 400); - } - // else if(!existingInsight.hasInstantiatedDataMaker()) { - // synchronized(existingInsight) { - // if(!existingInsight.hasInstantiatedDataMaker()) { - //// IDataMaker dm = null; - //// // check if the insight is from a csv - //// if(!existingInsight.isDbInsight()) { - //// // it better end up being created here since it must be serialized as a tinker - //// InsightCache inCache = CacheFactory.getInsightCache(CacheFactory.CACHE_TYPE.CSV_CACHE); - //// dm = inCache.getDMCache(existingInsight); - //// DataMakerComponent dmc = new DataMakerComponent(inCache.getDMFilePath(existingInsight)); - //// - //// Vector dmcList = new Vector(); - //// dmcList.add(dmc); - //// existingInsight.setDataMakerComponents(dmcList); - //// } else { - // // otherwise, grab the serialization if it is there - // IDataMaker dm = CacheFactory.getInsightCache(CacheFactory.CACHE_TYPE.DB_INSIGHT_CACHE).getDMCache(existingInsight); - //// } - // - // if(dm != null) { - // // this means the serialization was good and pushing it into the insight object - // existingInsight.setDataMaker(dm); - // } else { - //// this means the serialization has never occurred - //// could be because hasn't happened, or could be because it is not a tinker frame - // InsightCreateRunner run = new InsightCreateRunner(existingInsight); - // Map webData = run.runWeb(); - // // try to serialize - // // this will do nothing if not a tinker frame - // CacheFactory.getInsightCache(CacheFactory.CACHE_TYPE.DB_INSIGHT_CACHE).cacheInsight(existingInsight, webData); - // } - // } - // } - // } - } - else if(insightID.equals("new")) - { + } + // else if(!existingInsight.hasInstantiatedDataMaker()) { + // synchronized(existingInsight) { + // if(!existingInsight.hasInstantiatedDataMaker()) { + //// IDataMaker dm = null; + //// // check if the insight is from a csv + //// if(!existingInsight.isDbInsight()) { + //// // it better end up being created here since it must be serialized as a + // tinker + //// InsightCache inCache = + // CacheFactory.getInsightCache(CacheFactory.CACHE_TYPE.CSV_CACHE); + //// dm = inCache.getDMCache(existingInsight); + //// DataMakerComponent dmc = new + // DataMakerComponent(inCache.getDMFilePath(existingInsight)); + //// + //// Vector dmcList = new Vector(); + //// dmcList.add(dmc); + //// existingInsight.setDataMakerComponents(dmcList); + //// } else { + // // otherwise, grab the serialization if it is there + // IDataMaker dm = + // CacheFactory.getInsightCache(CacheFactory.CACHE_TYPE.DB_INSIGHT_CACHE).getDMCache(existingInsight); + //// } + // + // if(dm != null) { + // // this means the serialization was good and pushing it into the insight + // object + // existingInsight.setDataMaker(dm); + // } else { + //// this means the serialization has never occurred + //// could be because hasn't happened, or could be because it is not a tinker + // frame + // InsightCreateRunner run = new InsightCreateRunner(existingInsight); + // Map webData = run.runWeb(); + // // try to serialize + // // this will do nothing if not a tinker frame + // CacheFactory.getInsightCache(CacheFactory.CACHE_TYPE.DB_INSIGHT_CACHE).cacheInsight(existingInsight, + // webData); + // } + // } + // } + // } + } else if (insightID.equals("new")) { // get the data frame type and set it from the FE - if(dataFrameType == null) { + if (dataFrameType == null) { dataFrameType = "H2Frame"; } - // existingInsight = new Insight(null, dataFrameType, "Grid"); + // existingInsight = new Insight(null, dataFrameType, "Grid"); existingInsight = new Insight(); // set the user id into the insight - existingInsight.setUser( ((User) request.getSession().getAttribute(Constants.SESSION_USER)) ); + existingInsight.setUser(((User) request.getSession().getAttribute(Constants.SESSION_USER))); InsightStore.getInstance().put(existingInsight); } - // else if(insightID.equals("newDashboard")) { - // // get the data frame type and set it from the FE - //// existingInsight = new Insight(null, "Dashboard", "Dashboard"); - // existingInsight = new Insight(); - // // set the user id into the insight - // existingInsight.setUserId( ((User) request.getSession().getAttribute(Constants.SESSION_USER)).getId() ); - // Dashboard dashboard = new Dashboard(); - // existingInsight.setDataMaker(dashboard); - // String insightid = InsightStore.getInstance().put(existingInsight); - // dashboard.setInsightID(insightid); - // } + // else if(insightID.equals("newDashboard")) { + // // get the data frame type and set it from the FE + //// existingInsight = new Insight(null, "Dashboard", "Dashboard"); + // existingInsight = new Insight(); + // // set the user id into the insight + // existingInsight.setUserId( ((User) + // request.getSession().getAttribute(Constants.SESSION_USER)).getId() ); + // Dashboard dashboard = new Dashboard(); + // existingInsight.setDataMaker(dashboard); + // String insightid = InsightStore.getInstance().put(existingInsight); + // dashboard.setInsightID(insightid); + // } DataframeResource dfr = new DataframeResource(); dfr.insight = existingInsight; @@ -273,24 +287,25 @@ public Response downloadFile(@QueryParam("insightId") String insightId, @QueryPa // and the file id // in order to download the file Insight insight = InsightStore.getInstance().get(insightId); - if(insight == null) { - Map errorMap = new HashMap(); - errorMap.put("errorMessage", "Could not find the insight id"); + if (insight == null) { + Map errorMap = new HashMap<>(); + errorMap.put(ERROR_MESSAGE, "Could not find the insight id"); return WebUtility.getResponse(errorMap, 400); } String filePath = insight.getExportFileLocation(fileKey); File exportFile = new File(filePath); - if(!exportFile.exists()) { - Map errorMap = new HashMap(); - errorMap.put("errorMessage", "Could not find the file for given file id"); + if (!exportFile.exists()) { + Map errorMap = new HashMap<>(); + errorMap.put(ERROR_MESSAGE, "Could not find the file for given file id"); return WebUtility.getResponse(errorMap, 400); } // TODO: put file name cleanup // cannot have things like "," in the name for the attachment String exportName = FilenameUtils.getName(filePath); - return Response.status(200).entity(exportFile).header("Content-Disposition", "attachment; filename=" + exportName).build(); + return Response.status(200).entity(exportFile) + .header("Content-Disposition", "attachment; filename=" + exportName).build(); } /////////////////////////////////////////////// @@ -303,29 +318,31 @@ public Response downloadFile(@QueryParam("insightId") String insightId, @QueryPa @GET @Path("/appImage") - @Produces({MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_SVG_XML}) - public Response getAppImage(@Context final Request coreRequest, @Context HttpServletRequest request, @QueryParam("app") String app) { + @Produces({ MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_SVG_XML }) + public Response getAppImage(@Context final Request coreRequest, @Context HttpServletRequest request, + @QueryParam("app") String app) { AppResource r = new AppResource(); return r.downloadAppImage(coreRequest, request, app); } @GET @Path("/insightImage") - @Produces({MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_SVG_XML}) - public Response getInsightImage(@Context final Request coreRequest, @Context HttpServletRequest request, @QueryParam("app") String app, @QueryParam("rdbmsId") String insightId, @QueryParam("params") String params) { + @Produces({ MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_SVG_XML }) + public Response getInsightImage(@Context final Request coreRequest, @Context HttpServletRequest request, + @QueryParam("app") String app, @QueryParam("rdbmsId") String insightId, + @QueryParam("params") String params) { AppResource r = new AppResource(); return r.downloadInsightImage(coreRequest, request, app, insightId, params); } - + /////////////////////////////////////////////// /////////////////////////////////////////////// /////////////////////////////////////////////// - @POST @Path("/runPixel") @Produces("application/json;charset=utf-8") - public Response runPixelSync(@Context HttpServletRequest request){ + public Response runPixelSync(@Context HttpServletRequest request) { // I need to do a couple of things here // I need to get the basic blocking queue as a singleton // create a thread @@ -333,36 +350,37 @@ public Response runPixelSync(@Context HttpServletRequest request){ // and then let it lose // I need a couple of different statistics for this user and panel - // is user (initially I had he, but then diversity) listening for stdout / stderr or both + // is user (initially I had he, but then diversity) listening for + // stdout, stderr or both // what is the level of log the user wants and the panel wants - // other than that - + // other than that - // there is a jobID status Hash - this can eventually be zookeeper - // Then there is a jobID to message if the user has turned on the stdout, then it has a stack of messages + // Then there is a jobID to message if the user has turned on the stdout, then + // it has a stack of messages // once the job is done, the stack is also cleared HttpSession session = null; - String sessionId = null; + String sessionId = null; User user = null; - + PyTranslator pyt = null; Insight insight = null; PyExecutorThread jepThread = null; String port = null; - boolean securityEnabled = AbstractSecurityUtils.securityEnabled(); - //If security is enabled try to get an existing session. - //Otherwise get a session with the default user. - if(securityEnabled){ + // If security is enabled try to get an existing session. + // Otherwise get a session with the default user. + if (securityEnabled) { session = request.getSession(false); - if(session != null){ + if (session != null) { sessionId = session.getId(); user = ((User) session.getAttribute(Constants.SESSION_USER)); } - - if(user == null) { - Map errorMap = new HashMap(); + + if (user == null) { + Map errorMap = new HashMap<>(); errorMap.put("error", "User session is invalid"); return WebUtility.getResponse(errorMap, 401); } @@ -372,54 +390,52 @@ public Response runPixelSync(@Context HttpServletRequest request){ sessionId = session.getId(); } // need to see if the user is enabling python here.. I will assume it is here - if(session.getAttribute(Constants.PYTHON) != null) { - pyt = (PyTranslator)session.getAttribute(Constants.PYTHON); - port = (String)session.getAttribute("PORT"); + if (session.getAttribute(Constants.PYTHON) != null) { + pyt = (PyTranslator) session.getAttribute(Constants.PYTHON); + port = (String) session.getAttribute("PORT"); } - - - if(PyUtils.pyEnabled() && pyt == null) { + + if (PyUtils.pyEnabled() && pyt == null) { // i do not want to make more than 1 py thread per session - // and this method is called many times - synchronized(sessionId) { - boolean useFilePy = DIHelper.getInstance().getProperty("USE_PY_FILE") != null && DIHelper.getInstance().getProperty("USE_PY_FILE").equalsIgnoreCase("true"); - boolean useTCP = DIHelper.getInstance().getProperty("USE_TCP_PY") != null && DIHelper.getInstance().getProperty("USE_TCP_PY").equalsIgnoreCase("true"); + // and this method is called many times + synchronized (sessionId) { + boolean useFilePy = DIHelper.getInstance().getProperty("USE_PY_FILE") != null + && DIHelper.getInstance().getProperty("USE_PY_FILE").equalsIgnoreCase("true"); + boolean useTCP = DIHelper.getInstance().getProperty("USE_TCP_PY") != null + && DIHelper.getInstance().getProperty("USE_TCP_PY").equalsIgnoreCase("true"); useTCP = useFilePy; // forcing it to be same as TCP - if(!useFilePy) - { - if(session.getAttribute(Constants.PYTHON) != null) { - pyt = (PyTranslator)session.getAttribute(Constants.PYTHON); + if (!useFilePy) { + if (session.getAttribute(Constants.PYTHON) != null) { + pyt = (PyTranslator) session.getAttribute(Constants.PYTHON); } - if(jepThread == null) { + if (jepThread == null) { jepThread = PyUtils.getInstance().getJep(); pyt = new PyTranslator(); pyt.setPy(jepThread); } } // check to see if the py translator needs to be set ? - else if(useFilePy && session.getAttribute("USER_TUPLE") == null) - { - if(useTCP) - { - port = DIHelper.getInstance().getProperty("FORCE_PORT"); // this means someone has started it for debug - if(port == null) - { + else if (useFilePy && session.getAttribute("USER_TUPLE") == null) { + if (useTCP) { + port = DIHelper.getInstance().getProperty("FORCE_PORT"); // this means someone has started it + // for debug + if (port == null) { port = Utility.findOpenPort(); - session.setAttribute("USER_TUPLE", PyUtils.getInstance().startPyServe(user, DIHelper.getInstance().getProperty(Constants.INSIGHT_CACHE_DIR), port)); + session.setAttribute("USER_TUPLE", PyUtils.getInstance().startPyServe(user, + DIHelper.getInstance().getProperty(Constants.INSIGHT_CACHE_DIR), port)); NettyClient nc = new NettyClient(); nc.connect("127.0.0.1", Integer.parseInt(port), false); Thread t = new Thread(nc); t.start(); user.setPyServe(nc); pyt = new TCPPyTranslator(); - ((TCPPyTranslator)pyt).nc = nc; + ((TCPPyTranslator) pyt).nc = nc; } session.setAttribute("PORT", port); - } - else - { - session.setAttribute("USER_TUPLE", PyUtils.getInstance().getTempTupleSpace(user, DIHelper.getInstance().getProperty(Constants.INSIGHT_CACHE_DIR))); + } else { + session.setAttribute("USER_TUPLE", PyUtils.getInstance().getTempTupleSpace(user, + DIHelper.getInstance().getProperty(Constants.INSIGHT_CACHE_DIR))); pyt = new FilePyTranslator(); } } @@ -433,7 +449,7 @@ else if(useFilePy && session.getAttribute("USER_TUPLE") == null) // figure out the type of insight // first is temp - if(insightId == null || insightId.toString().isEmpty() || insightId.equals("undefined")) { + if (insightId == null || insightId.toString().isEmpty() || insightId.equals("undefined")) { insightId = "TempInsightNotStored_" + UUID.randomUUID().toString(); insight = new Insight(); insight.setInsightId(insightId); @@ -447,84 +463,85 @@ else if(useFilePy && session.getAttribute("USER_TUPLE") == null) // you better have a valid id... or else... O_O insight = InsightStore.getInstance().get(insightId); if (insight == null) { - Map errorMap = new HashMap(); - errorMap.put("errorMessage", "Could not find the insight id"); + Map errorMap = new HashMap<>(); + errorMap.put(ERROR_MESSAGE, "Could not find the insight id"); return WebUtility.getResponse(errorMap, 400); } // make sure we have the correct session trying to get this id // #soMuchSecurity - // Set sessionStore = InsightStore.getInstance().getInsightIDsForSession(sessionId); - // if(sessionStore == null || !sessionStore.contains(insightId)) { - // Map errorMap = new HashMap(); - // errorMap.put("errorMessage", "Trying to access insight id from incorrect session"); - // return WebUtility.getResponse(errorMap, 400); - // } + // Set sessionStore = + // InsightStore.getInstance().getInsightIDsForSession(sessionId); + // if(sessionStore == null || !sessionStore.contains(insightId)) { + // Map errorMap = new HashMap(); + // errorMap.put(ERROR_MESSAGE, "Trying to access insight id from incorrect + // session"); + // return WebUtility.getResponse(errorMap, 400); + // } } - // synchronized(insight) { - // set the user - insight.setUser(user); - //if(jepThread != null) - // insight.setPy(jepThread); - insight.setPyTranslator(pyt); - - if(insight.getTupleSpace() == null && session.getAttribute("USER_TUPLE") != null) - { - // try to see if the insight directory has been created in the tuplespace - String curTupleSpace = session.getAttribute("USER_TUPLE")+""; - insight.setTupleSpace(createInsightTupleSpace(curTupleSpace, insightId)); - } - - JobManager manager = JobManager.getManager(); - JobThread jt = manager.makeJob(insightId); - jobId = jt.getJobId(); - session.setAttribute(jobId+"", "TRUE"); - - // set in thread - ThreadStore.setInsightId(insightId); - ThreadStore.setSessionId(sessionId); - ThreadStore.setJobId(jobId); - ThreadStore.setUser(user); + // synchronized(insight) { + // set the user + insight.setUser(user); + // if(jepThread != null) + // insight.setPy(jepThread); + insight.setPyTranslator(pyt); + + if (insight.getTupleSpace() == null && session.getAttribute("USER_TUPLE") != null) { + // try to see if the insight directory has been created in the tuplespace + String curTupleSpace = session.getAttribute("USER_TUPLE") + ""; + insight.setTupleSpace(createInsightTupleSpace(curTupleSpace, insightId)); + } + + JobManager manager = JobManager.getManager(); + JobThread jt = manager.makeJob(insightId); + jobId = jt.getJobId(); + session.setAttribute(jobId + "", "TRUE"); + + // set in thread + ThreadStore.setInsightId(insightId); + ThreadStore.setSessionId(sessionId); + ThreadStore.setJobId(jobId); + ThreadStore.setUser(user); - String job = "META | Job(\"" + jobId + "\", \"" + insightId + "\", \"" + sessionId + "\");"; + String job = "META | Job(\"" + jobId + "\", \"" + insightId + "\", \"" + sessionId + "\");"; // // add the job first // // so we can do things like logging - jt.addPixel(job); - // then add the expression - jt.addPixel(expression); - jt.setInsight(insight); - jt.run(); - PixelRunner pixelRunner = jt.getRunner(); - - manager.flushJob(jobId); - return Response.status(200).entity(PixelStreamUtility.collectPixelData(pixelRunner)).build(); + jt.addPixel(job); + // then add the expression + jt.addPixel(expression); + jt.setInsight(insight); + jt.run(); + PixelRunner pixelRunner = jt.getRunner(); + + manager.flushJob(jobId); + return Response.status(200).entity(PixelStreamUtility.collectPixelData(pixelRunner)).build(); // } } @POST @Path("/getPipeline") @Produces("application/json;charset=utf-8") - public Response getPixelPipelinePlan(@Context HttpServletRequest request){ + public Response getPixelPipelinePlan(@Context HttpServletRequest request) { HttpSession session = null; - String sessionId = null; + String sessionId = null; User user = null; PyExecutorThread jepThread = null; PyTranslator pyt = null; String port = null; - + boolean securityEnabled = AbstractSecurityUtils.securityEnabled(); - //If security is enabled try to get an existing session. - //Otherwise get a session with the default user. - if(securityEnabled){ + // If security is enabled try to get an existing session. + // Otherwise get a session with the default user. + if (securityEnabled) { session = request.getSession(false); - if(session != null){ + if (session != null) { sessionId = session.getId(); user = ((User) session.getAttribute(Constants.SESSION_USER)); } - - if(user == null) { - Map errorMap = new HashMap(); + + if (user == null) { + Map errorMap = new HashMap<>(); errorMap.put("error", "User session is invalid"); - System.out.println("User session is invalid"); + logger.debug("User session is invalid"); return WebUtility.getResponse(errorMap, 401); } } else { @@ -533,64 +550,63 @@ public Response getPixelPipelinePlan(@Context HttpServletRequest request){ sessionId = session.getId(); } // need to see if the user is enabling python here.. I will assume it is here - if(session.getAttribute(Constants.PYTHON) != null) { - pyt = (PyTranslator)session.getAttribute(Constants.PYTHON); + if (session.getAttribute(Constants.PYTHON) != null) { + pyt = (PyTranslator) session.getAttribute(Constants.PYTHON); } - - if(session.getAttribute("PORT") != null) - port = (String)session.getAttribute("PORT"); - - if(PyUtils.pyEnabled() && pyt == null) { + + if (session.getAttribute("PORT") != null) + port = (String) session.getAttribute("PORT"); + + if (PyUtils.pyEnabled() && pyt == null) { // i do not want to make more than 1 py thread per session - // and this method is called many times - synchronized(sessionId) { - if(session.getAttribute(Constants.PYTHON) != null) { - pyt = (PyTranslator)session.getAttribute(Constants.PYTHON); + // and this method is called many times + synchronized (sessionId) { + if (session.getAttribute(Constants.PYTHON) != null) { + pyt = (PyTranslator) session.getAttribute(Constants.PYTHON); } - - boolean useFilePy = DIHelper.getInstance().getProperty("USE_PY_FILE") != null && DIHelper.getInstance().getProperty("USE_PY_FILE").equalsIgnoreCase("true"); - boolean useTCP = DIHelper.getInstance().getProperty("USE_TCP_PY") != null && DIHelper.getInstance().getProperty("USE_TCP_PY").equalsIgnoreCase("true"); + + boolean useFilePy = DIHelper.getInstance().getProperty("USE_PY_FILE") != null + && DIHelper.getInstance().getProperty("USE_PY_FILE").equalsIgnoreCase("true"); + boolean useTCP = DIHelper.getInstance().getProperty("USE_TCP_PY") != null + && DIHelper.getInstance().getProperty("USE_TCP_PY").equalsIgnoreCase("true"); useTCP = useFilePy; // forcing it to be same as TCP - if(!useFilePy) - { - if(session.getAttribute(Constants.PYTHON) != null) { - pyt = (PyTranslator)session.getAttribute(Constants.PYTHON); + if (!useFilePy) { + if (session.getAttribute(Constants.PYTHON) != null) { + pyt = (PyTranslator) session.getAttribute(Constants.PYTHON); } - if(jepThread == null) { + if (jepThread == null) { jepThread = PyUtils.getInstance().getJep(); pyt = new PyTranslator(); pyt.setPy(jepThread); } } // check to see if the py translator needs to be set ? - else if(useFilePy && session.getAttribute("USER_TUPLE") == null) - { - if(useTCP) - { - port = DIHelper.getInstance().getProperty("FORCE_PORT"); // this means someone has started it for debug - if(port == null) - { + else if (useFilePy && session.getAttribute("USER_TUPLE") == null) { + if (useTCP) { + port = DIHelper.getInstance().getProperty("FORCE_PORT"); // this means someone has started it + // for debug + if (port == null) { port = Utility.findOpenPort(); - session.setAttribute("USER_TUPLE", PyUtils.getInstance().startPyServe(user, DIHelper.getInstance().getProperty(Constants.INSIGHT_CACHE_DIR), port)); + session.setAttribute("USER_TUPLE", PyUtils.getInstance().startPyServe(user, + DIHelper.getInstance().getProperty(Constants.INSIGHT_CACHE_DIR), port)); NettyClient nc = new NettyClient(); nc.connect("127.0.0.1", Integer.parseInt(port), false); Thread t = new Thread(nc); t.start(); user.setPyServe(nc); pyt = new TCPPyTranslator(); - ((TCPPyTranslator)pyt).nc = nc; + ((TCPPyTranslator) pyt).nc = nc; } session.setAttribute("PORT", port); - } - else - { - session.setAttribute("USER_TUPLE", PyUtils.getInstance().getTempTupleSpace(user, DIHelper.getInstance().getProperty(Constants.INSIGHT_CACHE_DIR))); + } else { + session.setAttribute("USER_TUPLE", PyUtils.getInstance().getTempTupleSpace(user, + DIHelper.getInstance().getProperty(Constants.INSIGHT_CACHE_DIR))); pyt = new FilePyTranslator(); } } session.setAttribute(Constants.PYTHON, pyt); - + } } @@ -598,19 +614,21 @@ else if(useFilePy && session.getAttribute("USER_TUPLE") == null) String expression = request.getParameter("expression"); Insight insight = InsightStore.getInstance().get(insightId); if (insight == null) { - Map errorMap = new HashMap(); - errorMap.put("errorMessage", "Could not find the insight id"); + Map errorMap = new HashMap<>(); + errorMap.put(ERROR_MESSAGE, "Could not find the insight id"); return WebUtility.getResponse(errorMap, 400); } // make sure we have the correct session trying to get this id // #soMuchSecurity - // Set sessionStore = InsightStore.getInstance().getInsightIDsForSession(sessionId); - // if(sessionStore == null || !sessionStore.contains(insightId)) { - // Map errorMap = new HashMap(); - // errorMap.put("errorMessage", "Trying to access insight id from incorrect session"); - // return WebUtility.getResponse(errorMap, 400); - // } - synchronized(insight) { + // Set sessionStore = + // InsightStore.getInstance().getInsightIDsForSession(sessionId); + // if(sessionStore == null || !sessionStore.contains(insightId)) { + // Map errorMap = new HashMap(); + // errorMap.put(ERROR_MESSAGE, "Trying to access insight id from incorrect + // session"); + // return WebUtility.getResponse(errorMap, 400); + // } + synchronized (insight) { // set the user insight.setUser(user); insight.setPy(jepThread); @@ -620,20 +638,20 @@ else if(useFilePy && session.getAttribute("USER_TUPLE") == null) ThreadStore.setInsightId(insightId); ThreadStore.setSessionId(sessionId); ThreadStore.setUser(user); - + try { - return Response.status(200).entity( - GsonUtility.getDefaultGson().toJson(PixelUtility.generatePipeline(insight, expression)) - ).build(); - } catch(Exception e) { - e.printStackTrace(); - Map errorMap = new HashMap(); - errorMap.put("errorMessage", e.getMessage()); + return Response.status(200) + .entity(GsonUtility.getDefaultGson().toJson(PixelUtility.generatePipeline(insight, expression))) + .build(); + } catch (Exception e) { + logger.error(STACKTRACE, e); + Map errorMap = new HashMap<>(); + errorMap.put(ERROR_MESSAGE, e.getMessage()); return WebUtility.getResponse(errorMap, 400); } } } - + @POST @Path("runPixelAsync") @Produces("application/json;charset=utf-8") @@ -641,7 +659,7 @@ public Response runPixelAsync(@Context HttpServletRequest request) { boolean securityEnabled = AbstractSecurityUtils.securityEnabled(); HttpSession session = null; User user = null; - if(securityEnabled){ + if (securityEnabled) { session = request.getSession(false); user = ((User) session.getAttribute(Constants.SESSION_USER)); } else { @@ -650,7 +668,7 @@ public Response runPixelAsync(@Context HttpServletRequest request) { String sessionId = session.getId(); String jobId = ""; - Map dataReturn = new HashMap(); + Map dataReturn = new HashMap<>(); String insightId = request.getParameter("insightId"); String expression = request.getParameter("expression"); @@ -658,10 +676,10 @@ public Response runPixelAsync(@Context HttpServletRequest request) { // figure out the type of insight // first is temp - if(insightId == null || insightId.toString().isEmpty() || insightId.equals("undefined")) { + if (insightId == null || insightId.toString().isEmpty() || insightId.equals("undefined")) { insight = new Insight(); insight.setInsightId("TempInsightNotStored"); - } else if(insightId.equals("new")) { // need to make a new insight here + } else if (insightId.equals("new")) { // need to make a new insight here insight = new Insight(); InsightStore.getInstance().put(insight); InsightStore.getInstance().addToSessionHash(sessionId, insight.getInsightId()); @@ -669,35 +687,37 @@ public Response runPixelAsync(@Context HttpServletRequest request) { // the session id needs to be checked // you better have a valid id... or else... O_O insight = InsightStore.getInstance().get(insightId); - if(insight == null) { - Map errorMap = new HashMap(); - errorMap.put("errorMessage", "Could not find the insight id"); + if (insight == null) { + Map errorMap = new HashMap<>(); + errorMap.put(ERROR_MESSAGE, "Could not find the insight id"); return WebUtility.getResponse(errorMap, 400); } // make sure we have the correct session trying to get this id // #soMuchSecurity - // Set sessionStore = InsightStore.getInstance().getInsightIDsForSession(sessionId); - // if(sessionStore == null || !sessionStore.contains(insightId)) { - // Map errorMap = new HashMap(); - // errorMap.put("errorMessage", "Trying to access insight id from incorrect session"); - // return WebUtility.getResponse(errorMap, 400); - // } + // Set sessionStore = + // InsightStore.getInstance().getInsightIDsForSession(sessionId); + // if(sessionStore == null || !sessionStore.contains(insightId)) { + // Map errorMap = new HashMap(); + // errorMap.put(ERROR_MESSAGE, "Trying to access insight id from incorrect + // session"); + // return WebUtility.getResponse(errorMap, 400); + // } } - + // synchronized(insight) { - insight.setUser(user); - JobManager manager = JobManager.getManager(); - JobThread jt = manager.makeJob(); - jobId = jt.getJobId(); - session.setAttribute(jobId+"", "TRUE"); + insight.setUser(user); + JobManager manager = JobManager.getManager(); + JobThread jt = manager.makeJob(); + jobId = jt.getJobId(); + session.setAttribute(jobId + "", "TRUE"); // String job = "META | Job(\"" + jobId + "\", \"" + insightId + "\", \"" + sessionId + "\");"; // // so we can do things like logging // jt.addPixel(job); - // then add the expression - jt.addPixel(expression); - jt.setInsight(insight); - jt.start(); - dataReturn.put("jobId", jobId); + // then add the expression + jt.addPixel(expression); + jt.setInsight(insight); + jt.start(); + dataReturn.put("jobId", jobId); // } return WebUtility.getResponse(dataReturn, 200); } @@ -710,7 +730,7 @@ public StreamingOutput result(MultivaluedMap form, @Context Http Object dataReturn = "NULL"; HttpSession session = request.getSession(true); String jobId = form.getFirst("jobId"); - if(session.getAttribute(jobId) != null) { + if (session.getAttribute(jobId) != null) { dataReturn = JobManager.getManager().getOutput(jobId); } return WebUtility.getSO(dataReturn); @@ -725,7 +745,7 @@ public StreamingOutput status(MultivaluedMap form, @Context Http Object dataReturn = "NULL"; HttpSession session = request.getSession(true); String jobId = form.getFirst("jobId"); - if(session.getAttribute(jobId) != null) { + if (session.getAttribute(jobId) != null) { dataReturn = JobManager.getManager().getStatus(jobId); } return WebUtility.getSO(dataReturn); @@ -738,11 +758,11 @@ public StreamingOutput status(MultivaluedMap form, @Context Http public StreamingOutput console(MultivaluedMap form, @Context HttpServletRequest request) { Object dataReturn = "NULL"; String jobId = form.getFirst("jobId"); - // HttpSession session = request.getSession(true); - // if(session.getAttribute(jobId) != null) { - //if(jobId != null) + // HttpSession session = request.getSession(true); + // if(session.getAttribute(jobId) != null) { + // if(jobId != null) dataReturn = JobManager.getManager().getStdOut(jobId); - // } + // } return WebUtility.getSO(dataReturn); } @@ -752,10 +772,10 @@ public StreamingOutput console(MultivaluedMap form, @Context Htt public StreamingOutput error(MultivaluedMap form, @Context HttpServletRequest request) { Object dataReturn = "NULL"; String jobId = form.getFirst("jobId"); - // HttpSession session = request.getSession(true); - // if(session.getAttribute(jobId) != null) { + // HttpSession session = request.getSession(true); + // if(session.getAttribute(jobId) != null) { dataReturn = JobManager.getManager().getError(jobId); - // } + // } return WebUtility.getSO(dataReturn); } @@ -765,25 +785,24 @@ public StreamingOutput error(MultivaluedMap form, @Context HttpS @Produces("application/json") public StreamingOutput terminate(MultivaluedMap form, @Context HttpServletRequest request) { String jobId = form.getFirst("jobId"); - // HttpSession session = request.getSession(true); - // if(session.getAttribute(jobId) != null) { + // HttpSession session = request.getSession(true); + // if(session.getAttribute(jobId) != null) { JobManager.getManager().flushJob(jobId); - // } - // session.removeAttribute(jobId); + // } + // session.removeAttribute(jobId); return WebUtility.getSO("success"); } - // reset job @POST @Path("/reset") @Produces("application/json") public StreamingOutput reset(MultivaluedMap form, @Context HttpServletRequest request) { String jobId = form.getFirst("jobId"); - // HttpSession session = request.getSession(true); - // if(session.getAttribute(jobId) != null) { + // HttpSession session = request.getSession(true); + // if(session.getAttribute(jobId) != null) { JobManager.getManager().resetJob(jobId); - // } + // } return WebUtility.getSO("success"); } @@ -793,36 +812,37 @@ public StreamingOutput reset(MultivaluedMap form, @Context HttpS public String cometTry(@Context HttpServletRequest request) { // I need to create a job id // then I need to start the thread with this job id - // I need to keep the response in the response hash with this job id.. so when I have + // I need to keep the response in the response hash with this job id.. so when I + // have SemossExecutorSingleton threader = SemossExecutorSingleton.getInstance(); - SemossThread newThread = new SemossThread(); - //newThread.setResponse(response); + SemossThread newThread = new SemossThread(); + // newThread.setResponse(response); String jId = threader.execute(newThread); - //ResponseHashSingleton.setResponse(jId, response); - ResponseHashSingleton.setThread(jId, newThread); - //request.getSession(true).setAttribute("JOB_ID", jId); + // ResponseHashSingleton.setResponse(jId, response); + ResponseHashSingleton.setThread(jId, newThread); + // request.getSession(true).setAttribute("JOB_ID", jId); return jId; // store this in session so the user doesn't need to provide this } @GET @Path("/joutput") @Produces("text/plain") - public String getJobOutput(@QueryParam("jobId") String jobId, @Context HttpServletRequest request){ + public String getJobOutput(@QueryParam("jobId") String jobId, @Context HttpServletRequest request) { String output = "Job Longer Available"; - AsyncResponse myResponse = (AsyncResponse)ResponseHashSingleton.getResponseforJobId(jobId); - // if(ResponseHashSingleton.getThread(jobId) != null) - // { - // SemossThread thread = (SemossThread)ResponseHashSingleton.getThread(jobId); - // output = thread.getOutput() + ""; - // } - if(myResponse != null ) { - System.out.println("Respons Done ? " + myResponse.isDone()); - System.out.println("Respons suspended ? " + myResponse.isSuspended()); - System.out.println("Is the response done.. ? " + myResponse.isDone()); + AsyncResponse myResponse = (AsyncResponse) ResponseHashSingleton.getResponseforJobId(jobId); + // if(ResponseHashSingleton.getThread(jobId) != null) + // { + // SemossThread thread = (SemossThread)ResponseHashSingleton.getThread(jobId); + // output = thread.getOutput() + ""; + // } + if (myResponse != null) { + logger.debug("Response Done ? " + myResponse.isDone()); + logger.debug("Response suspended ? " + myResponse.isSuspended()); + logger.debug("Is the response done.. ? " + myResponse.isDone()); myResponse.resume("Hello2222"); myResponse.resume("Hola again"); - System.out.println("MyResponse is not null"); + logger.debug("MyResponse is not null"); } return output; @@ -831,9 +851,10 @@ public String getJobOutput(@QueryParam("jobId") String jobId, @Context HttpServl @GET @Path("/jkill") @Produces("application/xml") - public void killJob(@QueryParam("jobId") String jobId, @Context HttpServletRequest request){ - //AsyncResponse myResponse = (AsyncResponse)ResponseHashSingleton.getResponseforJobId(jobId); - SemossThread thread = (SemossThread)ResponseHashSingleton.getThread(jobId); + public void killJob(@QueryParam("jobId") String jobId, @Context HttpServletRequest request) { + // AsyncResponse myResponse = + // (AsyncResponse)ResponseHashSingleton.getResponseforJobId(jobId); + SemossThread thread = (SemossThread) ResponseHashSingleton.getThread(jobId); thread.setComplete(true); ResponseHashSingleton.removeThread(jobId); @@ -845,8 +866,8 @@ public void killJob(@QueryParam("jobId") String jobId, @Context HttpServletReque myResponse.resume("Hola again"); System.out.println("MyResponse is not null"); } - */ - //return thread.getOutput() + ""; + */ + // return thread.getOutput() + ""; } /////////////////////////////////////////////////////////////// @@ -855,28 +876,30 @@ public void killJob(@QueryParam("jobId") String jobId, @Context HttpServletReque /////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////// - /* * Legacy code that isn't really used anymore * * */ - + /** - * Executes search on MediaWiki/Wikipedia for a given search term and returns the top results. + * Executes search on MediaWiki/Wikipedia for a given search term and returns + * the top results. * - * @param searchTerm Search term to be queried against endpoint - * @return ret Map + * @param searchTerm Search term to be queried against endpoint + * @return ret Map */ @GET @Path("mediawiki/tags") @Produces("application/json") - public StreamingOutput getMediaWikiTagsForSearchTerm(@QueryParam("searchTerm") String searchTerm, @QueryParam("numResults") int numResults) { - String MEDAWIKI_ENDPOINT = "https://en.wikipedia.org/w/api.php?action=query&srlimit=" + numResults + "&list=search&format=json&utf8=1&srprop=snippet&srsearch="; + public StreamingOutput getMediaWikiTagsForSearchTerm(@QueryParam("searchTerm") String searchTerm, + @QueryParam("numResults") int numResults) { + String MEDAWIKI_ENDPOINT = "https://en.wikipedia.org/w/api.php?action=query&srlimit=" + numResults + + "&list=search&format=json&utf8=1&srprop=snippet&srsearch="; String PRODUCT_ONTOLOGY_PREFIX = "http://www.productontology.org/id/"; - StringMap ret = new StringMap(); + StringMap ret = new StringMap<>(); - if(searchTerm != null && !searchTerm.isEmpty()) { + if (searchTerm != null && !searchTerm.isEmpty()) { try { CloseableHttpClient httpClient = null; CloseableHttpResponse response = null; @@ -891,53 +914,58 @@ public StreamingOutput getMediaWikiTagsForSearchTerm(@QueryParam("searchTerm") S if (is != null) { String resp = EntityUtils.toString(entity); Gson gson = new Gson(); - HashMap>>> k = gson.fromJson(resp, HashMap.class);; - List> mapsList = (List>)k.get("query").get("search"); + HashMap>>> k = gson.fromJson(resp, HashMap.class); + List> mapsList = k.get("query").get("search"); - for(StringMap s : mapsList) { + for (StringMap s : mapsList) { ret.put(PRODUCT_ONTOLOGY_PREFIX + s.get("title"), Jsoup.parse(s.get("snippet")).text()); } } } } catch (ClientProtocolException e) { - e.printStackTrace(); + logger.error(STACKTRACE, e); } finally { - httpClient.close(); - response.close(); + if (httpClient != null) { + httpClient.close(); + } + if (response != null) { + response.close(); + } } } catch (IOException e) { - e.printStackTrace(); + logger.error(STACKTRACE, e); } } return WebUtility.getSO(ret); } - - + // gets the engine resource necessary for all engine calls @Path("e-{engine}") - public Object getLocalDatabase(@Context HttpServletRequest request, @PathParam("engine") String engineId, @QueryParam("api") String api) throws IOException { + public Object getLocalDatabase(@Context HttpServletRequest request, @PathParam("engine") String engineId, + @QueryParam("api") String api) throws IOException { boolean security = AbstractSecurityUtils.securityEnabled(); - if(security) { + if (security) { HttpSession session = request.getSession(false); - if(session == null) { + if (session == null) { return WebUtility.getSO("Not properly authenticated"); } User user = (User) session.getAttribute(Constants.SESSION_USER); - if(user == null) { + if (user == null) { return WebUtility.getSO("Not properly authenticated"); } engineId = SecurityQueryUtils.testUserEngineIdForAlias(user, engineId); - if(!SecurityAppUtils.userCanViewEngine(user, engineId)) { - Map errorMap = new HashMap(); - errorMap.put("errorMessage", "Database " + engineId + " does not exist or user does not have access to database"); + if (!SecurityAppUtils.userCanViewEngine(user, engineId)) { + Map errorMap = new HashMap<>(); + errorMap.put(ERROR_MESSAGE, + "Database " + engineId + " does not exist or user does not have access to database"); return WebUtility.getResponse(errorMap, 400); } } else { engineId = MasterDatabaseUtility.testEngineIdIfAlias(engineId); - if(!MasterDatabaseUtility.getAllEngineIds().contains(engineId)) { - Map errorMap = new HashMap(); - errorMap.put("errorMessage", "Database " + engineId + " does not exist"); + if (!MasterDatabaseUtility.getAllEngineIds().contains(engineId)) { + Map errorMap = new HashMap<>(); + errorMap.put(ERROR_MESSAGE, "Database " + engineId + " does not exist"); return WebUtility.getResponse(errorMap, 400); } } @@ -952,7 +980,7 @@ public Object getLocalDatabase(@Context HttpServletRequest request, @PathParam(" public Object getEngineProxy(@PathParam("engine") String db, @Context HttpServletRequest request) { // this is the name server // this needs to return stuff - System.out.println(" Getting DB... " + db); + logger.debug(" Getting DB... " + db); HttpSession session = request.getSession(); IEngine engine = (IEngine) session.getAttribute(db); EngineRemoteResource res = new EngineRemoteResource(); @@ -966,15 +994,15 @@ public Object getCentralNameServer(@QueryParam("centralServerUrl") String url, @Context HttpServletRequest request) { // this is the name server // this needs to return stuff - System.out.println(" Going to central name server ... " + url); + logger.debug(" Going to central name server ... " + url); CentralNameServer cns = new CentralNameServer(); cns.setCentralApi(url); return cns; } - /** * Get the basic information of all engines from solr. + * * @param request * @return all engines. */ @@ -984,13 +1012,13 @@ public Object getCentralNameServer(@QueryParam("centralServerUrl") String url, public StreamingOutput printEngines(@Context HttpServletRequest request) { boolean securityEnabled = AbstractSecurityUtils.securityEnabled(); List> engines = null; - if(securityEnabled) { + if (securityEnabled) { HttpSession session = request.getSession(false); - if(session == null) { + if (session == null) { return WebUtility.getSO("Not properly authenticated"); } User user = (User) session.getAttribute(Constants.SESSION_USER); - if(user == null) { + if (user == null) { return WebUtility.getSO("Not properly authenticated"); } engines = SecurityQueryUtils.getUserDatabaseList(user); @@ -1005,18 +1033,20 @@ public StreamingOutput printEngines(@Context HttpServletRequest request) { @GET @Path("add") @Produces("application/json") - public void addEngine(@Context HttpServletRequest request, @QueryParam("api") String api, @QueryParam("database") String database) { + public void addEngine(@Context HttpServletRequest request, @QueryParam("api") String api, + @QueryParam("database") String database) { // would be cool to give this as an HTML RemoteSemossSesameEngine newEngine = new RemoteSemossSesameEngine(); newEngine.setAPI(api); newEngine.setDatabase(database); HttpSession session = request.getSession(); - ArrayList> engines = (ArrayList>) session.getAttribute(Constants.ENGINES); + ArrayList> engines = (ArrayList>) session + .getAttribute(Constants.ENGINES); // temporal String remoteDbKey = api + ":" + database; newEngine.openDB(null); if (newEngine.isConnected()) { - Hashtable engineHash = new Hashtable(); + Hashtable engineHash = new Hashtable<>(); engineHash.put("name", database); engineHash.put("api", api); engines.add(engineHash); @@ -1033,7 +1063,7 @@ public StreamingOutput printURL(@Context HttpServletRequest request, @Context Ht Hashtable helpHash = null; // would be cool to give this as an HTML if (helpHash == null) { - Hashtable urls = new Hashtable(); + Hashtable urls = new Hashtable<>(); urls.put("Help - this menu (GET)", "hostname:portname/Monolith/api/engine/help"); urls.put("Get All the engines (GET)", "hostname:portname/Monolith/api/engine/all"); urls.put("Perspectives in a specific engine (GET)", @@ -1095,7 +1125,7 @@ public void write(OutputStream outputStream) throws IOException, WebApplicationE Enumeration keys = helpHash.keys(); while (keys.hasMoreElements()) { String key = keys.nextElement(); - String value = (String) helpHash.get(key); + String value = helpHash.get(key); out.println("" + key + ""); out.println("" + value + ""); out.println("
"); @@ -1104,7 +1134,7 @@ public void write(OutputStream outputStream) throws IOException, WebApplicationE out.println(""); out.println(""); } catch (Exception e) { - e.printStackTrace(); + logger.error(STACKTRACE, e); } } }; @@ -1114,7 +1144,7 @@ public void write(OutputStream outputStream) throws IOException, WebApplicationE @Path("runPkql") @Produces("application/json") @Deprecated - public StreamingOutput runPkql(MultivaluedMap form ) { + public StreamingOutput runPkql(MultivaluedMap form) { /* * This is only used for calls that do not require us to hold state * pkql that run in here should not touch a data farme @@ -1123,12 +1153,12 @@ public StreamingOutput runPkql(MultivaluedMap form ) { PKQLRunner runner = new PKQLRunner(); runner.runPKQL(expression); - Map resultHash = new HashMap(); + Map resultHash = new HashMap<>(); // this is technically the only piece of information the FE needs // but to keep the return consistent for them // i am sending back the information in the same weird ordering - Map pkqlDataHash = new HashMap(); + Map pkqlDataHash = new HashMap<>(); pkqlDataHash.put("pkqlData", runner.getResults()); Object[] insightArr = new Object[1]; @@ -1141,21 +1171,24 @@ public StreamingOutput runPkql(MultivaluedMap form ) { //////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////// - ////////////////////////////// START SEARCH BAR /////////////////////////////////// + ////////////////////////////// START SEARCH BAR + //////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////// /** * Complete user search based on string input + * * @return */ @GET @Path("central/context/getAutoCompleteResults") @Produces("application/json") - public StreamingOutput getAutoCompleteResults(@QueryParam("completeTerm") String searchString, @Context HttpServletRequest request) { + public StreamingOutput getAutoCompleteResults(@QueryParam("completeTerm") String searchString, + @Context HttpServletRequest request) { List searchResults = null; boolean securityEnabled = AbstractSecurityUtils.securityEnabled(); - if(securityEnabled) { + if (securityEnabled) { HttpSession session = request.getSession(false); User user = (User) session.getAttribute(Constants.SESSION_USER); searchResults = SecurityInsightUtils.predictUserInsightSearch(user, searchString, "15", "0"); @@ -1166,21 +1199,24 @@ public StreamingOutput getAutoCompleteResults(@QueryParam("completeTerm") String } /** - * Search based on a string input + * Search based on a string input + * * @param form - information passes in from the front end * @return a string version of the results attained from the query search */ /** - * Search based on a string input + * Search based on a string input + * * @param form - information passes in from the front end * @return a string version of the results attained from the query search */ @POST @Path("central/context/getSearchInsightsResults") @Produces("application/json") - public StreamingOutput getSearchInsightsResults(MultivaluedMap form, @Context HttpServletRequest request) { + public StreamingOutput getSearchInsightsResults(MultivaluedMap form, + @Context HttpServletRequest request) { Gson gson = new Gson(); - + // text searched in search bar String searchString = form.getFirst("searchString"); // offset for call @@ -1190,21 +1226,21 @@ public StreamingOutput getSearchInsightsResults(MultivaluedMap f List appIds = null; List tags = null; - + String filterStr = form.getFirst("filterData"); - if(filterStr != null) { + if (filterStr != null) { try { Map> filterMap = gson.fromJson(filterStr, Map.class); appIds = filterMap.get("app_id"); tags = filterMap.get("tags"); - } catch(Exception e) { - e.printStackTrace(); - Map errorMap = new HashMap(); - errorMap.put("errorMessage", "Invalid filter map"); + } catch (Exception e) { + logger.error(STACKTRACE, e); + Map errorMap = new HashMap<>(); + errorMap.put(ERROR_MESSAGE, "Invalid filter map"); return WebUtility.getSO(errorMap); } } - + // If security is enabled, remove the engines in the filters that aren't // accessible - if none in filters, add all accessible engines to filter // list @@ -1221,31 +1257,31 @@ public StreamingOutput getSearchInsightsResults(MultivaluedMap f return WebUtility.getSO(queryResults); } - - private String createInsightTupleSpace(String baseFolder, String insightId) - { + + private String createInsightTupleSpace(String baseFolder, String insightId) { baseFolder = baseFolder.replace("\\","/"); String insightSpecificFolder = baseFolder + "/" + insightId; - File file = new File(insightSpecificFolder); - if(!file.exists()) - { + String normalizedInsightSpecificFolder = Utility.normalizePath(insightSpecificFolder); + File file = new File(normalizedInsightSpecificFolder); + if (!file.exists()) { file.mkdir(); - String command = "addFolder@@" + insightSpecificFolder; - File cmdFile = new File(baseFolder + "/" + insightId +".admin"); + String command = "addFolder@@" + normalizedInsightSpecificFolder; + String normalizedCmdFilePath = Utility.normalizePath(baseFolder + "/" + insightId +".admin"); + File cmdFile = new File(normalizedCmdFilePath); + try { FileUtils.writeStringToFile(cmdFile, command); - } catch (IOException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + } catch (IOException ioe) { + logger.error(STACKTRACE, ioe); } } - return insightSpecificFolder; + return normalizedInsightSpecificFolder; } - //////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////// - /////////////////////////////// END SEARCH BAR //////////////////////////////////// + /////////////////////////////// END SEARCH BAR + //////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////// // @@ -1313,5 +1349,5 @@ private String createInsightTupleSpace(String baseFolder, String insightId) // // return Response.status(200).entity(WebUtility.getSO(DatabasePkqlService.getAllLogicalNamesFromConceptual(conceptualName, parentConceptualName))).build(); // return WebUtility.getResponse(MasterDatabaseUtility.getAllLogicalNamesFromConceptualRDBMS(conceptualName), 200); // } - + } diff --git a/src/prerna/semoss/web/services/local/SessionResource.java b/src/prerna/semoss/web/services/local/SessionResource.java index c47a5c0d8..3e638ac03 100644 --- a/src/prerna/semoss/web/services/local/SessionResource.java +++ b/src/prerna/semoss/web/services/local/SessionResource.java @@ -1,6 +1,7 @@ package prerna.semoss.web.services.local; import java.io.IOException; +import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.HashSet; @@ -19,6 +20,7 @@ import org.apache.log4j.LogManager; import org.apache.log4j.Logger; +import org.owasp.encoder.Encode; import prerna.auth.User; import prerna.auth.utils.AbstractSecurityUtils; @@ -33,36 +35,36 @@ @Path("/session") public class SessionResource { - - private static final Logger LOGGER = LogManager.getLogger(SessionResource.class.getName()); + private static final Logger logger = LogManager.getLogger(SessionResource.class); private static final String CANCEL_INVALIDATION = "cancelInvalidation"; + private static final String STACKTRACE = "StackTrace: "; private Object lock = new Object(); - + @GET @Path("/active") @Produces("application/json;charset=utf-8") public Response getActiveSessions(@Context HttpServletRequest request) { - if(AbstractSecurityUtils.securityEnabled()) { + if (AbstractSecurityUtils.securityEnabled()) { User user; try { user = ResourceUtility.getUser(request); } catch (IllegalAccessException e) { - Map errorMap = new HashMap(); + Map errorMap = new HashMap<>(); errorMap.put("error", "User session is invalid"); return WebUtility.getResponse(errorMap, 401); } - if(!SecurityAdminUtils.userIsAdmin(user)) { - Map errorMap = new HashMap(); + if (!SecurityAdminUtils.userIsAdmin(user)) { + Map errorMap = new HashMap<>(); errorMap.put("error", "User is not an admin"); return WebUtility.getResponse(errorMap, 401); } } - Map ret = new HashMap(); + Map ret = new HashMap<>(); ret.put("activeSessions", SessionCounter.getActiveSessions()); return WebUtility.getResponse(ret, 200); } - + /* * End points for cleanup of the thread to account for closing/opening */ @@ -76,27 +78,27 @@ public Response cleanSession(@Context HttpServletRequest request) { Date execTime = new Date(); HttpSession session = request.getSession(false); - if(session == null) { - LOGGER.info("Invalid session for cleaning"); - Map ret = new HashMap(); + if (session == null) { + logger.info("Invalid session for cleaning"); + Map ret = new HashMap<>(); ret.put("output", "Invalid session"); return WebUtility.getResponse(ret, 400); } - LOGGER.info("Start invalidation of session"); + logger.info("Start invalidation of session"); String sessionId = session.getId(); // clear up insight store InsightStore inStore = InsightStore.getInstance(); Set insightIDs = inStore.getInsightIDsForSession(sessionId); - if(insightIDs != null) { - Set copy = new HashSet(insightIDs); - for(String insightId : copy) { + if (insightIDs != null) { + Set copy = new HashSet<>(insightIDs); + for (String insightId : copy) { Insight insight = InsightStore.getInstance().get(insightId); - if(insight == null) { + if (insight == null) { continue; } InsightUtility.dropInsight(insight); } - LOGGER.info("Successfully removed insight information from session"); + logger.info("Successfully removed insight information from session"); // clear the current session store insightIDs.removeAll(copy); @@ -106,29 +108,30 @@ public Response cleanSession(@Context HttpServletRequest request) { try { Thread.sleep(10_000); } catch (InterruptedException e1) { - e1.printStackTrace(); + Thread.currentThread().interrupt(); + logger.error(STACKTRACE, e1); } String output = null; - if(request.isRequestedSessionIdValid()) { + if (request.isRequestedSessionIdValid()) { // did the FE at any point cancel this clean? Date cancelTime = null; - synchronized(lock) { + synchronized (lock) { cancelTime = (Date) session.getAttribute(CANCEL_INVALIDATION); } - if(cancelTime == null) { + if (cancelTime == null) { // kill the entire session - LOGGER.info("Invalidating session"); + logger.info("Invalidating session"); session.invalidate(); output = "invalidated"; } else { boolean isCancelled = execTime.before(cancelTime); - if(isCancelled) { - LOGGER.info("Cancelled invalidating session"); + if (isCancelled) { + logger.info("Cancelled invalidating session"); output = "cancelled"; } else { // kill the entire session - LOGGER.info("Invalidating session"); + logger.info("Invalidating session"); session.invalidate(); output = "invalidated"; } @@ -137,11 +140,11 @@ public Response cleanSession(@Context HttpServletRequest request) { // in case during the time this was called // the session has been invalidated by some other means // like a logout - LOGGER.info("Session has already been invalidated"); + logger.info("Session has already been invalidated"); output = "invalidated"; } - Map ret = new HashMap(); + Map ret = new HashMap<>(); ret.put("output", output); return WebUtility.getResponse(ret, 200); } @@ -151,77 +154,79 @@ public Response cleanSession(@Context HttpServletRequest request) { @Produces("application/json;charset=utf-8") public Response cancelCleanSession(@Context HttpServletRequest request) { HttpSession session = request.getSession(false); - if(session == null) { - Map ret = new HashMap(); + if (session == null) { + Map ret = new HashMap<>(); ret.put("output", "Invalid session"); return WebUtility.getResponse(ret, 400); } - LOGGER.info("Cancelling invalidation..."); + logger.info("Cancelling invalidation..."); Date d = new Date(); - synchronized(lock) { + synchronized (lock) { session.setAttribute(CANCEL_INVALIDATION, d); } - - Map ret = new HashMap(); + + Map ret = new HashMap<>(); ret.put("output", "cancel"); return WebUtility.getResponse(ret, 200); } - + @GET @Path("/invalidateSession") @Produces("application/json;charset=utf-8") - public void invalidateSession(@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException { + public void invalidateSession(@Context HttpServletRequest request, @Context HttpServletResponse response) + throws IOException { String redirectUrl = request.getHeader("referer"); response.setStatus(302); // redirect to login/logout page - if(DBLoader.useLogoutPage()) { - LOGGER.info("Session ended. Redirect to logout page"); + if (DBLoader.useLogoutPage()) { + logger.info("Session ended. Redirect to logout page"); String customUrl = DBLoader.getCustomLogoutUrl(); - if(customUrl != null && !customUrl.isEmpty()) { + if (customUrl != null && !customUrl.isEmpty()) { response.setHeader("redirect", customUrl); response.sendError(302, "Need to redirect to " + customUrl); } else { - String scheme = request.getScheme(); // http - String serverName = request.getServerName(); // hostname.com - int serverPort = request.getServerPort(); // 8080 - String contextPath = request.getContextPath(); // /Monolith - - redirectUrl = ""; - redirectUrl += scheme + "://" + serverName; - if (serverPort != 80 && serverPort != 443) { - redirectUrl += ":" + serverPort; - } - redirectUrl += contextPath + "/logout/"; + String scheme = request.getScheme(); // http + String serverName = request.getServerName(); // hostname.com + int serverPort = request.getServerPort(); // 8080 + String contextPath = request.getContextPath(); // /Monolith + + redirectUrl = ""; + redirectUrl += scheme + "://" + serverName; + if (serverPort != 80 && serverPort != 443) { + redirectUrl += ":" + serverPort; + } + redirectUrl += contextPath + "/logout/"; response.setHeader("redirect", redirectUrl); response.sendError(302, "Need to redirect to " + redirectUrl); } } else { - LOGGER.info("Session ended. Redirect to login page"); + logger.info("Session ended. Redirect to login page"); redirectUrl = redirectUrl + "#!/login"; - response.setHeader("redirect", redirectUrl); - response.sendError(302, "Need to redirect to " + redirectUrl); + String encodedRedirectUrl = Encode.forHtml(redirectUrl); + response.setHeader("redirect", encodedRedirectUrl); + response.sendError(302, "Need to redirect to " + encodedRedirectUrl); } - + HttpSession session = request.getSession(false); - if(session != null) { - LOGGER.info("User is no longer logged in"); - LOGGER.info("Removing user object from session"); + if (session != null) { + logger.info("User is no longer logged in"); + logger.info("Removing user object from session"); session.removeAttribute(Constants.SESSION_USER); - + session.invalidate(); } } - + @GET @Path("/insights") @Produces("application/json;charset=utf-8") public Response getInsights(@Context HttpServletRequest request) { HttpSession session = request.getSession(false); - if(session == null) { - Map ret = new HashMap(); + if (session == null) { + Map ret = new HashMap<>(); ret.put("output", "Invalid session"); return WebUtility.getResponse(ret, 400); } @@ -229,5 +234,5 @@ public Response getInsights(@Context HttpServletRequest request) { Set ids = InsightStore.getInstance().getInsightIDsForSession(sessionId); return WebUtility.getResponse(ids, 200); } - + } diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index c28452d4c..0aa3df825 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -71,6 +71,7 @@ import org.apache.log4j.Logger; import org.kohsuke.github.GHMyself; import org.kohsuke.github.GitHub; +import org.owasp.encoder.Encode; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; @@ -117,51 +118,53 @@ @Path("/auth") public class UserResource { - private static final Logger LOGGER = LogManager.getLogger(UserResource.class.getName()); - + private static final Logger logger = LogManager.getLogger(UserResource.class.getName()); + + private static final String STACKTRACE = "StackTrace: "; private static Properties socialData = null; private static Map loginsAllowed; - + static { loadSocialProperties(); AppTokens.setSocial(socialData); } - + private static void loadSocialProperties() { FileInputStream fis = null; File f = new File(DIHelper.getInstance().getProperty("SOCIAL")); try { - if(f.exists()) { + if (f.exists()) { socialData = new Properties(); fis = new FileInputStream(f); socialData.load(fis); setLoginsAllowed(); } - } catch (FileNotFoundException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); + } catch (FileNotFoundException fnfe) { + logger.error(STACKTRACE, fnfe); + } catch (IOException ioe) { + logger.error(STACKTRACE, ioe); } catch (Exception e) { - e.printStackTrace(); + logger.error(STACKTRACE, e); } finally { - if(fis != null) { + if (fis != null) { try { fis.close(); } catch (IOException e) { - e.printStackTrace(); + logger.error(STACKTRACE, e); } } } } - + /** * Method to get the redirect URL if defined in the social properties - * @return + * + * @return */ public static String getLoginRedirect() { return socialData.getProperty("redirect") + "/login"; } - + private static void setLoginsAllowed() { boolean nativeLogin = Boolean.parseBoolean(socialData.getProperty("native_login")); boolean githubLogin = Boolean.parseBoolean(socialData.getProperty("github_login")); @@ -179,50 +182,52 @@ private static void setLoginsAllowed() { UserResource.loginsAllowed.put("cac", cacLogin); UserResource.loginsAllowed.put("registration", registration); } - + public static Map getLoginsAllowed() { return UserResource.loginsAllowed; } - + @GET @Path("/logins") public Response getAllLogins(@Context HttpServletRequest request) { - List newCookies = new Vector(); + List newCookies = new Vector<>(); HttpSession session = request.getSession(false); User semossUser = null; - if(session != null) { + if (session != null) { semossUser = (User) request.getSession().getAttribute(Constants.SESSION_USER); } - - if(semossUser == null) { + + if (semossUser == null) { // not authenticated // remove any cookies we shouldn't have Cookie[] cookies = request.getCookies(); - if(cookies != null) { - for(Cookie c : cookies) { - if(DBLoader.getSessionIdKey().equals(c.getName())) { + if (cookies != null) { + for (Cookie c : cookies) { + if (DBLoader.getSessionIdKey().equals(c.getName())) { // we need to null this out - NewCookie nullC = new NewCookie(c.getName(), c.getValue(), c.getPath(), c.getDomain(), c.getComment(), 0, c.getSecure()); + NewCookie nullC = new NewCookie(c.getName(), c.getValue(), c.getPath(), c.getDomain(), + c.getComment(), 0, c.getSecure()); newCookies.add(nullC); } } } } - + Map retMap = User.getLoginNames(semossUser); - return WebUtility.getResponse(retMap, 200, newCookies.toArray(new NewCookie[]{})); + return WebUtility.getResponse(retMap, 200, newCookies.toArray(new NewCookie[] {})); } - + @GET @Produces("application/json") @Path("/logout/{provider}") - public Response logout(@PathParam("provider") String provider, @Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException { + public Response logout(@PathParam("provider") String provider, @Context HttpServletRequest request, + @Context HttpServletResponse response) throws IOException { boolean noUser = false; boolean removed = false; - + HttpSession session = request.getSession(); User thisUser = (User) session.getAttribute(Constants.SESSION_USER); - + // Stop R if (thisUser != null) { IRUserConnection rserve = thisUser.getRcon(); @@ -235,35 +240,32 @@ public Void call() throws Exception { try { rserve.stopR(); } catch (Exception e) { - LOGGER.warn("Unable to stop R."); + logger.warn("Unable to stop R."); } return null; } - }); + }); } finally { executor.shutdown(); } } } - - // stop python too - if(PyUtils.pyEnabled()) { - PyTranslator pyt= (PyTranslator) session.getAttribute(Constants.PYTHON); - if(pyt instanceof prerna.ds.py.PyTranslator) + // stop python too + if (PyUtils.pyEnabled()) { + PyTranslator pyt = (PyTranslator) session.getAttribute(Constants.PYTHON); + if (pyt instanceof prerna.ds.py.PyTranslator) PyUtils.getInstance().killPyThread(pyt.getPy()); - if(pyt instanceof FilePyTranslator && thisUser != null) + if (pyt instanceof FilePyTranslator && thisUser != null) PyUtils.getInstance().killTempTupleSpace(thisUser); - if(pyt instanceof TCPPyTranslator) - { + if (pyt instanceof TCPPyTranslator) { NettyClient nc = thisUser.getPyServe(); - String dir = (String)session.getAttribute("USER_TUPLE"); + String dir = (String) session.getAttribute("USER_TUPLE"); nc.stopPyServe(dir); } } - - if(provider.equalsIgnoreCase("ALL")) { + if (provider.equalsIgnoreCase("ALL")) { // remove the user from session call it a day request.getSession().removeAttribute(Constants.SESSION_USER); removed = true; @@ -272,78 +274,79 @@ public Void call() throws Exception { AuthProvider token = AuthProvider.valueOf(provider.toUpperCase()); String assetEngineId = null; String workspaceEngineId = null; - - if(thisUser.getLogins().size() == 1) { + + if (thisUser.getLogins().size() == 1) { assetEngineId = thisUser.getAssetEngineId(token); workspaceEngineId = thisUser.getWorkspaceEngineId(token); } removed = thisUser.dropAccessToken(token); - if(thisUser.getLogins().isEmpty()) { + if (thisUser.getLogins().isEmpty()) { noUser = true; } else { request.getSession().setAttribute(Constants.SESSION_USER, thisUser); - - SyncUserAppsThread sync = new SyncUserAppsThread(workspaceEngineId, assetEngineId); + + SyncUserAppsThread sync = new SyncUserAppsThread(workspaceEngineId, assetEngineId); Thread t = new Thread(sync); t.start(); - + // put the new map for the user space session.setAttribute(Constants.USER_WORKSPACE_IDS, thisUser.getWorkspaceEngineMap()); session.setAttribute(Constants.USER_ASSET_IDS, thisUser.getAssetEngineMap()); } } - + // if there are no users and there is security // redirect the user // and invalidate the session - if(noUser && AbstractSecurityUtils.securityEnabled()) { - LOGGER.info("User is no longer logged in"); - LOGGER.info("Removing user object from session"); + if (noUser && AbstractSecurityUtils.securityEnabled()) { + logger.info("User is no longer logged in"); + logger.info("Removing user object from session"); session.removeAttribute(Constants.SESSION_USER); // well, you have logged out and we always require a login // so i will redirect you response.setStatus(302); - + String customUrl = DBLoader.getCustomLogoutUrl(); - if(customUrl != null && !customUrl.isEmpty()) { + if (customUrl != null && !customUrl.isEmpty()) { response.setHeader("redirect", customUrl); response.sendError(302, "Need to redirect to " + customUrl); } else { String redirectUrl = request.getHeader("referer"); - if(DBLoader.useLogoutPage()) { - String scheme = request.getScheme(); // http - String serverName = request.getServerName(); // hostname.com - int serverPort = request.getServerPort(); // 8080 - String contextPath = request.getContextPath(); // /Monolith - - redirectUrl = ""; - redirectUrl += scheme + "://" + serverName; - if (serverPort != 80 && serverPort != 443) { - redirectUrl += ":" + serverPort; - } - redirectUrl += contextPath + "/logout/"; + if (DBLoader.useLogoutPage()) { + String scheme = request.getScheme(); // http + String serverName = request.getServerName(); // hostname.com + int serverPort = request.getServerPort(); // 8080 + String contextPath = request.getContextPath(); // /Monolith + + redirectUrl = ""; + redirectUrl += scheme + "://" + serverName; + if (serverPort != 80 && serverPort != 443) { + redirectUrl += ":" + serverPort; + } + redirectUrl += contextPath + "/logout/"; response.setHeader("redirect", redirectUrl); response.sendError(302, "Need to redirect to " + redirectUrl); } else { redirectUrl = redirectUrl + "#!/login"; - response.setHeader("redirect", redirectUrl); - response.sendError(302, "Need to redirect to " + redirectUrl); + String encodedRedirectUrl = Encode.forHtml(redirectUrl); + response.setHeader("redirect", encodedRedirectUrl); + response.sendError(302, "Need to redirect to " + encodedRedirectUrl); } } - + // remove the cookie from the browser // for the session id - LOGGER.info("Removing session token"); + logger.info("Removing session token"); Cookie[] cookies = request.getCookies(); - if(cookies != null) { - for(Cookie c : cookies) { - if(DBLoader.getSessionIdKey().equals(c.getName())) { + if (cookies != null) { + for (Cookie c : cookies) { + if (DBLoader.getSessionIdKey().equals(c.getName())) { // we need to null this out Cookie nullC = new Cookie(c.getName(), c.getValue()); nullC.setPath(c.getPath()); nullC.setSecure(c.getSecure()); nullC.setVersion(c.getVersion()); - if(c.getDomain() != null) { + if (c.getDomain() != null) { nullC.setDomain(c.getDomain()); } nullC.setMaxAge(0); @@ -351,20 +354,20 @@ public Void call() throws Exception { } } } - + // invalidate the session session.invalidate(); return null; } - - - Map ret = new Hashtable(); + + Map ret = new Hashtable<>(); ret.put("success", removed); - return WebUtility.getResponse(ret, 200); + return WebUtility.getResponse(ret, 200); } - + /** * Method to add an access token to a user + * * @param token * @param request */ @@ -372,33 +375,32 @@ private void addAccessToken(AccessToken token, HttpServletRequest request) { User semossUser = null; HttpSession session = request.getSession(); Object user = session.getAttribute(Constants.SESSION_USER); - if(user != null) { - semossUser = (User)user; + if (user != null) { + semossUser = (User) user; } else { semossUser = new User(); PyTranslator pyt = null; // also add the python thread to this user // if security is not on, we have a single py thread for the entire instance // and we dont want to override those variables due to user login - if(AbstractSecurityUtils.securityEnabled() && PyUtils.pyEnabled()) { - - if(session.getAttribute(Constants.PYTHON) != null) { - pyt = (PyTranslator)session.getAttribute(Constants.PYTHON); + if (AbstractSecurityUtils.securityEnabled() && PyUtils.pyEnabled()) { + + if (session.getAttribute(Constants.PYTHON) != null) { + pyt = (PyTranslator) session.getAttribute(Constants.PYTHON); } - - boolean useFilePy = DIHelper.getInstance().getProperty("USE_PY_FILE") != null && DIHelper.getInstance().getProperty("USE_PY_FILE").equalsIgnoreCase("true"); - boolean useTCP = DIHelper.getInstance().getProperty("USE_TCP_PY") != null && DIHelper.getInstance().getProperty("USE_TCP_PY").equalsIgnoreCase("true"); + + boolean useFilePy = DIHelper.getInstance().getProperty("USE_PY_FILE") != null + && DIHelper.getInstance().getProperty("USE_PY_FILE").equalsIgnoreCase("true"); + boolean useTCP = DIHelper.getInstance().getProperty("USE_TCP_PY") != null + && DIHelper.getInstance().getProperty("USE_TCP_PY").equalsIgnoreCase("true"); useTCP = useFilePy; // forcing it to be same as TCP - - - - if(!useFilePy) - { + + if (!useFilePy) { PyExecutorThread jepThread = null; - if(session.getAttribute(Constants.PYTHON) != null) { - pyt = (PyTranslator)session.getAttribute(Constants.PYTHON); + if (session.getAttribute(Constants.PYTHON) != null) { + pyt = (PyTranslator) session.getAttribute(Constants.PYTHON); } - if(jepThread == null) { + if (jepThread == null) { jepThread = PyUtils.getInstance().getJep(); pyt = new PyTranslator(); pyt.setPy(jepThread); @@ -406,28 +408,26 @@ private void addAccessToken(AccessToken token, HttpServletRequest request) { } // check to see if the py translator needs to be set ? // check to see if the py translator needs to be set ? - else if(useFilePy && session.getAttribute("USER_TUPLE") == null) - { - if(useTCP) - { - String port = DIHelper.getInstance().getProperty("FORCE_PORT"); // this means someone has started it for debug - if(port == null) - { + else if (useFilePy && session.getAttribute("USER_TUPLE") == null) { + if (useTCP) { + String port = DIHelper.getInstance().getProperty("FORCE_PORT"); // this means someone has + // started it for debug + if (port == null) { port = Utility.findOpenPort(); - session.setAttribute("USER_TUPLE", PyUtils.getInstance().startPyServe(semossUser, DIHelper.getInstance().getProperty(Constants.INSIGHT_CACHE_DIR), port)); + session.setAttribute("USER_TUPLE", PyUtils.getInstance().startPyServe(semossUser, + DIHelper.getInstance().getProperty(Constants.INSIGHT_CACHE_DIR), port)); NettyClient nc = new NettyClient(); nc.connect("127.0.0.1", Integer.parseInt(port), false); Thread t = new Thread(nc); t.start(); semossUser.setPyServe(nc); pyt = new TCPPyTranslator(); - ((TCPPyTranslator)pyt).nc = nc; + ((TCPPyTranslator) pyt).nc = nc; } session.setAttribute("PORT", port); - } - else - { - session.setAttribute("USER_TUPLE", PyUtils.getInstance().getTempTupleSpace(semossUser, DIHelper.getInstance().getProperty(Constants.INSIGHT_CACHE_DIR))); + } else { + session.setAttribute("USER_TUPLE", PyUtils.getInstance().getTempTupleSpace(semossUser, + DIHelper.getInstance().getProperty(Constants.INSIGHT_CACHE_DIR))); pyt = new FilePyTranslator(); } } @@ -446,8 +446,7 @@ else if(useFilePy && session.getAttribute("USER_TUPLE") == null) // add new users into the database SecurityUpdateUtils.addOAuthUser(token); } - - + ////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////// @@ -456,8 +455,7 @@ else if(useFilePy && session.getAttribute("USER_TUPLE") == null) /** * User info method calls */ - - + /** * Gets user info for GoogleDrive */ @@ -465,14 +463,14 @@ else if(useFilePy && session.getAttribute("USER_TUPLE") == null) @Produces("application/json") @Path("/userinfo/google") public Response userinfoGoogle(@Context HttpServletRequest request) { - Map ret = new Hashtable(); + Map ret = new Hashtable<>(); User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - String [] beanProps = {"name", "profile"}; + String[] beanProps = { "name", "profile" }; String jsonPattern = "[name, picture]"; String accessString = null; try { - if(user == null) { + if (user == null) { ret.put("ERROR", "Log into your Google account"); return WebUtility.getResponse(ret, 200); } else { @@ -483,26 +481,27 @@ public Response userinfoGoogle(@Context HttpServletRequest request) { ret.put("ERROR", "Log into your Google account"); return WebUtility.getResponse(ret, 200); } - + String url = "https://www.googleapis.com/oauth2/v3/userinfo"; Hashtable params = new Hashtable(); params.put("access_token", accessString); params.put("alt", "json"); String output = AbstractHttpHelper.makeGetCall(url, accessString, params, true); - AccessToken accessToken2 = (AccessToken)BeanFiller.fillFromJson(output, jsonPattern, beanProps, new AccessToken()); + AccessToken accessToken2 = (AccessToken) BeanFiller.fillFromJson(output, jsonPattern, beanProps, + new AccessToken()); try { ret.put("name", accessToken2.getName()); - if(accessToken2.getProfile() != null) { + if (accessToken2.getProfile() != null) { ret.put("picture", accessToken2.getProfile()); } } catch (Exception e) { - e.printStackTrace(); + logger.error(STACKTRACE, e); } - + return WebUtility.getResponse(ret, 200); } - + /** * Gets user info for OneDrive */ @@ -510,33 +509,33 @@ public Response userinfoGoogle(@Context HttpServletRequest request) { @Produces("application/json") @Path("/userinfo/ms") public Response userinfoOneDrive(@Context HttpServletRequest request) { - Map ret = new Hashtable(); + Map ret = new Hashtable<>(); User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - String [] beanProps = {"name"}; + String[] beanProps = { "name" }; String jsonPattern = "[displayName]"; String accessString = null; - try{ - if(user == null) { + try { + if (user == null) { ret.put("ERROR", "Log into your Microsoft account"); } else { AccessToken msToken = user.getAccessToken(AuthProvider.MS); accessString = msToken.getAccess_token(); String url = "https://graph.microsoft.com/v1.0/me/"; String output = AbstractHttpHelper.makeGetCall(url, accessString, null, true); - AccessToken accessToken2 = (AccessToken)BeanFiller.fillFromJson(output, jsonPattern, beanProps, new AccessToken()); + AccessToken accessToken2 = (AccessToken) BeanFiller.fillFromJson(output, jsonPattern, beanProps, + new AccessToken()); String name = accessToken2.getName(); ret.put("name", name); } return WebUtility.getResponse(ret, 200); - } - catch (Exception e) { + } catch (Exception e) { ret.put("ERROR", "Log into your Microsoft account"); return WebUtility.getResponse(ret, 200); } } - + /** * Gets user info for DropBox */ @@ -544,43 +543,43 @@ public Response userinfoOneDrive(@Context HttpServletRequest request) { @Produces("application/json") @Path("/userinfo/dropbox") public Response userinfoDropbox(@Context HttpServletRequest request) { - Map ret = new Hashtable(); + Map ret = new Hashtable<>(); User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - String [] beanProps = {"name", "profile"}; // add is done when you have a list + String[] beanProps = { "name", "profile" }; // add is done when you have a list String jsonPattern = "[name.display_name, profile_photo_url]"; String accessString = null; try { - if(user == null){ + if (user == null) { ret.put("ERROR", "Log into your DropBox account"); return WebUtility.getResponse(ret, 200); } else { AccessToken dropToken = user.getAccessToken(AuthProvider.DROPBOX); - accessString=dropToken.getAccess_token(); + accessString = dropToken.getAccess_token(); } - } - catch (Exception e) { + } catch (Exception e) { ret.put("ERROR", "Log into your DropBox account"); return WebUtility.getResponse(ret, 200); } String url = "https://api.dropboxapi.com/2/users/get_current_account"; String output = AbstractHttpHelper.makePostCall(url, accessString, null, true); - AccessToken accessToken2 = (AccessToken)BeanFiller.fillFromJson(output, jsonPattern, beanProps, new AccessToken()); + AccessToken accessToken2 = (AccessToken) BeanFiller.fillFromJson(output, jsonPattern, beanProps, + new AccessToken()); try { - if(accessToken2.getProfile() == null||accessToken2.getProfile().equalsIgnoreCase("null")) { + if (accessToken2.getProfile() == null || accessToken2.getProfile().equalsIgnoreCase("null")) { ret.put("picture", ""); } else { ret.put("picture", accessToken2.getProfile()); } ret.put("name", accessToken2.getName()); } catch (Exception e) { - e.printStackTrace(); + logger.error(STACKTRACE, e); } return WebUtility.getResponse(ret, 200); } - + /** * Gets user info for Github */ @@ -588,20 +587,20 @@ public Response userinfoDropbox(@Context HttpServletRequest request) { @Produces("application/json") @Path("/userinfo/github") public Response userinfoGithub(@Context HttpServletRequest request) { - Map ret = new Hashtable(); + Map ret = new Hashtable<>(); User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - String [] beanProps = {"name", "profile"}; // add is done when you have a list + String[] beanProps = { "name", "profile" }; // add is done when you have a list String jsonPattern = "[name,login]"; String accessString = null; - try{ - if(user == null) { + try { + if (user == null) { ret.put("ERROR", "Log into your Github account"); return WebUtility.getResponse(ret, 200); } else { AccessToken gitToken = user.getAccessToken(AuthProvider.GITHUB); - accessString=gitToken.getAccess_token(); + accessString = gitToken.getAccess_token(); } } catch (Exception e) { ret.put("ERROR", "Log into your Github account"); @@ -627,11 +626,10 @@ public Response userinfoGithub(@Context HttpServletRequest request) { ////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////// - + /** * Login methods + redirect methods */ - /** * Logs user in through salesforce @@ -639,25 +637,26 @@ public Response userinfoGithub(@Context HttpServletRequest request) { @GET @Produces("application/json") @Path("/login/sf") - public Response loginSF(@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException { + public Response loginSF(@Context HttpServletRequest request, @Context HttpServletResponse response) + throws IOException { /* * Try to log in the user * If they are not logged in * Redirect the FE */ - + User userObj = (User) request.getSession().getAttribute(Constants.SESSION_USER); String queryString = request.getQueryString(); - if(queryString != null && queryString.contains("code=")) { - if(userObj == null || userObj.getAccessToken(AuthProvider.SF) == null) { + if (queryString != null && queryString.contains("code=")) { + if (userObj == null || userObj.getAccessToken(AuthProvider.SF) == null) { String[] outputs = AbstractHttpHelper.getCodes(queryString); String prefix = "sf_"; - String clientId = socialData.getProperty(prefix+"client_id"); - String clientSecret = socialData.getProperty(prefix+"secret_key"); - String redirectUri = socialData.getProperty(prefix+"redirect_uri"); + String clientId = socialData.getProperty(prefix + "client_id"); + String clientSecret = socialData.getProperty(prefix + "secret_key"); + String redirectUri = socialData.getProperty(prefix + "redirect_uri"); - System.out.println(">> " + request.getQueryString()); + logger.debug(">> " + request.getQueryString()); Hashtable params = new Hashtable(); params.put("client_id", clientId); @@ -667,9 +666,9 @@ public Response loginSF(@Context HttpServletRequest request, @Context HttpServle params.put("client_secret", clientSecret); String url = "https://login.salesforce.com/services/oauth2/token"; - + AccessToken accessToken = AbstractHttpHelper.getAccessToken(url, params, true, true); - if(accessToken == null) { + if (accessToken == null) { // not authenticated response.setStatus(302); response.sendRedirect(getSFRedirect(request)); @@ -678,35 +677,33 @@ public Response loginSF(@Context HttpServletRequest request, @Context HttpServle accessToken.setProvider(AuthProvider.SF); addAccessToken(accessToken, request); - System.out.println("Access Token is.. " + accessToken.getAccess_token()); + logger.debug("Access Token is.. " + accessToken.getAccess_token()); } } // grab the user again userObj = (User) request.getSession().getAttribute(Constants.SESSION_USER); - if(userObj == null || userObj.getAccessToken(AuthProvider.SF) == null) { + if (userObj == null || userObj.getAccessToken(AuthProvider.SF) == null) { // not authenticated response.setStatus(302); response.sendRedirect(getSFRedirect(request)); return null; } - + setMainPageRedirect(request, response); return null; } - + private String getSFRedirect(HttpServletRequest request) throws UnsupportedEncodingException { String prefix = "sf_"; - String clientId = socialData.getProperty(prefix+"client_id"); - String redirectUri = socialData.getProperty(prefix+"redirect_uri"); + String clientId = socialData.getProperty(prefix + "client_id"); + String redirectUri = socialData.getProperty(prefix + "redirect_uri"); - String redirectUrl = "https://login.salesforce.com/services/oauth2/authorize?" + - "client_id=" + clientId + - "&response_type=code" + - "&redirect_uri=" + redirectUri + - "&scope=" + URLEncoder.encode("api", "UTF-8"); + String redirectUrl = "https://login.salesforce.com/services/oauth2/authorize?" + "client_id=" + clientId + + "&response_type=code" + "&redirect_uri=" + redirectUri + "&scope=" + + URLEncoder.encode("api", "UTF-8"); - System.out.println("Sending redirect.. " + redirectUrl); + logger.debug("Sending redirect.. " + redirectUrl); return redirectUrl; } @@ -716,25 +713,26 @@ private String getSFRedirect(HttpServletRequest request) throws UnsupportedEncod @GET @Produces("application/json") @Path("/login/surveymonkey") - public Response loginSurveyMonkey(@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException { + public Response loginSurveyMonkey(@Context HttpServletRequest request, @Context HttpServletResponse response) + throws IOException { /* * Try to log in the user * If they are not logged in * Redirect the FE */ - + User userObj = (User) request.getSession().getAttribute(Constants.SESSION_USER); String queryString = request.getQueryString(); - if(queryString != null && queryString.contains("code=")) { - if(userObj == null || userObj.getAccessToken(AuthProvider.SURVEYMONKEY) == null) { + if (queryString != null && queryString.contains("code=")) { + if (userObj == null || userObj.getAccessToken(AuthProvider.SURVEYMONKEY) == null) { String[] outputs = AbstractHttpHelper.getCodes(queryString); String prefix = "surveymonkey_"; - String clientId = socialData.getProperty(prefix+"client_id"); - String clientSecret = socialData.getProperty(prefix+"secret_key"); - String redirectUri = socialData.getProperty(prefix+"redirect_uri"); + String clientId = socialData.getProperty(prefix + "client_id"); + String clientSecret = socialData.getProperty(prefix + "secret_key"); + String redirectUri = socialData.getProperty(prefix + "redirect_uri"); - System.out.println(">> " + request.getQueryString()); + logger.debug(">> " + request.getQueryString()); Hashtable params = new Hashtable(); params.put("client_id", clientId); @@ -744,9 +742,9 @@ public Response loginSurveyMonkey(@Context HttpServletRequest request, @Context params.put("client_secret", clientSecret); String url = "https://api.surveymonkey.com/oauth/token"; - + AccessToken accessToken = AbstractHttpHelper.getAccessToken(url, params, true, true); - if(accessToken == null) { + if (accessToken == null) { // not authenticated response.setStatus(302); response.sendRedirect(getSurveyMonkeyRedirect(request)); @@ -756,34 +754,32 @@ public Response loginSurveyMonkey(@Context HttpServletRequest request, @Context MonkeyProfile.fillAccessToken(accessToken, null); addAccessToken(accessToken, request); - System.out.println("Access Token is.. " + accessToken.getAccess_token()); + logger.debug("Access Token is.. " + accessToken.getAccess_token()); } } // grab the user again userObj = (User) request.getSession().getAttribute(Constants.SESSION_USER); - if(userObj == null || userObj.getAccessToken(AuthProvider.SURVEYMONKEY) == null) { + if (userObj == null || userObj.getAccessToken(AuthProvider.SURVEYMONKEY) == null) { // not authenticated response.setStatus(302); response.sendRedirect(getSurveyMonkeyRedirect(request)); return null; } - + setMainPageRedirect(request, response); return null; } - + private String getSurveyMonkeyRedirect(HttpServletRequest request) throws UnsupportedEncodingException { String prefix = "surveymonkey_"; - String clientId = socialData.getProperty(prefix+"client_id"); - String redirectUri = socialData.getProperty(prefix+"redirect_uri"); - - String redirectUrl = "https://api.surveymonkey.com/oauth/authorize?" + - "client_id=" + clientId + - "&response_type=code" + - "&redirect_uri=" + redirectUri; - - System.out.println("Sending redirect.. " + redirectUrl); + String clientId = socialData.getProperty(prefix + "client_id"); + String redirectUri = socialData.getProperty(prefix + "redirect_uri"); + + String redirectUrl = "https://api.surveymonkey.com/oauth/authorize?" + "client_id=" + clientId + + "&response_type=code" + "&redirect_uri=" + redirectUri; + + logger.debug("Sending redirect.. " + redirectUrl); return redirectUrl; } @@ -794,7 +790,8 @@ private String getSurveyMonkeyRedirect(HttpServletRequest request) throws Unsupp @GET @Produces("application/json") @Path("/login/github") - public Response loginGithub(@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException { + public Response loginGithub(@Context HttpServletRequest request, @Context HttpServletResponse response) + throws IOException { /* * Try to log in the user * If they are not logged in @@ -803,16 +800,16 @@ public Response loginGithub(@Context HttpServletRequest request, @Context HttpSe User userObj = (User) request.getSession().getAttribute(Constants.SESSION_USER); String queryString = request.getQueryString(); - if(queryString != null && queryString.contains("code=")) { - if(userObj == null || userObj.getAccessToken(AuthProvider.GITHUB) == null) { - String [] outputs = AbstractHttpHelper.getCodes(queryString); + if (queryString != null && queryString.contains("code=")) { + if (userObj == null || userObj.getAccessToken(AuthProvider.GITHUB) == null) { + String[] outputs = AbstractHttpHelper.getCodes(queryString); String prefix = "github_"; - String clientId = socialData.getProperty(prefix+"client_id"); - String clientSecret = socialData.getProperty(prefix+"secret_key"); - String redirectUri = socialData.getProperty(prefix+"redirect_uri"); + String clientId = socialData.getProperty(prefix + "client_id"); + String clientSecret = socialData.getProperty(prefix + "secret_key"); + String redirectUri = socialData.getProperty(prefix + "redirect_uri"); - System.out.println(">> " + request.getQueryString()); + logger.debug(">> " + request.getQueryString()); Hashtable params = new Hashtable(); params.put("client_id", clientId); @@ -824,7 +821,7 @@ public Response loginGithub(@Context HttpServletRequest request, @Context HttpSe String url = "https://github.com/login/oauth/access_token"; AccessToken accessToken = AbstractHttpHelper.getAccessToken(url, params, false, true); - if(accessToken == null) { + if (accessToken == null) { // not authenticated response.setStatus(302); response.sendRedirect(getGithubRedirect(request)); @@ -842,38 +839,35 @@ public Response loginGithub(@Context HttpServletRequest request, @Context HttpSe accessToken.setUsername(myGit.getLogin()); addAccessToken(accessToken, request); - System.out.println("Access Token is.. " + accessToken.getAccess_token()); + logger.debug("Access Token is.. " + accessToken.getAccess_token()); } } - + // grab the user again userObj = (User) request.getSession().getAttribute(Constants.SESSION_USER); - if(userObj == null || userObj.getAccessToken(AuthProvider.GITHUB) == null) { + if (userObj == null || userObj.getAccessToken(AuthProvider.GITHUB) == null) { // not authenticated GitRepoUtils.addCertForDomain("https://github.com"); response.setStatus(302); response.sendRedirect(getGithubRedirect(request)); return null; } - + setMainPageRedirect(request, response); return null; } - + private String getGithubRedirect(HttpServletRequest request) throws UnsupportedEncodingException { String prefix = "github_"; - String clientId = socialData.getProperty(prefix+"client_id"); - String redirectUri = socialData.getProperty(prefix+"redirect_uri"); - String scope = socialData.getProperty(prefix+"scope"); - - String redirectUrl = "https://github.com/login/oauth/authorize?" + - "client_id=" + clientId + - "&redirect_uri=" + redirectUri + - "&state=" + UUID.randomUUID().toString() + - "&allow_signup=true" + - "&scope=" + URLEncoder.encode(scope, "UTF-8"); - - System.out.println("Sending redirect.. " + redirectUrl); + String clientId = socialData.getProperty(prefix + "client_id"); + String redirectUri = socialData.getProperty(prefix + "redirect_uri"); + String scope = socialData.getProperty(prefix + "scope"); + + String redirectUrl = "https://github.com/login/oauth/authorize?" + "client_id=" + clientId + "&redirect_uri=" + + redirectUri + "&state=" + UUID.randomUUID().toString() + "&allow_signup=true" + "&scope=" + + URLEncoder.encode(scope, "UTF-8"); + + logger.debug("Sending redirect.. " + redirectUrl); return redirectUrl; } @@ -883,7 +877,8 @@ private String getGithubRedirect(HttpServletRequest request) throws UnsupportedE @GET @Produces("application/json") @Path("/login/ms") - public Response loginMS(@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException { + public Response loginMS(@Context HttpServletRequest request, @Context HttpServletResponse response) + throws IOException { /* * Try to log in the user * If they are not logged in @@ -892,18 +887,18 @@ public Response loginMS(@Context HttpServletRequest request, @Context HttpServle User userObj = (User) request.getSession().getAttribute(Constants.SESSION_USER); String queryString = request.getQueryString(); - if(queryString != null && queryString.contains("code=")) { - if(userObj == null || ((User)userObj).getAccessToken(AuthProvider.MS) == null) { - String [] outputs = AbstractHttpHelper.getCodes(queryString); + if (queryString != null && queryString.contains("code=")) { + if (userObj == null || ((User) userObj).getAccessToken(AuthProvider.MS) == null) { + String[] outputs = AbstractHttpHelper.getCodes(queryString); String prefix = "ms_"; - String clientId = socialData.getProperty(prefix+"client_id"); - String clientSecret = socialData.getProperty(prefix+"secret_key"); - String redirectUri = socialData.getProperty(prefix+"redirect_uri"); - String tenant = socialData.getProperty(prefix+"tenant"); - String scope = socialData.getProperty(prefix+"scope"); + String clientId = socialData.getProperty(prefix + "client_id"); + String clientSecret = socialData.getProperty(prefix + "secret_key"); + String redirectUri = socialData.getProperty(prefix + "redirect_uri"); + String tenant = socialData.getProperty(prefix + "tenant"); + String scope = socialData.getProperty(prefix + "scope"); - System.out.println(">> " + request.getQueryString()); + logger.debug(">> " + request.getQueryString()); Hashtable params = new Hashtable(); params.put("client_id", clientId); @@ -916,50 +911,47 @@ public Response loginMS(@Context HttpServletRequest request, @Context HttpServle String url = "https://login.microsoftonline.com/" + tenant + "/oauth2/v2.0/token"; AccessToken accessToken = AbstractHttpHelper.getAccessToken(url, params, true, true); - if(accessToken == null) { + if (accessToken == null) { // not authenticated response.setStatus(302); response.sendRedirect(getMSRedirect(request)); return null; } - + accessToken.setProvider(AuthProvider.MS); MSProfile.fillAccessToken(accessToken, null); addAccessToken(accessToken, request); - System.out.println("Access Token is.. " + accessToken.getAccess_token()); + logger.debug("Access Token is.. " + accessToken.getAccess_token()); } } - + // grab the user again userObj = (User) request.getSession().getAttribute(Constants.SESSION_USER); - if(userObj == null || userObj.getAccessToken(AuthProvider.MS) == null) { + if (userObj == null || userObj.getAccessToken(AuthProvider.MS) == null) { // not authenticated response.setStatus(302); response.sendRedirect(getMSRedirect(request)); return null; - } + } setMainPageRedirect(request, response); return null; } - + private String getMSRedirect(HttpServletRequest request) throws UnsupportedEncodingException { String prefix = "ms_"; - String clientId = socialData.getProperty(prefix+"client_id"); - String redirectUri = socialData.getProperty(prefix+"redirect_uri"); - String tenant = socialData.getProperty(prefix+"tenant"); - String scope = socialData.getProperty(prefix+"scope"); // need to set this up and reuse + String clientId = socialData.getProperty(prefix + "client_id"); + String redirectUri = socialData.getProperty(prefix + "redirect_uri"); + String tenant = socialData.getProperty(prefix + "tenant"); + String scope = socialData.getProperty(prefix + "scope"); // need to set this up and reuse String state = UUID.randomUUID().toString(); - String redirectUrl = "https://login.microsoftonline.com/" + tenant - + "/oauth2/v2.0/authorize?" + "client_id=" + clientId - + "&response_type=code" + "&redirect_uri=" - + URLEncoder.encode(redirectUri, "UTF-8") - + "&response_mode=query" + "&scope=" + URLEncoder.encode(scope) + "&state=" - + state; - - System.out.println("Sending redirect.. " + redirectUrl); + String redirectUrl = "https://login.microsoftonline.com/" + tenant + "/oauth2/v2.0/authorize?" + "client_id=" + + clientId + "&response_type=code" + "&redirect_uri=" + URLEncoder.encode(redirectUri, "UTF-8") + + "&response_mode=query" + "&scope=" + URLEncoder.encode(scope) + "&state=" + state; + + logger.debug("Sending redirect.. " + redirectUrl); return redirectUrl; } @@ -970,25 +962,26 @@ private String getMSRedirect(HttpServletRequest request) throws UnsupportedEncod @GET @Produces("application/json") @Path("/login/dropbox") - public Response loginDropBox(@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException { + public Response loginDropBox(@Context HttpServletRequest request, @Context HttpServletResponse response) + throws IOException { /* * Try to log in the user * If they are not logged in * Redirect the FE */ - + User userObj = (User) request.getSession().getAttribute(Constants.SESSION_USER); String queryString = request.getQueryString(); - if(queryString != null && queryString.contains("code=")) { - if(userObj == null || userObj.getAccessToken(AuthProvider.DROPBOX) == null) { - String [] outputs = AbstractHttpHelper.getCodes(queryString); + if (queryString != null && queryString.contains("code=")) { + if (userObj == null || userObj.getAccessToken(AuthProvider.DROPBOX) == null) { + String[] outputs = AbstractHttpHelper.getCodes(queryString); String prefix = "dropbox_"; - String clientId = socialData.getProperty(prefix+"client_id"); - String clientSecret = socialData.getProperty(prefix+"secret_key"); - String redirectUri = socialData.getProperty(prefix+"redirect_uri"); + String clientId = socialData.getProperty(prefix + "client_id"); + String clientSecret = socialData.getProperty(prefix + "secret_key"); + String redirectUri = socialData.getProperty(prefix + "redirect_uri"); - System.out.println(">> " + request.getQueryString()); + logger.debug(">> " + request.getQueryString()); Hashtable params = new Hashtable(); params.put("client_id", clientId); @@ -1000,7 +993,7 @@ public Response loginDropBox(@Context HttpServletRequest request, @Context HttpS String url = "https://www.dropbox.com/oauth2/token"; AccessToken accessToken = AbstractHttpHelper.getAccessToken(url, params, true, true); - if(accessToken == null) { + if (accessToken == null) { // not authenticated response.setStatus(302); response.sendRedirect(getDBRedirect(request)); @@ -1009,37 +1002,34 @@ public Response loginDropBox(@Context HttpServletRequest request, @Context HttpS accessToken.setProvider(AuthProvider.DROPBOX); addAccessToken(accessToken, request); - System.out.println("Access Token is.. " + accessToken.getAccess_token()); + logger.debug("Access Token is.. " + accessToken.getAccess_token()); } } - + // grab the user again userObj = (User) request.getSession().getAttribute(Constants.SESSION_USER); - if(userObj == null || userObj.getAccessToken(AuthProvider.DROPBOX) == null) { + if (userObj == null || userObj.getAccessToken(AuthProvider.DROPBOX) == null) { // not authenticated response.setStatus(302); response.sendRedirect(getDBRedirect(request)); return null; - } + } setMainPageRedirect(request, response); return null; } - + private String getDBRedirect(HttpServletRequest request) throws UnsupportedEncodingException { String prefix = "dropbox_"; - - String clientId = socialData.getProperty(prefix+"client_id"); - String redirectUri = socialData.getProperty(prefix+"redirect_uri"); - String role = socialData.getProperty(prefix+"role"); // need to set this up and reuse - String redirectUrl = "https://www.dropbox.com/oauth2/authorize?" + - "client_id=" + clientId+ - "&response_type=code" + - "&redirect_uri=" + URLEncoder.encode(redirectUri, "UTF-8")+ - "&require_role=" + role + - "&disable_signup=false"; - - System.out.println("Sending redirect.. " + redirectUrl); + + String clientId = socialData.getProperty(prefix + "client_id"); + String redirectUri = socialData.getProperty(prefix + "redirect_uri"); + String role = socialData.getProperty(prefix + "role"); // need to set this up and reuse + String redirectUrl = "https://www.dropbox.com/oauth2/authorize?" + "client_id=" + clientId + + "&response_type=code" + "&redirect_uri=" + URLEncoder.encode(redirectUri, "UTF-8") + "&require_role=" + + role + "&disable_signup=false"; + + logger.debug("Sending redirect.. " + redirectUrl); return redirectUrl; } @@ -1050,7 +1040,8 @@ private String getDBRedirect(HttpServletRequest request) throws UnsupportedEncod @GET @Produces("application/json") @Path("/login/google") - public Response loginGoogle(@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException { + public Response loginGoogle(@Context HttpServletRequest request, @Context HttpServletResponse response) + throws IOException { /* * Try to log in the user * If they are not logged in @@ -1059,17 +1050,18 @@ public Response loginGoogle(@Context HttpServletRequest request, @Context HttpSe User userObj = (User) request.getSession().getAttribute(Constants.SESSION_USER); String queryString = request.getQueryString(); - if(queryString != null && queryString.contains("code=")) { - if(userObj == null || userObj.getAccessToken(AuthProvider.GOOGLE) == null) { - String [] outputs = AbstractHttpHelper.getCodes(queryString); - + if (queryString != null && queryString.contains("code=")) { + if (userObj == null || userObj.getAccessToken(AuthProvider.GOOGLE) == null) { + String[] outputs = AbstractHttpHelper.getCodes(queryString); + String prefix = "google_"; - String clientId = socialData.getProperty(prefix+"client_id"); - String clientSecret = socialData.getProperty(prefix+"secret_key"); - String redirectUri = socialData.getProperty(prefix+"redirect_uri"); - - System.out.println(">> " + request.getQueryString()); - //I need to decode the return code from google since the default param's are encoded on the post of getAccessToken + String clientId = socialData.getProperty(prefix + "client_id"); + String clientSecret = socialData.getProperty(prefix + "secret_key"); + String redirectUri = socialData.getProperty(prefix + "redirect_uri"); + + logger.debug(">> " + request.getQueryString()); + // I need to decode the return code from google since the default param's are + // encoded on the post of getAccessToken String codeDecode = URLDecoder.decode(outputs[0]); Hashtable params = new Hashtable(); params.put("client_id", clientId); @@ -1077,12 +1069,12 @@ public Response loginGoogle(@Context HttpServletRequest request, @Context HttpSe params.put("code", codeDecode); params.put("grant_type", "authorization_code"); params.put("client_secret", clientSecret); - + String url = "https://www.googleapis.com/oauth2/v4/token"; - - //https://developers.google.com/api-client-library/java/google-api-java-client/oauth2 + + // https://developers.google.com/api-client-library/java/google-api-java-client/oauth2 AccessToken accessToken = AbstractHttpHelper.getAccessToken(url, params, true, true); - if(accessToken == null) { + if (accessToken == null) { // not authenticated response.setStatus(302); response.sendRedirect(getGoogleRedirect(request)); @@ -1090,13 +1082,14 @@ public Response loginGoogle(@Context HttpServletRequest request, @Context HttpSe } accessToken.setProvider(AuthProvider.GOOGLE); - // fill the access token with the other properties so we can properly create the user + // fill the access token with the other properties so we can properly create the + // user GoogleProfile.fillAccessToken(accessToken, null); addAccessToken(accessToken, request); - + // Shows how to make a google credential from an access token - System.out.println("Access Token is.. " + accessToken.getAccess_token()); - + logger.debug("Access Token is.. " + accessToken.getAccess_token()); + // this is just for testing... // but i will get yelled at if i remove it so here it is... // TODO: adding this todo to easily locate it @@ -1106,7 +1099,7 @@ public Response loginGoogle(@Context HttpServletRequest request, @Context HttpSe // grab the user again userObj = (User) request.getSession().getAttribute(Constants.SESSION_USER); - if(userObj == null || userObj.getAccessToken(AuthProvider.GOOGLE) == null) { + if (userObj == null || userObj.getAccessToken(AuthProvider.GOOGLE) == null) { // not authenticated response.setStatus(302); response.sendRedirect(getGoogleRedirect(request)); @@ -1116,40 +1109,36 @@ public Response loginGoogle(@Context HttpServletRequest request, @Context HttpSe setMainPageRedirect(request, response); return null; } - + private String getGoogleRedirect(HttpServletRequest request) throws UnsupportedEncodingException { String prefix = "google_"; - String clientId = socialData.getProperty(prefix+"client_id"); - String redirectUri = socialData.getProperty(prefix+"redirect_uri"); - String scope = socialData.getProperty(prefix+"scope"); // need to set this up and reuse - String accessType = socialData.getProperty(prefix+"access_type"); // need to set this up and reuse + String clientId = socialData.getProperty(prefix + "client_id"); + String redirectUri = socialData.getProperty(prefix + "redirect_uri"); + String scope = socialData.getProperty(prefix + "scope"); // need to set this up and reuse + String accessType = socialData.getProperty(prefix + "access_type"); // need to set this up and reuse String state = UUID.randomUUID().toString(); - - String redirectUrl = "https://accounts.google.com/o/oauth2/v2/auth?" - + "client_id=" + clientId - + "&response_type=code" - + "&redirect_uri=" + URLEncoder.encode(redirectUri, "UTF-8") - + "&access_type=" + accessType - + "&scope=" + URLEncoder.encode(scope, "UTF-8") - + "&state=" + state; - - System.out.println("Sending redirect.. " + redirectUrl); + + String redirectUrl = "https://accounts.google.com/o/oauth2/v2/auth?" + "client_id=" + clientId + + "&response_type=code" + "&redirect_uri=" + URLEncoder.encode(redirectUri, "UTF-8") + "&access_type=" + + accessType + "&scope=" + URLEncoder.encode(scope, "UTF-8") + "&state=" + state; + + logger.debug("Sending redirect.. " + redirectUrl); return redirectUrl; } - + /** * METHOD IS USED FOR TESTING + * * @param request * @param ret */ - private void performGoogleOps(HttpServletRequest request, Map ret) - { + private void performGoogleOps(HttpServletRequest request, Map ret) { // get the user details IConnectorIOp prof = new GoogleProfile(); - prof.execute((User)request.getSession().getAttribute(Constants.SESSION_USER), null); - + prof.execute((User) request.getSession().getAttribute(Constants.SESSION_USER), null); + IConnectorIOp lister = new GoogleListFiles(); - List fileList = (List)lister.execute((User)request.getSession().getAttribute(Constants.SESSION_USER), null); + List fileList = (List) lister.execute((User) request.getSession().getAttribute(Constants.SESSION_USER), null); // get the file IConnectorIOp getter = new GoogleFileRetriever(); @@ -1158,7 +1147,7 @@ private void performGoogleOps(HttpServletRequest request, Map ret) params2.put("id", "1it40jNFcRo1ur2dHIYUk18XmXdd37j4gmJm_Sg7KLjI"); params2.put("target", "c:\\users\\pkapaleeswaran\\workspacej3\\datasets\\googlefile.csv"); - getter.execute((User)request.getSession().getAttribute(Constants.SESSION_USER), params2); + getter.execute((User) request.getSession().getAttribute(Constants.SESSION_USER), params2); IConnectorIOp ner = new GoogleEntityResolver(); @@ -1166,62 +1155,63 @@ private void performGoogleOps(HttpServletRequest request, Map ret) docInput.setContent("Obama is staying in the whitehouse !!"); params2 = new Hashtable(); - - //Hashtable docInputShell = new Hashtable(); + + // Hashtable docInputShell = new Hashtable(); params2.put("encodingType", "UTF8"); params2.put("document", docInput); - - //params2.put("input", docInputShell); - ner.execute((User)request.getSession().getAttribute(Constants.SESSION_USER), params2); - + + // params2.put("input", docInputShell); + ner.execute((User) request.getSession().getAttribute(Constants.SESSION_USER), params2); + try { ret.put("files", BeanFiller.getJson(fileList)); } catch (Exception e) { // TODO Auto-generated catch block - e.printStackTrace(); + logger.error(STACKTRACE, e); } IConnectorIOp lat = new GoogleLatLongGetter(); params2 = new Hashtable(); params2.put("address", "1919 N Lynn Street, Arlington, VA"); - - lat.execute((User)request.getSession().getAttribute(Constants.SESSION_USER), params2); + + lat.execute((User) request.getSession().getAttribute(Constants.SESSION_USER), params2); IConnectorIOp ts = new TwitterSearcher(); params2 = new Hashtable(); params2.put("q", "Anlaytics"); params2.put("lang", "en"); params2.put("count", "10"); - - Object vp = ts.execute((User)request.getSession().getAttribute(Constants.SESSION_USER), params2); + + Object vp = ts.execute((User) request.getSession().getAttribute(Constants.SESSION_USER), params2); } - + @GET @Produces("application/json") @Path("/login/producthunt") - public Response loginProducthunt(@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException { + public Response loginProducthunt(@Context HttpServletRequest request, @Context HttpServletResponse response) + throws IOException { /* * Try to log in the user * If they are not logged in * Redirect the FE */ - + User userObj = (User) request.getSession().getAttribute(Constants.SESSION_USER); - + String queryString = request.getQueryString(); - if(queryString != null && queryString.contains("code=")) { - if(userObj == null || userObj.getAccessToken(AuthProvider.PRODUCT_HUNT) == null) { - String [] outputs = AbstractHttpHelper.getCodes(queryString); - + if (queryString != null && queryString.contains("code=")) { + if (userObj == null || userObj.getAccessToken(AuthProvider.PRODUCT_HUNT) == null) { + String[] outputs = AbstractHttpHelper.getCodes(queryString); + String prefix = "producthunt_"; - String clientId = socialData.getProperty(prefix+"client_id"); - String clientSecret = socialData.getProperty(prefix+"secret_key"); - String redirectUri = socialData.getProperty(prefix+"redirect_uri"); - - System.out.println(">> " + request.getQueryString()); - + String clientId = socialData.getProperty(prefix + "client_id"); + String clientSecret = socialData.getProperty(prefix + "secret_key"); + String redirectUri = socialData.getProperty(prefix + "redirect_uri"); + + logger.debug(">> " + request.getQueryString()); + Hashtable params = new Hashtable(); - + params.put("client_id", clientId); params.put("redirect_uri", redirectUri); params.put("code", outputs[0]); @@ -1231,7 +1221,7 @@ public Response loginProducthunt(@Context HttpServletRequest request, @Context H String url = "https://api.producthunt.com/v1/oauth/token"; AccessToken accessToken = AbstractHttpHelper.getAccessToken(url, params, true, true); - if(accessToken == null) { + if (accessToken == null) { // not authenticated response.setStatus(302); response.sendRedirect(getProducthuntRedirect(request)); @@ -1240,13 +1230,13 @@ public Response loginProducthunt(@Context HttpServletRequest request, @Context H accessToken.setProvider(AuthProvider.PRODUCT_HUNT); addAccessToken(accessToken, request); - System.out.println("Access Token is.. " + accessToken.getAccess_token()); + logger.debug("Access Token is.. " + accessToken.getAccess_token()); } } // grab the user again userObj = (User) request.getSession().getAttribute(Constants.SESSION_USER); - if(userObj == null || userObj.getAccessToken(AuthProvider.PRODUCT_HUNT) == null) { + if (userObj == null || userObj.getAccessToken(AuthProvider.PRODUCT_HUNT) == null) { response.setStatus(302); response.sendRedirect(getProducthuntRedirect(request)); return null; @@ -1255,49 +1245,48 @@ public Response loginProducthunt(@Context HttpServletRequest request, @Context H setMainPageRedirect(request, response); return null; } - + private String getProducthuntRedirect(HttpServletRequest request) throws UnsupportedEncodingException { String prefix = "producthunt_"; - - String clientId = socialData.getProperty(prefix+"client_id"); - String redirectUri = socialData.getProperty(prefix+"redirect_uri"); - String scope = socialData.getProperty(prefix+"scope"); - - String redirectUrl = "https://api.producthunt.com/v1/oauth/authorize?" + - "client_id=" + clientId+ - "&response_type=code" + - "&redirect_uri=" + URLEncoder.encode(redirectUri, "UTF-8")+ - "&scope=" + URLEncoder.encode(scope, "UTF-8") ; - - System.out.println("Sending redirect.. " + redirectUrl); + + String clientId = socialData.getProperty(prefix + "client_id"); + String redirectUri = socialData.getProperty(prefix + "redirect_uri"); + String scope = socialData.getProperty(prefix + "scope"); + + String redirectUrl = "https://api.producthunt.com/v1/oauth/authorize?" + "client_id=" + clientId + + "&response_type=code" + "&redirect_uri=" + URLEncoder.encode(redirectUri, "UTF-8") + "&scope=" + + URLEncoder.encode(scope, "UTF-8"); + + logger.debug("Sending redirect.. " + redirectUrl); return redirectUrl; } - + /** * Logs user in through linkedin */ @GET @Produces("application/json") @Path("/login/linkedin") - public Response loginIn(@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException { + public Response loginIn(@Context HttpServletRequest request, @Context HttpServletResponse response) + throws IOException { /* * Try to log in the user * If they are not logged in * Redirect the FE */ - + User userObj = (User) request.getSession().getAttribute(Constants.SESSION_USER); String queryString = request.getQueryString(); - if(queryString != null && queryString.contains("code=")) { - if(userObj == null || userObj.getAccessToken(AuthProvider.IN) == null) { - String [] outputs = AbstractHttpHelper.getCodes(queryString); + if (queryString != null && queryString.contains("code=")) { + if (userObj == null || userObj.getAccessToken(AuthProvider.IN) == null) { + String[] outputs = AbstractHttpHelper.getCodes(queryString); String prefix = "in_"; - String clientId = socialData.getProperty(prefix+"client_id"); - String clientSecret = socialData.getProperty(prefix+"secret_key"); - String redirectUri = socialData.getProperty(prefix+"redirect_uri"); + String clientId = socialData.getProperty(prefix + "client_id"); + String clientSecret = socialData.getProperty(prefix + "secret_key"); + String redirectUri = socialData.getProperty(prefix + "redirect_uri"); - System.out.println(">> " + request.getQueryString()); + logger.debug(">> " + request.getQueryString()); Hashtable params = new Hashtable(); params.put("client_id", clientId); @@ -1309,7 +1298,7 @@ public Response loginIn(@Context HttpServletRequest request, @Context HttpServle String url = "https://www.linkedin.com/oauth/v2/accessToken"; AccessToken accessToken = AbstractHttpHelper.getAccessToken(url, params, true, true); - if(accessToken == null) { + if (accessToken == null) { // not authenticated response.setStatus(302); response.sendRedirect(getInRedirect(request)); @@ -1317,52 +1306,38 @@ public Response loginIn(@Context HttpServletRequest request, @Context HttpServle } accessToken.setProvider(AuthProvider.IN); addAccessToken(accessToken, request); - System.out.println("Access Token is.. " + accessToken.getAccess_token()); + logger.debug("Access Token is.. " + accessToken.getAccess_token()); } } - + // grab the user again userObj = (User) request.getSession().getAttribute(Constants.SESSION_USER); - if(userObj == null || userObj.getAccessToken(AuthProvider.IN) == null) { + if (userObj == null || userObj.getAccessToken(AuthProvider.IN) == null) { response.setStatus(302); response.sendRedirect(getInRedirect(request)); - } + } setMainPageRedirect(request, response); return null; } - + private String getInRedirect(HttpServletRequest request) throws UnsupportedEncodingException { String prefix = "in_"; - String clientId = socialData.getProperty(prefix+"client_id"); - String redirectUri = socialData.getProperty(prefix+"redirect_uri"); - String scope = socialData.getProperty(prefix+"scope"); - - String redirectUrl = "https://www.linkedin.com/oauth/v2/authorization?" + - "client_id=" + clientId + - "&redirect_uri=" + redirectUri + - "&state=" + UUID.randomUUID().toString() + - "&response_type=code" + - "&scope=" + URLEncoder.encode(scope, "UTF-8"); - - System.out.println("Sending redirect.. " + redirectUrl); - return redirectUrl; - } + String clientId = socialData.getProperty(prefix + "client_id"); + String redirectUri = socialData.getProperty(prefix + "redirect_uri"); + String scope = socialData.getProperty(prefix + "scope"); - - - - + String redirectUrl = "https://www.linkedin.com/oauth/v2/authorization?" + "client_id=" + clientId + + "&redirect_uri=" + redirectUri + "&state=" + UUID.randomUUID().toString() + "&response_type=code" + + "&scope=" + URLEncoder.encode(scope, "UTF-8"); + logger.debug("Sending redirect.. " + redirectUrl); + return redirectUrl; + } /** * WHY IS THIS GIT?!?!?! - * WHY IS THIS GIT?!?!?! - * WHY IS THIS GIT?!?!?! - * WHY IS THIS GIT?!?!?! - * WHY IS THIS GIT?!?!?! - * WHY IS THIS GIT?!?!?! - * WHY IS THIS GIT?!?!?! + * * @param request * @param response * @return @@ -1371,28 +1346,28 @@ private String getInRedirect(HttpServletRequest request) throws UnsupportedEncod @GET @Produces("application/json") @Path("/login/twitter") - public Response loginTwitter(@Context HttpServletRequest request, @Context HttpServletResponse response) throws IOException - { + public Response loginTwitter(@Context HttpServletRequest request, @Context HttpServletResponse response) + throws IOException { // getting the bearer token on twitter for app authentication is a lot simpler // need to just combine the id and secret // base 64 and send as authorization - - //https://developer.github.com/apps/building-oauth-apps/authorization-options-for-oauth-apps/ - + + // https://developer.github.com/apps/building-oauth-apps/authorization-options-for-oauth-apps/ + User userObj = (User) request.getSession().getAttribute(Constants.SESSION_USER); String queryString = request.getQueryString(); - if(queryString != null && queryString.contains("code=")) { - if(userObj == null || ((User)userObj).getAccessToken(AuthProvider.GITHUB) == null) { + if (queryString != null && queryString.contains("code=")) { + if (userObj == null || ((User) userObj).getAccessToken(AuthProvider.GITHUB) == null) { - String [] outputs = AbstractHttpHelper.getCodes(queryString); + String[] outputs = AbstractHttpHelper.getCodes(queryString); String prefix = "git_"; - String clientId = socialData.getProperty(prefix+"client_id"); - String clientSecret = socialData.getProperty(prefix+"secret_key"); - String redirectUri = socialData.getProperty(prefix+"redirect_uri"); + String clientId = socialData.getProperty(prefix + "client_id"); + String clientSecret = socialData.getProperty(prefix + "secret_key"); + String redirectUri = socialData.getProperty(prefix + "redirect_uri"); - System.out.println(">> " + request.getQueryString()); + logger.debug(">> " + request.getQueryString()); Hashtable params = new Hashtable(); params.put("client_id", clientId); @@ -1404,23 +1379,23 @@ public Response loginTwitter(@Context HttpServletRequest request, @Context HttpS String url = "https://github.com/login/oauth/access_token"; AccessToken accessToken = AbstractHttpHelper.getAccessToken(url, params, false, true); - if(accessToken == null) { + if (accessToken == null) { // not authenticated response.setStatus(302); response.sendRedirect(getTwitterRedirect(request)); return null; } - + accessToken.setProvider(AuthProvider.GITHUB); addAccessToken(accessToken, request); - System.out.println("Access Token is.. " + accessToken.getAccess_token()); + logger.debug("Access Token is.. " + accessToken.getAccess_token()); } } - + // grab the user again userObj = (User) request.getSession().getAttribute(Constants.SESSION_USER); - if(userObj == null || ((User)userObj).getAccessToken(AuthProvider.GITHUB) == null) { + if (userObj == null || ((User) userObj).getAccessToken(AuthProvider.GITHUB) == null) { // not authenticated response.setStatus(302); response.sendRedirect(getTwitterRedirect(request)); @@ -1430,39 +1405,35 @@ public Response loginTwitter(@Context HttpServletRequest request, @Context HttpS setMainPageRedirect(request, response); return null; } - + private String getTwitterRedirect(HttpServletRequest request) throws UnsupportedEncodingException { String prefix = "twitter_"; - - String clientId = socialData.getProperty(prefix+"client_id"); - String clientSecret = socialData.getProperty(prefix+"secret_key"); - String redirectUri = socialData.getProperty(prefix+"redirect_uri"); - String scope = socialData.getProperty(prefix+"scope"); - String nonce = UUID.randomUUID().toString() ; - String timestamp = System.currentTimeMillis() +""; - - + + String clientId = socialData.getProperty(prefix + "client_id"); + String clientSecret = socialData.getProperty(prefix + "secret_key"); + String redirectUri = socialData.getProperty(prefix + "redirect_uri"); + String scope = socialData.getProperty(prefix + "scope"); + String nonce = UUID.randomUUID().toString(); + String timestamp = System.currentTimeMillis() + ""; + StringBuffer signatureString = new StringBuffer("GET").append("&"); signatureString.append(URLEncoder.encode("https://api.twitter.com/oauth/authorize", "UTF-8")).append("&"); - + StringBuffer parameterString = new StringBuffer(""); parameterString.append("oauth_callback=").append(URLEncoder.encode(redirectUri, "UTF-8")).append("&"); parameterString.append("oauth_consumer_key=").append(clientId).append("&"); parameterString.append("oauth_nonce=").append(nonce).append("&"); parameterString.append("oauth_timestamp=").append(timestamp); - + String finalString = signatureString.toString() + parameterString.toString(); - - //String signature = - - String redirectUrl = "https://github.com/login/oauth/authorize?" + - "oauth_consumer_key=" + clientId + - "&oauth_callback=" + redirectUri + - "&oauth_nonce=" + nonce + - "&oauth_timestamp=" + timestamp + - "&scope=" + URLEncoder.encode(scope, "UTF-8"); - - System.out.println("Sending redirect.. " + redirectUrl); + + // String signature = + + String redirectUrl = "https://github.com/login/oauth/authorize?" + "oauth_consumer_key=" + clientId + + "&oauth_callback=" + redirectUri + "&oauth_nonce=" + nonce + "&oauth_timestamp=" + timestamp + + "&scope=" + URLEncoder.encode(scope, "UTF-8"); + + logger.debug("Sending redirect.. " + redirectUrl); return redirectUrl; } @@ -1481,17 +1452,16 @@ private String getTwitterRedirect(HttpServletRequest request) throws Unsupported // } // return formatter.toString(); // } - - + ///////////////////////////////////////////////////////////////// - + /** * This portion of code is for semoss generated users */ - - + /** * Authenticates an user that's trying to log in. + * * @param request * @return true if the information provided to log in is valid otherwise error. */ @@ -1499,16 +1469,17 @@ private String getTwitterRedirect(HttpServletRequest request) throws Unsupported @Produces("application/json") @Path("login") public Response loginNative(@Context HttpServletRequest request, @Context HttpServletResponse response) { - Hashtable ret = new Hashtable(); - try{ + Hashtable ret = new Hashtable<>(); + try { String username = request.getParameter("username"); String password = request.getParameter("password"); String redirect = request.getParameter("redirect"); Boolean disableRedirect = Boolean.parseBoolean(request.getParameter("enableRedirect") + ""); - - boolean emptyCredentials = (username == null || password == null || username.isEmpty() || password.isEmpty()); + + boolean emptyCredentials = (username == null || password == null || username.isEmpty() + || password.isEmpty()); boolean canLogin = !emptyCredentials && NativeUserSecurityUtils.logIn(username, password); - if(canLogin){ + if (canLogin) { ret.put("success", "true"); ret.put("username", username); String name = NativeUserSecurityUtils.getNameUser(username); @@ -1520,26 +1491,26 @@ public Response loginNative(@Context HttpServletRequest request, @Context HttpSe AccessToken authToken = new AccessToken(); authToken.setProvider(AuthProvider.NATIVE); authToken.setId(id); - authToken.setName(username); + authToken.setName(username); authToken.setEmail(email); addAccessToken(authToken, request); - - if(!disableRedirect) { + + if (!disableRedirect) { setMainPageRedirect(request, response, redirect); } } else { ret.put("error", "The user name or password are invalid."); return WebUtility.getResponse(ret, 401); } - } catch(Exception e){ - e.printStackTrace(); + } catch (Exception e) { + logger.error(STACKTRACE, e); ret.put("error", "An unexpected error happened. Please try again."); return WebUtility.getResponse(ret, 500); } - + return WebUtility.getResponse(ret, 200); } - + /** * Logs user out when authenticated in a native way. */ @@ -1547,21 +1518,21 @@ public Response loginNative(@Context HttpServletRequest request, @Context HttpSe @Produces("application/json") @Path("/logout") public Response logoutNative(@Context HttpServletRequest request) throws IOException { - Hashtable ret = new Hashtable(); - try{ - if(request.getSession(false) != null){ - HttpSession session = request.getSession(false); + Hashtable ret = new Hashtable<>(); + try { + if (request.getSession(false) != null) { + HttpSession session = request.getSession(false); User print = (User) session.getAttribute(Constants.SESSION_USER); - //LOGGER.info("Logging out with: " + print); + // LOGGER.info("Logging out with: " + print); print.dropAccessToken(AuthProvider.NATIVE.name().toUpperCase()); request.getSession().setAttribute(Constants.SESSION_USER, print); } else { ret.put("error", "User is not connected."); return WebUtility.getResponse(ret, 401); } - // Only disconnect a connected user. + // Only disconnect a connected user. } catch (Exception ex) { - ex.printStackTrace(); + logger.error(STACKTRACE, ex); ret.put("error", "Unexpected error."); return WebUtility.getResponse(ret, 500); } @@ -1570,7 +1541,9 @@ public Response logoutNative(@Context HttpServletRequest request) throws IOExcep } /** - * Create an user according to the information provided (user name, password, email) + * Create an user according to the information provided (user name, password, + * email) + * * @param request * @return true if the user is created otherwise error. */ @@ -1578,8 +1551,8 @@ public Response logoutNative(@Context HttpServletRequest request) throws IOExcep @Produces("application/json") @Path("createUser") public Response createUser(@Context HttpServletRequest request) { - Hashtable ret = new Hashtable(); - try{ + Hashtable ret = new Hashtable<>(); + try { String username = request.getParameter("username"); String name = request.getParameter("name"); String password = request.getParameter("password"); @@ -1591,7 +1564,7 @@ public Response createUser(@Context HttpServletRequest request) { newUser.setEmail(email); newUser.setName(name); boolean userCreated = NativeUserSecurityUtils.addNativeUser(newUser, password); - if(userCreated){ + if (userCreated) { ret.put("success", "true"); ret.put("username", username); return WebUtility.getResponse(ret, 200); @@ -1599,17 +1572,17 @@ public Response createUser(@Context HttpServletRequest request) { ret.put("error", "The user name or email aready exists."); return WebUtility.getResponse(ret, 400); } - } catch (IllegalArgumentException e){ - e.printStackTrace(); - ret.put("error", e.getMessage()); + } catch (IllegalArgumentException iae) { + logger.error(STACKTRACE, iae); + ret.put("error", iae.getMessage()); return WebUtility.getResponse(ret, 500); - } catch (Exception e){ - e.printStackTrace(); + } catch (Exception e) { + logger.error(STACKTRACE, e); ret.put("error", "An unexpected error happened. Please try again."); return WebUtility.getResponse(ret, 500); } } - + ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// @@ -1617,85 +1590,90 @@ public Response createUser(@Context HttpServletRequest request) { ////////////////////////////////////////////////////////////////////// /** - * Setting / Getting Information from the social properties - * That is needed by the FE + * Setting / Getting Information from the social properties That is needed by + * the FE */ - + @GET @Produces("application/json") @Path("/loginsAllowed/") public Response loginsAllowed(@Context HttpServletRequest request) throws IOException { - return WebUtility.getResponse(UserResource.loginsAllowed, 200); + return WebUtility.getResponse(UserResource.loginsAllowed, 200); } - + @GET @Produces("application/json") @Path("/loginProperties/") public Response loginProperties(@Context HttpServletRequest request) throws IOException { - if(AbstractSecurityUtils.securityEnabled()) { + if (AbstractSecurityUtils.securityEnabled()) { User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - if(user == null) { - return WebUtility.getResponse("No user defined to access properties. Please login as an admin", 400); + if (user == null) { + return WebUtility.getResponse("No user defined to access properties. Please login as an admin", 400); } - if(!SecurityAdminUtils.userIsAdmin(user)){ - return WebUtility.getResponse("User is not an admin and does not have access. Please login as an admin", 400); + if (!SecurityAdminUtils.userIsAdmin(user)) { + return WebUtility.getResponse("User is not an admin and does not have access. Please login as an admin", + 400); } } - + // you have access - lets send all the info - - Map> loginApps = new TreeMap>(); - + + Map> loginApps = new TreeMap<>(); + Set propSet = socialData.stringPropertyNames(); - for(String prop : propSet) { - if(!prop.contains("_")) { + for (String prop : propSet) { + if (!prop.contains("_")) { // bad format // ignore continue; } - String[] split = prop.toString().split("_", 2); + String[] split = prop.toString().split("_", 2); String type = split[0]; String type_key = split[1]; - - if(!loginApps.containsKey(type)) { + + if (!loginApps.containsKey(type)) { loginApps.put(type, new TreeMap()); } - - loginApps.get(type).put(type_key, socialData.getProperty(prop).toString()); + + loginApps.get(type).put(type_key, socialData.getProperty(prop)); } - - return WebUtility.getResponse(loginApps, 200); + + return WebUtility.getResponse(loginApps, 200); } - + @POST @Produces("application/json") @Path("/modifyLoginProperties/{provider}") - public synchronized Response modifyLoginProperties(@PathParam("provider") String provider, MultivaluedMap form, @Context HttpServletRequest request) throws IOException { - if(AbstractSecurityUtils.securityEnabled()) { + public synchronized Response modifyLoginProperties(@PathParam("provider") String provider, + MultivaluedMap form, @Context HttpServletRequest request) throws IOException { + if (AbstractSecurityUtils.securityEnabled()) { User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - if(user == null) { - return WebUtility.getResponse("No user defined to access properties. Please login as an admin", 400); + if (user == null) { + return WebUtility.getResponse("No user defined to access properties. Please login as an admin", 400); } - if(!SecurityAdminUtils.userIsAdmin(user)){ - return WebUtility.getResponse("User is not an admin and does not have access. Please login as an admin", 400); + if (!SecurityAdminUtils.userIsAdmin(user)) { + return WebUtility.getResponse("User is not an admin and does not have access. Please login as an admin", + 400); } } - + Gson gson = new Gson(); String modStr = form.getFirst("modifications"); - Map mods = gson.fromJson(modStr, new TypeToken>() {}.getType()); - + Map mods = gson.fromJson(modStr, new TypeToken>() { + }.getType()); + PropertiesConfiguration config = null; try { config = new PropertiesConfiguration(DIHelper.getInstance().getProperty("SOCIAL")); } catch (ConfigurationException e1) { - e1.printStackTrace(); - Hashtable errorRet = new Hashtable(); - errorRet.put("error", "An unexpected error happened trying to access the properties. Please try again or reach out to server admin."); + logger.error(STACKTRACE, e1); + Hashtable errorRet = new Hashtable<>(); + errorRet.put("error", + "An unexpected error happened trying to access the properties. Please try again or reach out to server admin."); return WebUtility.getResponse(errorRet, 500); } - - for(String mod : mods.keySet()) { + + for (String mod : mods.keySet()) { config.setProperty(provider + "_" + mod, mods.get(mod)); } @@ -1703,28 +1681,32 @@ public synchronized Response modifyLoginProperties(@PathParam("provider") String config.save(); loadSocialProperties(); } catch (ConfigurationException e1) { - e1.printStackTrace(); - Hashtable errorRet = new Hashtable(); - errorRet.put("error", "An unexpected error happened when saving the new login properties. Please try again or reach out to server admin."); + logger.error(STACKTRACE, e1); + Hashtable errorRet = new Hashtable<>(); + errorRet.put("error", + "An unexpected error happened when saving the new login properties. Please try again or reach out to server admin."); return WebUtility.getResponse(errorRet, 500); } - + return WebUtility.getResponse(true, 200); } - + /** * Redirect the login back to the main app page + * * @param response */ private void setMainPageRedirect(@Context HttpServletRequest request, @Context HttpServletResponse response) { setMainPageRedirect(request, response, null); } - + /** * Redirect the login back to the main app page + * * @param response */ - private void setMainPageRedirect(@Context HttpServletRequest request, @Context HttpServletResponse response, String customRedirect) { + private void setMainPageRedirect(@Context HttpServletRequest request, @Context HttpServletResponse response, + String customRedirect) { // see if we have a location to redirect the user // if so, we will send them back to that URL // otherwise, we send them back to the FE @@ -1734,12 +1716,13 @@ private void setMainPageRedirect(@Context HttpServletRequest request, @Context H response.setStatus(302); try { Cookie cookie = new Cookie(DBLoader.getSessionIdKey(), request.getSession().getId()); - //cookie.setPath("/dev"); + // cookie.setPath("/dev"); response.addCookie(cookie); - if(useCustom) { + if (useCustom) { response.setHeader("redirect", customRedirect); - response.sendError(302, "Need to redirect to " + customRedirect); - } else if(endpoint) { + String encodedCustomRedirect = Encode.forHtml(customRedirect); + response.sendError(302, "Need to redirect to " + encodedCustomRedirect); + } else if (endpoint) { String redirectUrl = session.getAttribute(NoUserInSessionFilter.ENDPOINT_REDIRECT_KEY) + ""; response.setHeader("redirect", redirectUrl); response.sendError(302, "Need to redirect to " + redirectUrl); @@ -1747,12 +1730,13 @@ private void setMainPageRedirect(@Context HttpServletRequest request, @Context H response.sendRedirect(socialData.getProperty("redirect")); } } catch (IOException e) { - e.printStackTrace(); + logger.error(STACKTRACE, e); } } - + /** * Set the information in the JSON return after logging in + * * @param token * @param ret */ @@ -1761,7 +1745,7 @@ private void setAccessTokenDetails(AccessToken token, Map ret) { ret.put("email", token.getEmail()); ret.put("type", token.getToken_type()); } - + ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// @@ -1771,100 +1755,102 @@ private void setAccessTokenDetails(AccessToken token, Map ret) { /** * Sharing session */ - - + @GET @Produces("application/json") @Path("/cookie") - public StreamingOutput manCookie(@Context HttpServletRequest request, @Context HttpServletResponse response, @QueryParam("i") String insightId, @QueryParam("s") String secret) { - //https://nuwanbando.com/2010/05/07/sharing-https-http-sessions-in-tomcat/ - - /* - * When the user clicks on connect to tableau.. I need to give the user a link - * to that insight primarily - * the question is do I land on the same insight or a different one - * that link should have insight id and session id - * - * a. Launches a new browser with this redirect along with pseudo session id, session id hashed with insight id - * b. Redirects the user to a URL with the insight id and the pseudo session id / or something that sits in the user object. some random number - * c. We pick the session.. go to the user object to see if the secret can be verified. Basically you take the session id which came in hash it with the insight id to see if it is allowable - * d. We redirect the user to the embedded URL for the insight >> - * e. We need someway to repull the recipe - * - * I need first something that will take me to http and then from there on take me into my insight - * - */ + public StreamingOutput manCookie(@Context HttpServletRequest request, @Context HttpServletResponse response, + @QueryParam("i") String insightId, @QueryParam("s") String secret) { + // https://nuwanbando.com/2010/05/07/sharing-https-http-sessions-in-tomcat/ + + /* + * When the user clicks on connect to tableau.. I need to give the user a link + * to that insight primarily + * the question is do I land on the same insight or a different one + * that link should have insight id and session id + * + * a. Launches a new browser with this redirect along with pseudo session id, session id hashed with insight id + * b. Redirects the user to a URL with the insight id and the pseudo session id / or something that sits in the user object. some random number + * c. We pick the session.. go to the user object to see if the secret can be verified. Basically you take the session id which came in hash it with the insight id to see if it is allowable + * d. We redirect the user to the embedded URL for the insight >> + * e. We need someway to repull the recipe + * + * I need first something that will take me to http and then from there on take me into my insight + * + */ // get the session HttpSession session = request.getSession(); String sessionId = session.getId(); User user = (User) session.getAttribute(Constants.SESSION_USER); - Cookie k = new Cookie(DBLoader.getSessionIdKey(), sessionId); - k.setPath(request.getContextPath()); - response.addCookie(k); - - System.out.println("Session id set to " + sessionId); - - InsightToken token = new InsightToken(); - Hashtable outputHash = new Hashtable(); - try { - MessageDigest md = MessageDigest.getInstance("MD5"); - // create the insight token and add to the user - // the user has secret and salt - token.setSecret(secret); - user.addInsight(insightId, token); - - String finalData = token.getSalt() + token.getSecret(); - - byte [] digest = md.digest(finalData.getBytes()); //.toString().getBytes(); + Cookie k = new Cookie(DBLoader.getSessionIdKey(), sessionId); + k.setPath(request.getContextPath()); + response.addCookie(k); + + logger.debug("Session id set to " + sessionId); + + InsightToken token = new InsightToken(); + Hashtable outputHash = new Hashtable(); + try { + MessageDigest md = MessageDigest.getInstance("MD5"); + // create the insight token and add to the user + // the user has secret and salt + token.setSecret(secret); + user.addInsight(insightId, token); + + String finalData = token.getSalt() + token.getSecret(); + + byte[] digest = md.digest(finalData.getBytes()); // .toString().getBytes(); StringBuffer sb = new StringBuffer(); - for (int i = 0; i < digest.length; i++) { - sb.append(Integer.toString((digest[i] & 0xff) + 0x100, 16).substring(1)); - } - //String redir = "http://localhost:9090/Monolith/api/engine/all?JSESSIONID=" + sessionId; - String redir = "?" + DBLoader.getSessionIdKey() + "=" + sessionId + "&hash=" + sb + "&i=" + insightId; - - // add the route if this is server deployment - Map envMap = System.getenv(); - // the environment variable for this box will tell me which route variable - // is for this specific box - if(envMap.containsKey(NoUserInSessionFilter.MONOLITH_ROUTE)) { - String routeCookieName = envMap.get(NoUserInSessionFilter.MONOLITH_ROUTE); - Cookie[] curCookies = request.getCookies(); - if(curCookies != null) { - for(Cookie c : curCookies) { - if(c.getName().equals(routeCookieName)) { - redir += "&" + c.getName() + "=" + c.getValue(); - } - } - } - } - - System.out.println("Redirect URL " + redir); - outputHash.put("PARAM", redir); - // also tell the system that this session is not fully validated so if someone comes without secret on this session - // dont allow - user.addShare(sessionId); + for (int i = 0; i < digest.length; i++) { + sb.append(Integer.toString((digest[i] & 0xff) + 0x100, 16).substring(1)); + } + // String redir = "http://localhost:9090/Monolith/api/engine/all?JSESSIONID=" + + // sessionId; + String redir = "?" + DBLoader.getSessionIdKey() + "=" + sessionId + "&hash=" + sb + "&i=" + insightId; + + // add the route if this is server deployment + Map envMap = System.getenv(); + // the environment variable for this box will tell me which route variable + // is for this specific box + if (envMap.containsKey(NoUserInSessionFilter.MONOLITH_ROUTE)) { + String routeCookieName = envMap.get(NoUserInSessionFilter.MONOLITH_ROUTE); + Cookie[] curCookies = request.getCookies(); + if (curCookies != null) { + for (Cookie c : curCookies) { + if (c.getName().equals(routeCookieName)) { + redir += "&" + c.getName() + "=" + c.getValue(); + } + } + } + } + + logger.debug("Redirect URL " + redir); + outputHash.put("PARAM", redir); + // also tell the system that this session is not fully validated so if someone + // comes without secret on this session + // dont allow + user.addShare(sessionId); } catch (NoSuchAlgorithmException e) { - e.printStackTrace(); + logger.error(STACKTRACE, e); } - - return WebUtility.getSO(outputHash); + + return WebUtility.getSO(outputHash); } - + @GET @Produces("application/json") @Path("/whoami") public Response show(@Context HttpServletRequest request, @Context HttpServletResponse response) { Principal principal = request.getUserPrincipal(); - Map output = new HashMap(); + Map output = new HashMap<>(); output.put("name", principal.getName()); if (principal instanceof WindowsPrincipal) { WindowsPrincipal windowsPrincipal = (WindowsPrincipal) principal; - List> gropus = new Vector>(); - for(waffle.windows.auth.WindowsAccount account : windowsPrincipal.getGroups().values()) { - Map m = new HashMap(); + List> gropus = new Vector<>(); + for (waffle.windows.auth.WindowsAccount account : windowsPrincipal.getGroups().values()) { + Map m = new HashMap<>(); m.put("name", account.getName()); m.put("domain", account.getDomain()); m.put("fqn", account.getFqn()); diff --git a/src/prerna/upload/DatabaseUploader.java b/src/prerna/upload/DatabaseUploader.java index 91a888248..311ef4c11 100644 --- a/src/prerna/upload/DatabaseUploader.java +++ b/src/prerna/upload/DatabaseUploader.java @@ -8,6 +8,7 @@ import java.io.PrintWriter; import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Arrays; import java.util.Calendar; import java.util.Date; import java.util.HashMap; @@ -27,6 +28,8 @@ import org.apache.commons.fileupload.FileItem; import org.apache.commons.io.FileUtils; +import org.apache.log4j.LogManager; +import org.apache.log4j.Logger; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; @@ -74,8 +77,9 @@ import prerna.util.sql.RdbmsTypeEnum; import prerna.web.services.util.WebUtility; +@Deprecated public class DatabaseUploader extends Uploader { - + private static final Logger logger = LogManager.getLogger(DatabaseUploader.class); // we will control the adding of the engine into local master and solr // such that we dont send a success before those processes are complete boolean autoLoad = false; @@ -297,7 +301,7 @@ public Response checkUserDefinedHeaders(MultivaluedMap form) { HeadersException headerChecker = HeadersException.getInstance(); if(type.equals("CSV")) { - Map> invalidHeadersMap = new Hashtable>(); + Map> invalidHeadersMap = new Hashtable<>(); // the key is for each file name // the list are the headers inside that file @@ -310,7 +314,7 @@ public Response checkUserDefinedHeaders(MultivaluedMap form) { // now we need to check all of these headers for(int colIdx = 0; colIdx < userHeaders.length; colIdx++) { String userHeader = userHeaders[colIdx]; - Map badHeaderMap = new Hashtable(); + Map badHeaderMap = new Hashtable<>(); if(headerChecker.isIllegalHeader(userHeader)) { badHeaderMap.put(userHeader, "This header name is a reserved word"); } else if(headerChecker.containsIllegalCharacter(userHeader)) { @@ -327,7 +331,7 @@ public Response checkUserDefinedHeaders(MultivaluedMap form) { if(invalidHeadersMap.containsKey(fileName)) { invalidHeadersForFile = invalidHeadersMap.get(fileName); } else { - invalidHeadersForFile = new Hashtable(); + invalidHeadersForFile = new Hashtable<>(); } // now add in the bad header for the file map @@ -340,7 +344,7 @@ public Response checkUserDefinedHeaders(MultivaluedMap form) { return WebUtility.getResponse(invalidHeadersMap, 200); } else if(type.equals("EXCEL")) { - List>> invalidHeadersList = new Vector>>(); + List>> invalidHeadersList = new Vector<>(); // each entry (outer map object) in the list if a workbook // each key in that map object is the sheetName for that given workbook @@ -349,7 +353,7 @@ public Response checkUserDefinedHeaders(MultivaluedMap form) { // iterate through each workbook for(Map excelWorkbook : userDefinedHeadersMap) { - Map> invalidHeadersMap = new Hashtable>(); + Map> invalidHeadersMap = new Hashtable<>(); for(String sheetName : excelWorkbook.keySet()) { // grab all the headers for the given sheet @@ -358,7 +362,7 @@ public Response checkUserDefinedHeaders(MultivaluedMap form) { // now we need to check all of these headers for(int colIdx = 0; colIdx < userHeaders.length; colIdx++) { String userHeader = userHeaders[colIdx]; - Map badHeaderMap = new Hashtable(); + Map badHeaderMap = new Hashtable<>(); if(headerChecker.isIllegalHeader(userHeader)) { badHeaderMap.put(userHeader, "This header name is a reserved word"); } else if(headerChecker.containsIllegalCharacter(userHeader)) { @@ -375,7 +379,7 @@ public Response checkUserDefinedHeaders(MultivaluedMap form) { if(invalidHeadersMap.containsKey(sheetName)) { invalidHeadersForSheet = invalidHeadersMap.get(sheetName); } else { - invalidHeadersForSheet = new Hashtable(); + invalidHeadersForSheet = new Hashtable<>(); } // now add in the bad header for the file map @@ -428,6 +432,7 @@ public Response uploadCsvFileAndPredictMetamodel(@Context HttpServletRequest req // get the property files if necessary String props = inputData.get("propFile"); String[] propFiles = null; + if(props != null && !props.isEmpty()) { propFiles = props.split(";"); } @@ -437,14 +442,14 @@ public Response uploadCsvFileAndPredictMetamodel(@Context HttpServletRequest req if(props == null) { throw new IOException("No prop file has been selected. Please select a prop file for the file"); } - if(propFiles.length != files.length) { + if (propFiles != null && propFiles.length != files.length) { throw new IOException("No prop file has been selected. Please select a prop file for the file"); } } for(int i = 0; i < files.length; i++) { // this is the MM info for one of the files within the metaModelData list - Map fileMetaModelData = new HashMap(); + Map fileMetaModelData = new HashMap<>(); // store the file location on server so FE can send that back into actual upload routine String filePath = files[i]; @@ -474,7 +479,7 @@ public Response uploadCsvFileAndPredictMetamodel(@Context HttpServletRequest req fileMetaModelData.putAll(metaModel); } else if(generateMetaModel.equals("prop")) { - if(propFiles[i] == null) { + if(propFiles == null || propFiles[i] == null) { throw new IOException("No prop file has been selected for file " + file); } //turn prop file into meta data @@ -512,7 +517,7 @@ public Response uploadCsvFileAndPredictMetamodel(@Context HttpServletRequest req e.printStackTrace(); // grab the error thrown and send it to the FE - HashMap errorMap = new HashMap(); + HashMap errorMap = new HashMap<>(); errorMap.put("errorMessage", e.getMessage()); return WebUtility.getResponse(errorMap, 400); } @@ -542,7 +547,7 @@ public Response uploadCSVFile(MultivaluedMap form, @Context Http // set the files String files = form.getFirst("file"); if(files == null || files.trim().isEmpty()) { - Map errorHash = new HashMap(); + Map errorHash = new HashMap<>(); errorHash.put("errorMessage", "No files have been identified to upload"); return Response.status(400).entity(gson.toJson(errorHash)).build(); } @@ -604,7 +609,7 @@ public Response uploadCSVFile(MultivaluedMap form, @Context Http // if no meta data specified, send an error if(allEmpty) { - Map errorHash = new HashMap(); + Map errorHash = new HashMap<>(); errorHash.put("errorMessage", "No metamodel has been specified.\n Please specify a metamodel in order to determine how to load this data."); return Response.status(400).entity(gson.toJson(errorHash)).build(); } @@ -629,7 +634,7 @@ public Response uploadCSVFile(MultivaluedMap form, @Context Http if(this.securityEnabled) { User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); if(user == null) { - Map errorHash = new HashMap(); + Map errorHash = new HashMap<>(); errorHash.put("errorMessage", "User must be signed into an account in order to create a database"); return Response.status(400).entity(gson.toJson(errorHash)).build(); } @@ -666,18 +671,18 @@ public Response uploadCSVFile(MultivaluedMap form, @Context Http } } catch (IOException e) { e.printStackTrace(); - Map errorHash = new HashMap(); + Map errorHash = new HashMap<>(); errorHash.put("errorMessage", "Failure to write CSV Prop File based on user-defined metamodel."); return Response.status(400).entity(gson.toJson(errorHash)).build(); } } catch (IOException e) { e.printStackTrace(); - Map errorHash = new HashMap(); + Map errorHash = new HashMap<>(); errorHash.put("errorMessage", e.getMessage()); return Response.status(400).entity(gson.toJson(errorHash)).build(); } catch(Exception e) { e.printStackTrace(); - Map errorHash = new HashMap(); + Map errorHash = new HashMap<>(); errorHash.put("errorMessage", e.getMessage()); return Response.status(400).entity(gson.toJson(errorHash)).build(); } finally { @@ -904,7 +909,7 @@ public Response uploadExcelFile(@Context HttpServletRequest request) { String[] files = inputData.get("file").split(";"); for(int i = 0; i < files.length; i++) { // this is the MM info for one of the files within the metaModelData list - Map fileMetaModelData = new HashMap(); + Map fileMetaModelData = new HashMap<>(); // store the file location on server so FE can send that back into actual upload routine fileMetaModelData.put("fileLocation", files[i]); @@ -927,7 +932,7 @@ public Response uploadExcelFile(@Context HttpServletRequest request) { ExcelSheetPreProcessor processor = sProcessors.get(sheet); List blocks = processor.getAllBlocks(); - Map rangeInfo = new HashMap(); + Map rangeInfo = new HashMap<>(); for(ExcelBlock block : blocks) { List ranges = block.getRanges(); @@ -939,7 +944,7 @@ public Response uploadExcelFile(@Context HttpServletRequest request) { Object[][] rangeTypes = block.getRangeTypes(r); Map[] retMaps = FileHelperUtil.generateDataTypeMapsFromPrediction(cleanedHeaders, rangeTypes); - Map rangeMap = new HashMap(); + Map rangeMap = new HashMap<>(); rangeMap.put("headers", origHeaders); rangeMap.put("cleanHeaders", cleanedHeaders); rangeMap.put("dataTypes", retMaps[0]); @@ -961,7 +966,7 @@ public Response uploadExcelFile(@Context HttpServletRequest request) { e.printStackTrace(); // grab the error thrown and send it to the FE - HashMap errorMap = new HashMap(); + HashMap errorMap = new HashMap<>(); errorMap.put("errorMessage", e.getMessage()); return WebUtility.getResponse(errorMap, 400); } @@ -996,7 +1001,7 @@ public Response uploadExcelPOIFormat(@Context HttpServletRequest request) // only default options not set are the files String files = inputData.get("file"); if(files == null || files.trim().isEmpty()) { - Map errorHash = new HashMap(); + Map errorHash = new HashMap<>(); errorHash.put("errorMessage", "No files have been identified to upload"); return Response.status(400).entity(gson.toJson(errorHash)).build(); } @@ -1006,7 +1011,7 @@ public Response uploadExcelPOIFormat(@Context HttpServletRequest request) if(this.securityEnabled) { User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); if(user == null) { - Map errorHash = new HashMap(); + Map errorHash = new HashMap<>(); errorHash.put("errorMessage", "User must be signed into an account in order to create a database"); return Response.status(400).entity(gson.toJson(errorHash)).build(); } @@ -1018,12 +1023,12 @@ public Response uploadExcelPOIFormat(@Context HttpServletRequest request) importer.runProcessor(options); } catch (IOException e) { e.printStackTrace(); - Map errorHash = new HashMap(); + Map errorHash = new HashMap<>(); errorHash.put("errorMessage", e.getMessage()); return Response.status(400).entity(gson.toJson(errorHash)).build(); } catch(Exception e) { e.printStackTrace(); - Map errorHash = new HashMap(); + Map errorHash = new HashMap<>(); errorHash.put("errorMessage", e.getMessage()); return Response.status(400).entity(gson.toJson(errorHash)).build(); } finally { @@ -1058,7 +1063,7 @@ public Response getExistingRDBMSMetadata(@Context HttpServletRequest request, Mu String schema = form.getFirst("schema"); String additionalProperties = form.getFirst("additionalParams"); - Map ret = new HashMap(); + Map ret = new HashMap<>(); try { ret = importer.getSchemaDetails(driver, hostname, port, username, password, schema, additionalProperties); } catch(Exception e) { @@ -1079,17 +1084,17 @@ public Response getExistingRDBMSMetadata(@Context HttpServletRequest request, Mu @Produces("application/json") public Response connectExistingRDBMS(@Context HttpServletRequest request, MultivaluedMap form) { Gson gson = new Gson(); - HashMap ret = new HashMap(1); - Map metamodel = new HashMap(); + HashMap ret = new HashMap<>(1); + Map metamodel = new HashMap<>(); HashMap details = gson.fromJson(form.getFirst("details"), new TypeToken>() {}.getType()); HashMap metamodelData = gson.fromJson(gson.toJson(details.get("metamodelData")), new TypeToken>() {}.getType()); ArrayList nodes = gson.fromJson(gson.toJson(metamodelData.get("nodes")), new TypeToken>() {}.getType()); ArrayList relationships = gson.fromJson(gson.toJson(metamodelData.get("relationships")), new TypeToken>() {}.getType()); // reformat metamodel for new reactor - HashMap> nodesAndProps = new HashMap>(nodes.size()); + HashMap> nodesAndProps = new HashMap<>(nodes.size()); ArrayList> nodeRelationships = new ArrayList<>(relationships.size()); for(Object o: nodes) { - ArrayList props = new ArrayList(); + ArrayList props = new ArrayList<>(); HashMap nodeHash = gson.fromJson(gson.toJson(o), new TypeToken>() {}.getType()); ArrayList properties = gson.fromJson(gson.toJson(nodeHash.get("prop")), new TypeToken>() {}.getType()); for(String prop : properties) { @@ -1191,7 +1196,7 @@ public Response testExistingRDBMSConnection(@Context HttpServletRequest request, String password = form.getFirst(ReactorKeysEnum.PASSWORD.getKey()); String schema = form.getFirst(ReactorKeysEnum.SCHEMA.getKey()); String additionalProperties = form.getFirst(ReactorKeysEnum.ADDITIONAL_CONNECTION_PARAMS_KEY.getKey()); - HashMap ret = new HashMap(); + HashMap ret = new HashMap<>(); ImportRDBMSProcessor importer = new ImportRDBMSProcessor(); String test = importer.checkConnectionParams(driver, hostname, port, username, password, schema, additionalProperties); @@ -1251,11 +1256,13 @@ public Response uploadXrayConfig(@Context HttpServletRequest request) { String jsonStringEscaped = gson.toJson(xray); AddToMasterDB lm = new AddToMasterDB(); lm.addXrayConfig(jsonStringEscaped, cleanName.replace(".xray", "")); + + br.close(); } } catch(Exception e) { e.printStackTrace(); // grab the error thrown and send it to the FE - HashMap errorMap = new HashMap(); + HashMap errorMap = new HashMap<>(); errorMap.put("errorMessage", e.getMessage()); return WebUtility.getResponse(errorMap, 400); } @@ -1297,7 +1304,7 @@ public Response processExcelFile(@Context HttpServletRequest request) // only default options not set are the files String files = inputData.get("file"); if(files == null || files.trim().isEmpty()) { - Map errorHash = new HashMap(); + Map errorHash = new HashMap<>(); errorHash.put("errorMessage", "No files have been identified to upload"); return Response.status(400).entity(gson.toJson(errorHash)).build(); } @@ -1352,7 +1359,7 @@ public Response processExcelFile(@Context HttpServletRequest request) propFileArr[i] = propWriter.getPropFile(); } if(allEmpty) { - Map errorHash = new HashMap(); + Map errorHash = new HashMap<>(); errorHash.put("errorMessage", "No metamodel has been specified. \nPlease specify a metamodel in order to determine how to load this data."); return Response.status(400).entity(gson.toJson(errorHash)).build(); } @@ -1364,7 +1371,7 @@ public Response processExcelFile(@Context HttpServletRequest request) if(this.securityEnabled) { User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); if(user == null) { - Map errorHash = new HashMap(); + Map errorHash = new HashMap<>(); errorHash.put("errorMessage", "User must be signed into an account in order to create a database"); return Response.status(400).entity(gson.toJson(errorHash)).build(); } @@ -1376,12 +1383,12 @@ public Response processExcelFile(@Context HttpServletRequest request) importer.runProcessor(options); } catch (IOException e) { e.printStackTrace(); - Map errorHash = new HashMap(); + Map errorHash = new HashMap<>(); errorHash.put("errorMessage", e.getMessage()); return Response.status(400).entity(gson.toJson(errorHash)).build(); } catch(Exception e) { e.printStackTrace(); - Map errorHash = new HashMap(); + Map errorHash = new HashMap<>(); errorHash.put("errorMessage", e.getMessage()); return Response.status(400).entity(gson.toJson(errorHash)).build(); } finally { @@ -1410,7 +1417,7 @@ public Response processExcelFile(@Context HttpServletRequest request) } } catch (IOException e) { e.printStackTrace(); - Map errorHash = new HashMap(); + Map errorHash = new HashMap<>(); errorHash.put("errorMessage", "Failure to write Excel Prop File based on user-defined metamodel."); return Response.status(400).entity(gson.toJson(errorHash)).build(); } @@ -1480,7 +1487,7 @@ public Response uploadNLPFile(@Context HttpServletRequest request) { } // set the files if(uploadFiles.trim().isEmpty()) { - Map errorHash = new HashMap(); + Map errorHash = new HashMap<>(); errorHash.put("errorMessage", "No files have been identified to upload"); return Response.status(400).entity(gson.toJson(errorHash)).build(); } @@ -1490,7 +1497,7 @@ public Response uploadNLPFile(@Context HttpServletRequest request) { if(this.securityEnabled) { User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); if(user == null) { - Map errorHash = new HashMap(); + Map errorHash = new HashMap<>(); errorHash.put("errorMessage", "User must be signed into an account in order to create a database"); return Response.status(400).entity(gson.toJson(errorHash)).build(); } @@ -1502,12 +1509,12 @@ public Response uploadNLPFile(@Context HttpServletRequest request) { importer.runProcessor(options); } catch (IOException e) { e.printStackTrace(); - Map errorHash = new HashMap(); + Map errorHash = new HashMap<>(); errorHash.put("errorMessage", e.getMessage()); return Response.status(400).entity(gson.toJson(errorHash)).build(); } catch(Exception e) { e.printStackTrace(); - Map errorHash = new HashMap(); + Map errorHash = new HashMap<>(); errorHash.put("errorMessage", e.getMessage()); return Response.status(400).entity(gson.toJson(errorHash)).build(); } finally { diff --git a/src/prerna/upload/ImageUploader.java b/src/prerna/upload/ImageUploader.java index 2e1b69fbd..1fca80ef5 100644 --- a/src/prerna/upload/ImageUploader.java +++ b/src/prerna/upload/ImageUploader.java @@ -4,6 +4,7 @@ import java.io.FileFilter; import java.io.FilenameFilter; import java.io.IOException; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -19,6 +20,8 @@ import org.apache.commons.fileupload.FileItem; import org.apache.commons.io.filefilter.WildcardFileFilter; +import org.apache.log4j.LogManager; +import org.apache.log4j.Logger; import prerna.auth.User; import prerna.auth.utils.SecurityAppUtils; @@ -32,196 +35,210 @@ import prerna.web.services.util.WebUtility; public class ImageUploader extends Uploader { - + private static final Logger logger = LogManager.getLogger(ImageUploader.class); + private static final String ERROR_MESSAGE = "errorMessage"; + private static final String STACKTRACE = "StackTrace: "; + @POST @Path("/appImage") @Produces("application/json") public Response uploadAppImage(@Context HttpServletRequest request) { - Map returnMap = new HashMap(); - + Map returnMap = new HashMap<>(); + List fileItems = processRequest(request, null); // collect all of the data input on the form FileItem imageFile = null; String appId = null; String appName = null; - - for(FileItem fi : fileItems) { + + for (FileItem fi : fileItems) { String fieldName = fi.getFieldName(); String value = fi.getString(); - if(fieldName.equals("file")) { + if (fieldName.equals("file")) { imageFile = fi; } - if(fieldName.equals("app")) { + if (fieldName.equals("app")) { appName = value; } } - if(this.securityEnabled) { + if (imageFile == null) { + returnMap.put(ERROR_MESSAGE, "Could not find the file to upload for the insight in the request"); + return WebUtility.getResponse(returnMap, 400); + } else if (appName == null) { + returnMap.put(ERROR_MESSAGE, "Need to pass the proper app id to upload the image"); + return WebUtility.getResponse(returnMap, 400); + } + + if (this.securityEnabled) { HttpSession session = request.getSession(false); - if(session != null){ + if (session != null) { User user = ((User) session.getAttribute(Constants.SESSION_USER)); - if(user == null) { - HashMap errorMap = new HashMap(); - errorMap.put("errorMessage", "Session could not be validated in order to upload the app image"); + if (user == null) { + HashMap errorMap = new HashMap<>(); + errorMap.put(ERROR_MESSAGE, "Session could not be validated in order to upload the app image"); return WebUtility.getResponse(errorMap, 400); } - - if(user.isAnonymous()) { - HashMap errorMap = new HashMap(); - errorMap.put("errorMessage", "Must be logged in to upload an app image"); + + if (user.isAnonymous()) { + HashMap errorMap = new HashMap<>(); + errorMap.put(ERROR_MESSAGE, "Must be logged in to upload an app image"); return WebUtility.getResponse(errorMap, 400); } - + try { appId = SecurityQueryUtils.testUserEngineIdForAlias(user, appName); - } catch(Exception e) { - returnMap.put("errorMessage", e.getMessage()); + } catch (Exception e) { + returnMap.put(ERROR_MESSAGE, e.getMessage()); return WebUtility.getResponse(returnMap, 400); } - if(!SecurityAppUtils.userCanEditEngine(user, appId)) { - returnMap.put("errorMessage", "User does not have access to this app or the app id does not exist"); + if (!SecurityAppUtils.userCanEditEngine(user, appId)) { + returnMap.put(ERROR_MESSAGE, "User does not have access to this app or the app id does not exist"); return WebUtility.getResponse(returnMap, 400); } appName = SecurityQueryUtils.getEngineAliasForId(appId); } else { - returnMap.put("errorMessage", "User session is invalid"); + returnMap.put(ERROR_MESSAGE, "User session is invalid"); return WebUtility.getResponse(returnMap, 400); } } else { appId = MasterDatabaseUtility.testEngineIdIfAlias(appName); appName = MasterDatabaseUtility.getEngineAliasForId(appId); String appDir = filePath + DIR_SEPARATOR + SmssUtilities.getUniqueName(appName, appId); - if(!(new File(appDir).exists())) { - returnMap.put("errorMessage", "Could not find app directory"); + if (!(new File(appDir).exists())) { + returnMap.put(ERROR_MESSAGE, "Could not find app directory"); return WebUtility.getResponse(returnMap, 400); } } - + // now that we have the app name // and the image file // we want to write it into the app location - String imageDir = filePath + DIR_SEPARATOR + SmssUtilities.getUniqueName(appName, appId) + DIR_SEPARATOR + "version"; + String imageDir = filePath + DIR_SEPARATOR + SmssUtilities.getUniqueName(appName, appId) + DIR_SEPARATOR + + "version"; String imageLoc = imageDir + DIR_SEPARATOR + "image." + imageFile.getContentType().split("/")[1]; - if(ClusterUtil.IS_CLUSTER){ - imageDir=ClusterUtil.IMAGES_FOLDER_PATH+ DIR_SEPARATOR + "apps"; + if (ClusterUtil.IS_CLUSTER) { + imageDir = ClusterUtil.IMAGES_FOLDER_PATH + DIR_SEPARATOR + "apps"; imageLoc = imageDir + DIR_SEPARATOR + appId + "." + imageFile.getContentType().split("/")[1]; } File f = new File(imageDir); - if(!f.exists()) { + if (!f.exists()) { f.mkdirs(); } f = new File(imageLoc); // find all the existing image files // and delete them File[] oldImages = null; - if(ClusterUtil.IS_CLUSTER){ - FilenameFilter appIdFilter = new WildcardFileFilter(appId+"*"); + if (ClusterUtil.IS_CLUSTER) { + FilenameFilter appIdFilter = new WildcardFileFilter(appId + "*"); oldImages = f.getParentFile().listFiles(appIdFilter); - } else{ - oldImages = findImageFile(f.getParentFile()); + } else { + oldImages = findImageFile(f.getParentFile()); } // delete if any exist - if(oldImages != null) { - for(File oldI : oldImages) { + if (oldImages != null) { + for (File oldI : oldImages) { oldI.delete(); } } writeFile(imageFile, f); try { - if(ClusterUtil.IS_CLUSTER){ - CloudClient.getClient().pushImageFolder(); + if (ClusterUtil.IS_CLUSTER) { + CloudClient.getClient().pushImageFolder(); } - } catch (IOException | InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); + } catch (IOException ioe) { + logger.error(STACKTRACE, ioe); + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); + logger.error(STACKTRACE, ie); } returnMap.put("message", "successfully updated app image"); return WebUtility.getResponse(returnMap, 200); } - + @POST @Path("/insightImage") @Produces("application/json") public Response uploadInsightImage(@Context HttpServletRequest request) { - Map returnMap = new HashMap(); - + Map returnMap = new HashMap<>(); List fileItems = processRequest(request, null); // collect all of the data input on the form FileItem imageFile = null; String appId = null; String appName = null; String insightId = null; - - for(FileItem fi : fileItems) { + + for (FileItem fi : fileItems) { String fieldName = fi.getFieldName(); String value = fi.getString(); - if(fieldName.equals("file")) { + if (fieldName.equals("file")) { imageFile = fi; } - if(fieldName.equals("app")) { + if (fieldName.equals("app")) { appName = value; } - if(fieldName.equals("insightId")) { + if (fieldName.equals("insightId")) { insightId = value; } } - if(imageFile == null) { - returnMap.put("errorMessage", "Could not find the file to upload for the insight in the request"); + if (imageFile == null) { + returnMap.put(ERROR_MESSAGE, "Could not find the file to upload for the insight in the request"); return WebUtility.getResponse(returnMap, 400); - } else if(appName == null || insightId == null) { - returnMap.put("errorMessage", "Need to pass the proper app and insight ids to upload the image"); + } else if (appName == null || insightId == null) { + returnMap.put(ERROR_MESSAGE, "Need to pass the proper app and insight ids to upload the image"); return WebUtility.getResponse(returnMap, 400); } - - if(this.securityEnabled) { + + if (this.securityEnabled) { HttpSession session = request.getSession(false); - if(session != null){ + if (session != null) { User user = ((User) session.getAttribute(Constants.SESSION_USER)); - if(user == null) { - HashMap errorMap = new HashMap(); - errorMap.put("errorMessage", "Session could not be validated in order to upload the insight image"); + if (user == null) { + HashMap errorMap = new HashMap<>(); + errorMap.put(ERROR_MESSAGE, "Session could not be validated in order to upload the insight image"); return WebUtility.getResponse(errorMap, 400); } - - if(user.isAnonymous()) { - HashMap errorMap = new HashMap(); - errorMap.put("errorMessage", "Must be logged in to upload an insight image"); + + if (user.isAnonymous()) { + HashMap errorMap = new HashMap<>(); + errorMap.put(ERROR_MESSAGE, "Must be logged in to upload an insight image"); return WebUtility.getResponse(errorMap, 400); } - + try { appId = SecurityQueryUtils.testUserEngineIdForAlias(user, appName); - } catch(Exception e) { - returnMap.put("errorMessage", e.getMessage()); + } catch (Exception e) { + returnMap.put(ERROR_MESSAGE, e.getMessage()); return WebUtility.getResponse(returnMap, 400); } - if(!SecurityInsightUtils.userCanEditInsight(user, appId, insightId)) { - returnMap.put("errorMessage", "User does not have access to edit this insight within the app"); + if (!SecurityInsightUtils.userCanEditInsight(user, appId, insightId)) { + returnMap.put(ERROR_MESSAGE, "User does not have access to edit this insight within the app"); return WebUtility.getResponse(returnMap, 400); } appName = SecurityQueryUtils.getEngineAliasForId(appId); } else { - returnMap.put("errorMessage", "User session is invalid"); + returnMap.put(ERROR_MESSAGE, "User session is invalid"); return WebUtility.getResponse(returnMap, 400); } } else { appId = MasterDatabaseUtility.testEngineIdIfAlias(appName); appName = MasterDatabaseUtility.getEngineAliasForId(appId); String appDir = filePath + DIR_SEPARATOR + SmssUtilities.getUniqueName(appName, appId); - if(!(new File(appDir).exists())) { - returnMap.put("errorMessage", "Could not find app directory"); + if (!(new File(appDir).exists())) { + returnMap.put(ERROR_MESSAGE, "Could not find app directory"); return WebUtility.getResponse(returnMap, 400); } } - + // now that we have the app name // and the image file // we want to write it into the app location - String imageDir = filePath + DIR_SEPARATOR + SmssUtilities.getUniqueName(appName, appId) + DIR_SEPARATOR + "version" + DIR_SEPARATOR + insightId; + String imageDir = filePath + DIR_SEPARATOR + SmssUtilities.getUniqueName(appName, appId) + DIR_SEPARATOR + + "version" + DIR_SEPARATOR + insightId; File f = new File(imageDir); - if(!f.exists()) { + if (!f.exists()) { f.mkdirs(); } String imageLoc = imageDir + DIR_SEPARATOR + "image." + imageFile.getContentType().split("/")[1]; @@ -230,24 +247,25 @@ public Response uploadInsightImage(@Context HttpServletRequest request) { // and delete them File[] oldImages = findImageFile(f.getParentFile()); // delete if any exist - if(oldImages != null) { - for(File oldI : oldImages) { + if (oldImages != null) { + for (File oldI : oldImages) { oldI.delete(); } } writeFile(imageFile, f); - + returnMap.put("message", "successfully updated insight image"); return WebUtility.getResponse(returnMap, 200); } - + /** * Find an image in the directory + * * @param baseDir * @return */ public static File[] findImageFile(String baseDir) { - List extensions = new Vector(); + List extensions = new Vector<>(); extensions.add("image.png"); extensions.add("image.jpeg"); extensions.add("image.jpg"); @@ -255,24 +273,25 @@ public static File[] findImageFile(String baseDir) { extensions.add("image.svg"); FileFilter imageExtensionFilter = new WildcardFileFilter(extensions); File baseFolder = new File(baseDir); - File[] imageFiles = baseFolder.listFiles(imageExtensionFilter); - return imageFiles; + + return baseFolder.listFiles(imageExtensionFilter); } - + /** * Find an image in the directory + * * @param baseDir * @return */ public static File[] findImageFile(File baseFolder) { - List extensions = new Vector(); + List extensions = new Vector<>(); extensions.add("image.png"); extensions.add("image.jpeg"); extensions.add("image.jpg"); extensions.add("image.gif"); extensions.add("image.svg"); FileFilter imageExtensionFilter = new WildcardFileFilter(extensions); - File[] imageFiles = baseFolder.listFiles(imageExtensionFilter); - return imageFiles; + + return baseFolder.listFiles(imageExtensionFilter); } } diff --git a/src/prerna/upload/Uploader.java b/src/prerna/upload/Uploader.java index 214b0f226..760fb1317 100644 --- a/src/prerna/upload/Uploader.java +++ b/src/prerna/upload/Uploader.java @@ -51,20 +51,21 @@ import prerna.om.InsightStore; import prerna.poi.main.HeadersException; import prerna.poi.main.helper.CSVFileHelper; +import prerna.util.Utility; /** * Servlet implementation class Uploader */ @SuppressWarnings("serial") public abstract class Uploader extends HttpServlet { - - private static final Logger LOGGER = LogManager.getLogger(Uploader.class); + private static final Logger logger = LogManager.getLogger(Uploader.class); // get the directory separator protected static final String DIR_SEPARATOR = java.nio.file.FileSystems.getDefault().getSeparator(); public static final String CSV_FILE_KEY = "CSV"; public static final String CSV_HELPER_MESSAGE = "HTML_RESPONSE"; + private static final String STACKTRACE = "StackTrace: "; protected int maxFileSize = 10_000_000 * 1024; protected int maxMemSize = 8 * 1024; @@ -77,10 +78,14 @@ public abstract class Uploader extends HttpServlet { boolean autoLoad = false; public void setFilePath(String filePath) { - if(filePath.endsWith(DIR_SEPARATOR)) { - this.filePath = filePath; + // first, normalize path + String normalizedfilePath = Utility.normalizePath(filePath); + + // then set path + if(normalizedfilePath.endsWith(DIR_SEPARATOR)) { + this.filePath = normalizedfilePath; } else { - this.filePath = filePath + DIR_SEPARATOR; + this.filePath = normalizedfilePath + DIR_SEPARATOR; } File f = new File(this.filePath); if(!f.exists() && !f.isDirectory()) { @@ -89,8 +94,12 @@ public void setFilePath(String filePath) { } public void setTempFilePath(String tempFilePath){ - this.tempFilePath = tempFilePath; - File tFile = new File(tempFilePath); + // first, normalize path + String normalizedTempFilePath = Utility.normalizePath(tempFilePath); + + // then set path + this.tempFilePath = normalizedTempFilePath; + File tFile = new File(normalizedTempFilePath); if(!tFile.exists() && !tFile.isDirectory()) { tFile.mkdirs(); } @@ -104,13 +113,17 @@ public void writeFile(FileItem fi, File file){ try { fi.write(file); } catch (Exception e) { - e.printStackTrace(); + logger.error(STACKTRACE, e); } } protected void deleteFilesFromServer(String[] files) { for(String file : files) { - File f = new File(file); + // first, normalize path + String normalizedFile = Utility.normalizePath(file); + + // then delete + File f = new File(normalizedFile); ICache.deleteFile(f); } } @@ -141,15 +154,12 @@ protected List processRequest(@Context HttpServletRequest request, Str ProgressListener progressListener = new FileUploadProgressListener(insightId); upload.setProgressListener(progressListener); - // long start = System.currentTimeMillis(); // Parse the request to get file items fileItems = upload.parseRequest(request); - // long end = System.currentTimeMillis(); - // System.out.println("Time to create temp = " + (end - start) + "ms"); - } catch (FileUploadException e) { - e.printStackTrace(); + } catch (FileUploadException fue) { + logger.error(STACKTRACE, fue); } catch (Exception e) { - e.printStackTrace(); + logger.error(STACKTRACE, e); } return fileItems; } @@ -160,12 +170,12 @@ protected Hashtable getInputData(List fileItems) Iterator iteratorFileItems = fileItems.iterator(); // collect all of the data input on the form - Hashtable inputData = new Hashtable(); + Hashtable inputData = new Hashtable<>(); File file; while(iteratorFileItems.hasNext()) { - FileItem fi = (FileItem) iteratorFileItems.next(); + FileItem fi = iteratorFileItems.next(); // Get the uploaded file parameters String fieldName = fi.getFieldName(); String fileName = fi.getName(); @@ -185,16 +195,13 @@ protected Hashtable getInputData(List fileItems) String modifiedDate = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_SSSS").format(date); value = this.filePath + fileName.substring(fileName.lastIndexOf(DIR_SEPARATOR) + 1, fileName.lastIndexOf(".")).trim().replace(" ", "_") + "_____UNIQUE" + modifiedDate + fileName.substring(fileName.lastIndexOf(".")); file = new File(value); - -// long start = System.currentTimeMillis(); + writeFile(fi, file); -// long end = System.currentTimeMillis(); -// System.out.println("Time to write file = " + (end - start) + "ms"); - LOGGER.info("File item is the actual data. Saved Filename: " + fileName + " to "+ file); + logger.info("File item is the actual data. Saved Filename: " + fileName + " to "+ file); } } } else { - LOGGER.info("File item type is " + fi.getFieldName() + fi.getString()); + logger.info("File item type is " + fi.getFieldName() + fi.getString()); } //need to handle multiple files getting selected for upload if(value == null) { diff --git a/src/prerna/web/conf/AdminStartupFilter.java b/src/prerna/web/conf/AdminStartupFilter.java index 83de39e91..8e32095d5 100644 --- a/src/prerna/web/conf/AdminStartupFilter.java +++ b/src/prerna/web/conf/AdminStartupFilter.java @@ -10,6 +10,10 @@ import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletResponse; +import org.apache.log4j.LogManager; +import org.apache.log4j.Logger; +import org.owasp.encoder.Encode; + import prerna.auth.utils.AbstractSecurityUtils; import prerna.engine.api.IEngine; import prerna.engine.api.IRawSelectWrapper; @@ -18,12 +22,14 @@ import prerna.util.Utility; public class AdminStartupFilter implements Filter { - + + private static final Logger logger = LogManager.getLogger(AdminStartupFilter.class); + private static final String STACKTRACE = "StackTrace: "; private static String initialRedirect; @Override public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { - if(AbstractSecurityUtils.securityEnabled()) { + if (AbstractSecurityUtils.securityEnabled()) { IEngine engine = Utility.getEngine(Constants.SECURITY_DB); String q = "SELECT * FROM USER LIMIT 1"; IRawSelectWrapper wrapper = null; @@ -32,19 +38,19 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 boolean hasUser = wrapper.hasNext(); // if there are users, redirect to the main semoss page // we do not want to allow the person to make any admin requests - if(hasUser) { - if(initialRedirect != null) { - ((HttpServletResponse) arg1).setHeader("redirect", initialRedirect); - ((HttpServletResponse) arg1).sendError(302, "Need to redirect to " + initialRedirect); + if (hasUser) { + if (initialRedirect != null) { + String encodedRedirectUrl = Encode.forHtml(initialRedirect); + ((HttpServletResponse) arg1).setHeader("redirect", encodedRedirectUrl); + ((HttpServletResponse) arg1).sendError(302, "Need to redirect to " + encodedRedirectUrl); } else { ((HttpServletResponse) arg1).sendError(404, "Page Not Found"); } - return; } } catch (Exception e) { - e.printStackTrace(); + logger.error(STACKTRACE, e); } finally { - if(wrapper != null) { + if (wrapper != null) { wrapper.cleanUp(); } } @@ -55,14 +61,12 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 @Override public void destroy() { - // TODO Auto-generated method stub - + // destroy } @Override public void init(FilterConfig arg0) throws ServletException { - // TODO Auto-generated method stub - + // initialize } public static void setSuccessfulRedirectUrl(String initialRedirect) { diff --git a/src/prerna/web/conf/DBLoader.java b/src/prerna/web/conf/DBLoader.java index 634501efe..72a013bb7 100644 --- a/src/prerna/web/conf/DBLoader.java +++ b/src/prerna/web/conf/DBLoader.java @@ -60,90 +60,91 @@ public class DBLoader implements ServletContextListener { - private static final Logger LOGGER = LogManager.getLogger(DBLoader.class.getName()); + private static final Logger logger = LogManager.getLogger(DBLoader.class); private static final String RDFMAP = "RDF-MAP"; private static String SESSION_ID_KEY = "JSESSIONID"; + private static final String STACKTRACE = "StackTrace: "; private static boolean useLogoutPage = false; private static String customLogoutUrl = null; - - // keep track of all the watcher threads to kill - private static List watcherList = new Vector(); - + + // keep track of all the watcher threads to kill + private static List watcherList = new Vector<>(); + @Override public void contextInitialized(ServletContextEvent arg0) { ServletContext context = arg0.getServletContext(); String contextPath = context.getContextPath(); - + String rdfPropFile = context.getInitParameter(RDFMAP); // see if security is enabled String securityEnabled = context.getInitParameter(Constants.SECURITY_ENABLED); - + // see if only admins can set an engine as public String adminSetPublicOnly = context.getInitParameter(Constants.ADMIN_SET_PUBLIC); - if(adminSetPublicOnly == null) { + if (adminSetPublicOnly == null) { adminSetPublicOnly = "false"; } context.setInitParameter(Constants.ADMIN_SET_PUBLIC, adminSetPublicOnly); - + // see if admin can determine who can publish String adminSetPublisher = context.getInitParameter(Constants.ADMIN_SET_PUBLISHER); - if(adminSetPublisher == null) { + if (adminSetPublisher == null) { adminSetPublisher = "false"; } context.setInitParameter(Constants.ADMIN_SET_PUBLISHER, adminSetPublisher); - + // see if we allow anonymous users String anonymousUsersEnabled = context.getInitParameter(Constants.ANONYMOUS_USER_ALLOWED); - if(anonymousUsersEnabled == null) { + if (anonymousUsersEnabled == null) { anonymousUsersEnabled = "false"; } context.setInitParameter(Constants.ANONYMOUS_USER_ALLOWED, anonymousUsersEnabled); // see if anonymous users can upload data String anonymousUsersUploadData = context.getInitParameter(Constants.ANONYMOUS_USER_UPLOAD_DATA); - if(anonymousUsersUploadData == null) { + if (anonymousUsersUploadData == null) { anonymousUsersUploadData = "false"; } context.setInitParameter(Constants.ANONYMOUS_USER_UPLOAD_DATA, anonymousUsersUploadData); - + // see if we redirect to logout page or back to login screen String useLogoutPage = context.getInitParameter(Constants.USE_LOGOUT_PAGE); - if(useLogoutPage == null) { + if (useLogoutPage == null) { useLogoutPage = "false"; } context.setInitParameter(Constants.USE_LOGOUT_PAGE, useLogoutPage); DBLoader.useLogoutPage = Boolean.parseBoolean(useLogoutPage); - + // see if we redirect to logout page or back to login screen String customLogoutUrl = context.getInitParameter(Constants.CUSTOM_LOGOUT_URL); - if(customLogoutUrl != null && !customLogoutUrl.trim().isEmpty()) { + if (customLogoutUrl != null && !customLogoutUrl.trim().isEmpty()) { String trimmedUrl = customLogoutUrl.trim(); context.setInitParameter(Constants.CUSTOM_LOGOUT_URL, trimmedUrl); DBLoader.customLogoutUrl = trimmedUrl; } - + // get the session id key - if(context.getSessionCookieConfig() != null) { + if (context.getSessionCookieConfig() != null) { SessionCookieConfig cookieConfig = context.getSessionCookieConfig(); - if(cookieConfig != null && cookieConfig.getName() != null) { + if (cookieConfig != null && cookieConfig.getName() != null) { DBLoader.SESSION_ID_KEY = cookieConfig.getName(); } } - - LOGGER.info("Initializing application context..." + contextPath); - - //Set default file separator system variable - LOGGER.info("Changing file separator value to: '/'"); + + logger.info("Initializing application context..." + Utility.cleanLogString(contextPath)); + + // Set default file separator system variable + logger.info("Changing file separator value to: '/'"); System.setProperty("file.separator", "/"); - - //Load RDF_Map.prop file - LOGGER.info("Loading RDF_Map.prop: " + rdfPropFile); + + // Load RDF_Map.prop file + logger.info("Loading RDF_Map.prop: " + Utility.cleanLogString(rdfPropFile)); DIHelper.getInstance().loadCoreProp(rdfPropFile); - - //Set log4j prop + + // Set log4j prop String log4jConfig = DIHelper.getInstance().getProperty("LOG4J"); - LOGGER.info("Setting log4j property: " + log4jConfig); + logger.info("Setting log4j property: " + log4jConfig); PropertyConfigurator.configure(log4jConfig); - + // set security enabled within DIHelper first // this is because security database, on init, will // load it as a boolean instead of us searching within DIHelper @@ -155,52 +156,52 @@ public void contextInitialized(ServletContextEvent arg0) { DIHelper.getInstance().setLocalProperty(Constants.USE_LOGOUT_PAGE, useLogoutPage); DIHelper.getInstance().setLocalProperty(Constants.SESSION_ID_KEY, SESSION_ID_KEY); - //Load empty engine list into DIHelper, then load engines from db folder - LOGGER.info("Loading engines..."); + // Load empty engine list into DIHelper, then load engines from db folder + logger.info("Loading engines..."); String engines = ""; - DIHelper.getInstance().setLocalProperty(Constants.ENGINES, engines); + DIHelper.getInstance().setLocalProperty(Constants.ENGINES, engines); loadEngines(); - + // //Just load R right away to avoid synchronization issues // try { // RJavaTranslatorFactory.initRConnection(); // } catch(Exception e) { // e.printStackTrace(); // } - + // need to set the path // important for taking the image with security ChromeDriverUtility.setContextPath(contextPath); - + // if there was an issue starting up the server // we should do it here so that we can redirect the user { IEngine localmaster = (IEngine) DIHelper.getInstance().getLocalProp(Constants.LOCAL_MASTER_DB_NAME); IEngine security = (IEngine) DIHelper.getInstance().getLocalProp(Constants.SECURITY_DB); - if(localmaster == null || security == null || !localmaster.isConnected() || !security.isConnected()) { + if (localmaster == null || security == null || !localmaster.isConnected() || !security.isConnected()) { // you have messed up!!! StartUpSuccessFilter.setStartUpSuccess(false); } } } - + public void loadEngines() { String watcherStr = DIHelper.getInstance().getProperty(Constants.ENGINE_WEB_WATCHER); StringTokenizer watchers = new StringTokenizer(watcherStr, ";"); - try { - while(watchers.hasMoreElements()) { + try { + while (watchers.hasMoreElements()) { Object monitor = new Object(); String watcher = watchers.nextToken(); String watcherClass = DIHelper.getInstance().getProperty(watcher); String folder = DIHelper.getInstance().getProperty(watcher + "_DIR"); String ext = DIHelper.getInstance().getProperty(watcher + "_EXT"); - AbstractFileWatcher watcherInstance = (AbstractFileWatcher) Class.forName(watcherClass).getConstructor(null).newInstance(null); + AbstractFileWatcher watcherInstance = (AbstractFileWatcher) Class.forName(watcherClass) + .getConstructor(null).newInstance(null); watcherInstance.setMonitor(monitor); watcherInstance.setFolderToWatch(folder); watcherInstance.setExtension(ext); watcherInstance.init(); - synchronized(monitor) - { + synchronized (monitor) { Thread thread = new Thread(watcherInstance); thread.start(); watcherList.add(watcherInstance); @@ -210,96 +211,98 @@ public void loadEngines() { ex.printStackTrace(); } } - + @Override public void contextDestroyed(ServletContextEvent arg0) { - LOGGER.info("Start shutdown"); + logger.info("Start shutdown"); - Set insights = new HashSet(InsightStore.getInstance().getAllInsights()); - for(String id : insights) { + Set insights = new HashSet<>(InsightStore.getInstance().getAllInsights()); + for (String id : insights) { Insight in = InsightStore.getInstance().get(id); - LOGGER.info("Closing insight " + id); + logger.info("Closing insight " + id); InsightUtility.dropInsight(in); } - + // close watchers - for(AbstractFileWatcher watcher : watcherList) { + for (AbstractFileWatcher watcher : watcherList) { watcher.shutdown(); } - + // we need to close all the engine ids List eIds = MasterDatabaseUtility.getAllEngineIds(); - for(String id : eIds) { + for (String id : eIds) { // grab only loaded engines IEngine engine = (IEngine) DIHelper.getInstance().getLocalProp(id); - if(engine != null) { + if (engine != null) { // if it is loaded, close it - LOGGER.info("Closing database " + id); + logger.info("Closing database " + id); engine.closeDB(); } } - + // these are not loaded in the normal fashion // so specifically pull them to close IEngine engine = Utility.getEngine(AbstractFormBuilder.FORM_BUILDER_ENGINE_NAME); - if(engine != null) { - LOGGER.info("Closing database " + AbstractFormBuilder.FORM_BUILDER_ENGINE_NAME); + if (engine != null) { + logger.info("Closing database " + AbstractFormBuilder.FORM_BUILDER_ENGINE_NAME); engine.closeDB(); } else { - LOGGER.info("Couldn't find database " + AbstractFormBuilder.FORM_BUILDER_ENGINE_NAME); + logger.info("Couldn't find database " + AbstractFormBuilder.FORM_BUILDER_ENGINE_NAME); } - + engine = Utility.getEngine(Constants.SECURITY_DB); - if(engine != null) { - LOGGER.info("Closing database " + Constants.SECURITY_DB); + if (engine != null) { + logger.info("Closing database " + Constants.SECURITY_DB); engine.closeDB(); } else { - LOGGER.info("Couldn't find database " + Constants.SECURITY_DB); + logger.info("Couldn't find database " + Constants.SECURITY_DB); } - + engine = Utility.getEngine(Constants.LOCAL_MASTER_DB_NAME); - if(engine != null) { - LOGGER.info("Closing database " + Constants.LOCAL_MASTER_DB_NAME); + if (engine != null) { + logger.info("Closing database " + Constants.LOCAL_MASTER_DB_NAME); engine.closeDB(); } else { - LOGGER.info("Couldn't find database " + Constants.LOCAL_MASTER_DB_NAME); + logger.info("Couldn't find database " + Constants.LOCAL_MASTER_DB_NAME); } - + // close scheduler try { - LOGGER.info("Closing scheduler"); + logger.info("Closing scheduler"); SchedulerUtil.shutdownScheduler(true); } catch (SchedulerException e) { - e.printStackTrace(); + logger.error(STACKTRACE, e); } - + // close r try { RJavaTranslatorFactory.stopRConnection(); - } catch(Exception e) { - e.printStackTrace(); + } catch (Exception e) { + logger.error(STACKTRACE, e); } - - LOGGER.info("Finished shutdown"); + + logger.info("Finished shutdown"); } - + /** * Get the user defined session id key + * * @return */ public static String getSessionIdKey() { return DBLoader.SESSION_ID_KEY; } - + /** - * Get if we should redirect to a dedicated logout page - * Or back to the login page + * Get if we should redirect to a dedicated logout page Or back to the login + * page + * * @return */ public static boolean useLogoutPage() { return DBLoader.useLogoutPage; } - + public static String getCustomLogoutUrl() { return DBLoader.customLogoutUrl; } diff --git a/src/prerna/web/conf/IASFilter.java b/src/prerna/web/conf/IASFilter.java index b7a099256..80f0e811f 100644 --- a/src/prerna/web/conf/IASFilter.java +++ b/src/prerna/web/conf/IASFilter.java @@ -19,6 +19,7 @@ import prerna.auth.User; import prerna.auth.utils.SecurityUpdateUtils; import prerna.util.Constants; +import prerna.util.Utility; public class IASFilter implements Filter { @@ -26,7 +27,7 @@ public class IASFilter implements Filter { private static final String EMAIL = "PRI_EMAIL"; private static final String ID = "UNIQUE_ID"; - private static final Logger LOGGER = LogManager.getLogger(IASFilter.class.getName()); + private static final Logger logger = LogManager.getLogger(IASFilter.class.getName()); @Override public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { @@ -44,11 +45,11 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 if(dodId == null || email == null || id == null || dodId.isEmpty() || email.isEmpty() || id.isEmpty() ) { - LOGGER.info("REQUEST COMING WITH NO USER"); - LOGGER.info("REQUEST COMING WITH NO USER"); - LOGGER.info("REQUEST COMING WITH NO USER"); - LOGGER.info("REQUEST COMING WITH NO USER"); - LOGGER.info("REQUEST COMING WITH NO USER"); + logger.info("REQUEST COMING WITH NO USER"); + logger.info("REQUEST COMING WITH NO USER"); + logger.info("REQUEST COMING WITH NO USER"); + logger.info("REQUEST COMING WITH NO USER"); + logger.info("REQUEST COMING WITH NO USER"); valid = false; } @@ -64,16 +65,16 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 user.setAccessToken(token); session.setAttribute(Constants.SESSION_USER, user); - LOGGER.info("NEW SESSION - USER ADDED WITH ID = " + id); - LOGGER.info("NEW SESSION - USER ADDED WITH ID = " + id); - LOGGER.info("NEW SESSION - USER ADDED WITH ID = " + id); - LOGGER.info("NEW SESSION - USER ADDED WITH ID = " + id); + logger.info("NEW SESSION - USER ADDED WITH ID = " + Utility.cleanLogString(id)); + logger.info("NEW SESSION - USER ADDED WITH ID = " + Utility.cleanLogString(id)); + logger.info("NEW SESSION - USER ADDED WITH ID = " + Utility.cleanLogString(id)); + logger.info("NEW SESSION - USER ADDED WITH ID = " + Utility.cleanLogString(id)); } } else { - LOGGER.info("EXISTING SESSION WITH USER ALREADY PRESENT"); - LOGGER.info("EXISTING SESSION WITH USER ALREADY PRESENT"); - LOGGER.info("EXISTING SESSION WITH USER ALREADY PRESENT"); - LOGGER.info("EXISTING SESSION WITH USER ALREADY PRESENT"); + logger.info("EXISTING SESSION WITH USER ALREADY PRESENT"); + logger.info("EXISTING SESSION WITH USER ALREADY PRESENT"); + logger.info("EXISTING SESSION WITH USER ALREADY PRESENT"); + logger.info("EXISTING SESSION WITH USER ALREADY PRESENT"); } arg2.doFilter(arg0, arg1); diff --git a/src/prerna/web/conf/NoUserInSessionFilter.java b/src/prerna/web/conf/NoUserInSessionFilter.java index e84e576e5..be8838db6 100644 --- a/src/prerna/web/conf/NoUserInSessionFilter.java +++ b/src/prerna/web/conf/NoUserInSessionFilter.java @@ -22,6 +22,10 @@ import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; +import org.apache.log4j.LogManager; +import org.apache.log4j.Logger; +import org.owasp.encoder.Encode; + import prerna.auth.AuthProvider; import prerna.auth.InsightToken; import prerna.auth.User; @@ -31,20 +35,23 @@ import prerna.web.requests.MultiReadHttpServletRequest; public class NoUserInSessionFilter implements Filter { + + private static final Logger logger = LogManager.getLogger(NoUserInSessionFilter.class); // this is so if you are making a direct BE request // after you sign in // we can redirect you back to the original call // instead of taking you to the base SemossWeb URL public static final String ENDPOINT_REDIRECT_KEY = "ENDPOINT_REDIRECT_KEY"; - + public static final String MONOLITH_ROUTE = "MONOLITH_ROUTE"; public static final String MONOLITH_PREFIX = "MONOLITH_PREFIX"; - + private static final String LOGIN = "login"; + private static final String STACKTRACE = "StackTrace: "; private static final String NO_USER_HTML = "/noUserFail/"; - protected static List ignoreDueToFE = new Vector(); + protected static List ignoreDueToFE = new Vector<>(); static { // allow these for successful dropping of @@ -59,56 +66,60 @@ public class NoUserInSessionFilter implements Filter { ignoreDueToFE.add("auth/loginsAllowed"); ignoreDueToFE.add("auth/login"); ignoreDueToFE.add("auth/createUser"); - for(AuthProvider v : AuthProvider.values()) { - ignoreDueToFE.add("auth/userinfo/" + v.toString().toLowerCase()); - ignoreDueToFE.add("auth/login/" + v.toString().toLowerCase()); + for (AuthProvider v : AuthProvider.values()) { + ignoreDueToFE.add("auth/userinfo/" + v.toString().toLowerCase()); + ignoreDueToFE.add("auth/login/" + v.toString().toLowerCase()); } } @Override - public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { + public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) + throws IOException, ServletException { ServletContext context = arg0.getServletContext(); - if(AbstractSecurityUtils.securityEnabled()) { + if (AbstractSecurityUtils.securityEnabled()) { // this will be the full path of the request // like http://localhost:8080/Monolith_Dev/api/engine/runPixel + String fullUrl = ((HttpServletRequest) arg0).getRequestURL().toString(); String contextPath = ((HttpServletRequest) arg0).getContextPath(); // REALLY DISLIKE THIS CHECK!!! - if(!isIgnored(fullUrl)) { + if (!isIgnored(fullUrl)) { // due to FE being annoying // we need to push a response for this one end point // since security is embedded w/ normal semoss and not standalone HttpSession session = ((HttpServletRequest) arg0).getSession(false); User user = null; - if(session != null) { - //System.out.println("Session ID >> " + session.getId()); + if (session != null) { + // System.out.println("Session ID >> " + session.getId()); user = (User) session.getAttribute(Constants.SESSION_USER); } // if no user // need to make a check in terms of am I a part of trusted host scheme - // basically the RDF_map will have a list of IPs for trusted host who can make a call - // when that IP makes a call, we will transfer the session and give the user over + // basically the RDF_map will have a list of IPs for trusted host who can make a + // call + // when that IP makes a call, we will transfer the session and give the user + // over // RDF_MAP - // Trusted_token true // says this instance will work with trusted token + // Trusted_token true // says this instance will work with trusted token // Trusted_host - // Token_Prefix this is an optional piece - I am not going to implement right now - - - if(user == null || (!AbstractSecurityUtils.anonymousUsersEnabled() && user.getLogins().isEmpty()) ) { + // Token_Prefix this is an optional piece - I am not going to implement right + // now + + if (user == null || (!AbstractSecurityUtils.anonymousUsersEnabled() && user.getLogins().isEmpty())) { // do a condition here if the session id request parameter is available // eventually this will be that and the tableau - HttpServletRequest req = (HttpServletRequest) arg0; - - if(req.getParameter(DBLoader.getSessionIdKey()) != null) { + HttpServletRequest req = (HttpServletRequest) arg0; + + if (req.getParameter(DBLoader.getSessionIdKey()) != null) { String sessionId = req.getParameter(DBLoader.getSessionIdKey()); // create the cookie add it and sent it back Cookie k = new Cookie(DBLoader.getSessionIdKey(), sessionId); k.setPath(contextPath); - ((HttpServletResponse)arg1).addCookie(k); + ((HttpServletResponse) arg1).addCookie(k); // in case there are other JSESSIONID // cookies, reset the value to the correct sessionId Cookie[] cookies = req.getCookies(); @@ -116,66 +127,62 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 for (Cookie c : cookies) { if (c.getName().equals(DBLoader.getSessionIdKey())) { c.setValue(sessionId); - ((HttpServletResponse)arg1).addCookie(c); + ((HttpServletResponse) arg1).addCookie(c); } } } - Set routes = Collections.list(req.getParameterNames()) - .stream().filter(s -> s.startsWith("route")) - .collect(Collectors.toSet()); - if(routes != null && !routes.isEmpty()) { - for(String r : routes) { + Set routes = Collections.list(req.getParameterNames()).stream() + .filter(s -> s.startsWith("route")).collect(Collectors.toSet()); + if (routes != null && !routes.isEmpty()) { + for (String r : routes) { Cookie c = new Cookie(r, req.getParameter(r)); c.setPath(contextPath); - ((HttpServletResponse)arg1).addCookie(c); + ((HttpServletResponse) arg1).addCookie(c); } } - + // add the hash cookie String hash = req.getParameter("hash"); Cookie h = new Cookie("HASH", hash); h.setPath(contextPath); - ((HttpServletResponse)arg1).addCookie(h); + ((HttpServletResponse) arg1).addCookie(h); // and now redirect back to the URL // if get, we can do it String method = req.getMethod(); - if(method.equalsIgnoreCase("GET")) { + if (method.equalsIgnoreCase("GET")) { // modify the prefix if necessary Map envMap = System.getenv(); - if(envMap.containsKey(MONOLITH_PREFIX)) { + if (envMap.containsKey(MONOLITH_PREFIX)) { fullUrl = fullUrl.replace(contextPath, envMap.get(MONOLITH_PREFIX)); } - + ((HttpServletResponse) arg1).setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY); ((HttpServletResponse) arg1).sendRedirect(fullUrl + "?" + req.getQueryString()); - return; - } else if(method.equalsIgnoreCase("POST")) { + } else if (method.equalsIgnoreCase("POST")) { // modify the prefix if necessary Map envMap = System.getenv(); - if(envMap.containsKey(MONOLITH_PREFIX)) { + if (envMap.containsKey(MONOLITH_PREFIX)) { fullUrl = fullUrl.replace(contextPath, envMap.get(MONOLITH_PREFIX)); } - + ((HttpServletResponse) arg1).setStatus(HttpServletResponse.SC_TEMPORARY_REDIRECT); ((HttpServletResponse) arg1).setHeader("Location", fullUrl); - return; } else { - // don't know what i am redirecting + // don't know what i am redirecting // send back an error and have the client remake the request setInvalidEntryRedirect(context, arg0, arg1, LOGIN); } - + return; } // no jsession id as a param // just a normal redirect - else - { + else { setInvalidEntryRedirect(context, arg0, arg1, LOGIN); // invalidate the session if necessary - if(session != null) { + if (session != null) { session.invalidate(); } return; @@ -183,23 +190,24 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 } // is the user logging in, but was previously at a different page? - // this is because even if i set the redirect URL in the - // {@link UserResource#setMainPageRedirect(@Context HttpServletRequest request, @Context HttpServletResponse response)} + // this is because even if i set the redirect URL in the + // {@link UserResource#setMainPageRedirect(@Context HttpServletRequest request, + // @Context HttpServletResponse response)} // is sent to the pop-up for OAuth login String endpointRedirectUrl = (String) session.getAttribute(NoUserInSessionFilter.ENDPOINT_REDIRECT_KEY); - if(endpointRedirectUrl != null && !endpointRedirectUrl.isEmpty()) { + if (endpointRedirectUrl != null && !endpointRedirectUrl.isEmpty()) { ((HttpServletResponse) arg1).setHeader("redirect", endpointRedirectUrl); ((HttpServletResponse) arg1).sendError(302, "Need to redirect to " + endpointRedirectUrl); session.removeAttribute(NoUserInSessionFilter.ENDPOINT_REDIRECT_KEY); return; } - + // so we have a user // let us look at the cookies // are we redirecting based on the above // or it is the main session String hashId = null; - Cookie[] cookies = ((HttpServletRequest)arg0).getCookies(); + Cookie[] cookies = ((HttpServletRequest) arg0).getCookies(); if (cookies != null) { for (Cookie c : cookies) { if (c.getName().equals("HASH")) { @@ -210,9 +218,9 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 } // well, we are the shared session - if(hashId != null) { + if (hashId != null) { // is this the first time we are hooking up the shared session? - if(!user.isShareSession(session.getId())) { + if (!user.isShareSession(session.getId())) { // tricky tricky // if you have a hash id but not shared // you are trying to get in when you shouldn't @@ -223,12 +231,12 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 // use a wrapper otherwise // POST data consumed will be destroyed // when we get to the actual request method - MultiReadHttpServletRequest wrapper = new MultiReadHttpServletRequest(((HttpServletRequest)arg0)); + MultiReadHttpServletRequest wrapper = new MultiReadHttpServletRequest(((HttpServletRequest) arg0)); String insightId = wrapper.getParameter("i"); String secret = wrapper.getParameter("s"); // not enough input - if(insightId == null || secret == null) { + if (insightId == null || secret == null) { setInvalidEntryRedirect(context, arg0, arg1, LOGIN); return; } @@ -237,34 +245,35 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 InsightToken token = user.getInsight(insightId); try { MessageDigest md = MessageDigest.getInstance("MD5"); - String finalData = token.getSalt()+secret; - byte [] digest = md.digest(finalData.getBytes()); + String finalData = token.getSalt() + secret; + byte[] digest = md.digest(finalData.getBytes()); StringBuffer sb = new StringBuffer(); for (int i = 0; i < digest.length; i++) { sb.append(Integer.toString((digest[i] & 0xff) + 0x100, 16).substring(1)); } - if(hashId == null || !hashId.equals(sb+"")) { - // bad input + if (hashId == null || !hashId.equals(sb + "")) { + // bad input setInvalidEntryRedirect(context, arg0, arg1, LOGIN); return; - } + } - // this session has been ratified so remove the session and move the user forward + // this session has been ratified so remove the session and move the user + // forward user.removeShare(session.getId()); // remove the hash cookie since the user has validated this session for (Cookie c : cookies) { if (c.getName().equals("HASH")) { c.setMaxAge(0); c.setPath(contextPath); - ((HttpServletResponse)arg1).addCookie(c); + ((HttpServletResponse) arg1).addCookie(c); break; } } - + arg2.doFilter(wrapper, arg1); return; } catch (NoSuchAlgorithmException e) { - e.printStackTrace(); + logger.error(STACKTRACE, e); } } } @@ -275,6 +284,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 /** * Method to determine where to redirect the user + * * @param context * @param arg0 * @param arg1 @@ -286,12 +296,12 @@ private void setInvalidEntryRedirect(ServletContext context, ServletRequest arg0 String redirectUrl = ((HttpServletRequest) arg0).getHeader("referer"); // if no referrer // then a person hit the endpoint directly - if(redirectUrl == null) { + if (redirectUrl == null) { ((HttpServletRequest) arg0).getSession(true).setAttribute(ENDPOINT_REDIRECT_KEY, fullUrl); // this will be the deployment name of the app String loginRedirect = UserResource.getLoginRedirect(); ((HttpServletResponse) arg1).setStatus(302); - if(loginRedirect != null) { + if (loginRedirect != null) { ((HttpServletResponse) arg1).sendRedirect(loginRedirect); } else { String contextPath = context.getContextPath(); @@ -300,33 +310,32 @@ private void setInvalidEntryRedirect(ServletContext context, ServletRequest arg0 } } else { redirectUrl = redirectUrl + "#!/" + endpoint; - ((HttpServletResponse) arg1).setHeader("redirect", redirectUrl); - ((HttpServletResponse) arg1).sendError(302, "Need to redirect to " + redirectUrl); + String encodedRedirectUrl = Encode.forHtml(redirectUrl); + ((HttpServletResponse) arg1).setHeader("redirect", encodedRedirectUrl); + ((HttpServletResponse) arg1).sendError(302, "Need to redirect to " + encodedRedirectUrl); } } @Override public void destroy() { - // TODO Auto-generated method stub - + // destroy } @Override public void init(FilterConfig arg0) throws ServletException { - // TODO Auto-generated method stub - + // initialize } /** - * Due to how the FE security is set up - * Need to ignore some URLs :( - * I REALLY DISLIKE THIS!!! + * Due to how the FE security is set up Need to ignore some URLs :( I REALLY + * DISLIKE THIS!!! + * * @param fullUrl * @return */ protected static boolean isIgnored(String fullUrl) { - for(String ignore : ignoreDueToFE) { - if(fullUrl.endsWith(ignore)) { + for (String ignore : ignoreDueToFE) { + if (fullUrl.endsWith(ignore)) { return true; } } diff --git a/src/prerna/web/conf/PIVFilter.java b/src/prerna/web/conf/PIVFilter.java index 5fc03fb1b..91433a72e 100644 --- a/src/prerna/web/conf/PIVFilter.java +++ b/src/prerna/web/conf/PIVFilter.java @@ -31,7 +31,7 @@ public class PIVFilter implements Filter { - private static final Logger LOGGER = LogManager.getLogger(PIVFilter.class.getName()); + private static final Logger logger = LogManager.getLogger(PIVFilter.class.getName()); // filter init params private static final String AUTO_ADD = "autoAdd"; @@ -111,7 +111,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 } } // end rdn loop } catch (InvalidNameException e) { - LOGGER.error("ERROR WITH PARSING CAC INFORMATION!"); + logger.error("ERROR WITH PARSING CAC INFORMATION!"); e.printStackTrace(); } } @@ -120,7 +120,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 // and it has values filled in // we know we can populate the user if(token.getName() != null) { - LOGGER.info("Valid request coming from user " + token.getName()); + logger.info("Valid request coming from user " + token.getName()); user.setAccessToken(token); session.setAttribute(Constants.SESSION_USER, user); @@ -176,18 +176,18 @@ private void setInitParams(ServletRequest arg0) { String logInfoPath = this.filterConfig.getInitParameter(LOG_USER_INFO_PATH); String logInfoSep = this.filterConfig.getInitParameter(LOG_USER_INFO_SEP); if(logInfoPath == null) { - LOGGER.info("SYSTEM HAS REGISTERED TO PERFORM A USER FILE LOG BUT NOT FILE PATH HAS BEEN ENTERED!!!"); - LOGGER.info("SYSTEM HAS REGISTERED TO PERFORM A USER FILE LOG BUT NOT FILE PATH HAS BEEN ENTERED!!!"); - LOGGER.info("SYSTEM HAS REGISTERED TO PERFORM A USER FILE LOG BUT NOT FILE PATH HAS BEEN ENTERED!!!"); - LOGGER.info("SYSTEM HAS REGISTERED TO PERFORM A USER FILE LOG BUT NOT FILE PATH HAS BEEN ENTERED!!!"); + logger.info("SYSTEM HAS REGISTERED TO PERFORM A USER FILE LOG BUT NOT FILE PATH HAS BEEN ENTERED!!!"); + logger.info("SYSTEM HAS REGISTERED TO PERFORM A USER FILE LOG BUT NOT FILE PATH HAS BEEN ENTERED!!!"); + logger.info("SYSTEM HAS REGISTERED TO PERFORM A USER FILE LOG BUT NOT FILE PATH HAS BEEN ENTERED!!!"); + logger.info("SYSTEM HAS REGISTERED TO PERFORM A USER FILE LOG BUT NOT FILE PATH HAS BEEN ENTERED!!!"); } try { userLogger = UserFileLogUtil.getInstance(logInfoPath, logInfoSep); } catch(Exception e) { - LOGGER.info(e.getMessage()); - LOGGER.info(e.getMessage()); - LOGGER.info(e.getMessage()); - LOGGER.info(e.getMessage()); + logger.info(e.getMessage()); + logger.info(e.getMessage()); + logger.info(e.getMessage()); + logger.info(e.getMessage()); } } @@ -202,18 +202,18 @@ private void setInitParams(ServletRequest arg0) { if(countUsers) { String countDatabaseId = this.filterConfig.getInitParameter(COUNT_USER_ENTRY_DATABASE); if(countDatabaseId == null) { - LOGGER.info("SYSTEM HAS REGISTERED TO PERFORM A COUNT BUT NO DATABASE ID HAS BEEN ENTERED!!!"); - LOGGER.info("SYSTEM HAS REGISTERED TO PERFORM A COUNT BUT NO DATABASE ID HAS BEEN ENTERED!!!"); - LOGGER.info("SYSTEM HAS REGISTERED TO PERFORM A COUNT BUT NO DATABASE ID HAS BEEN ENTERED!!!"); - LOGGER.info("SYSTEM HAS REGISTERED TO PERFORM A COUNT BUT NO DATABASE ID HAS BEEN ENTERED!!!"); + logger.info("SYSTEM HAS REGISTERED TO PERFORM A COUNT BUT NO DATABASE ID HAS BEEN ENTERED!!!"); + logger.info("SYSTEM HAS REGISTERED TO PERFORM A COUNT BUT NO DATABASE ID HAS BEEN ENTERED!!!"); + logger.info("SYSTEM HAS REGISTERED TO PERFORM A COUNT BUT NO DATABASE ID HAS BEEN ENTERED!!!"); + logger.info("SYSTEM HAS REGISTERED TO PERFORM A COUNT BUT NO DATABASE ID HAS BEEN ENTERED!!!"); } try { tracker = CACTrackingUtil.getInstance(countDatabaseId); } catch(Exception e) { - LOGGER.info(e.getMessage()); - LOGGER.info(e.getMessage()); - LOGGER.info(e.getMessage()); - LOGGER.info(e.getMessage()); + logger.info(e.getMessage()); + logger.info(e.getMessage()); + logger.info(e.getMessage()); + logger.info(e.getMessage()); } } } diff --git a/src/prerna/web/conf/UserExistsFilter.java b/src/prerna/web/conf/UserExistsFilter.java index 9fdab9052..7674a37d0 100644 --- a/src/prerna/web/conf/UserExistsFilter.java +++ b/src/prerna/web/conf/UserExistsFilter.java @@ -11,6 +11,10 @@ import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; +import org.apache.log4j.LogManager; +import org.apache.log4j.Logger; +import org.owasp.encoder.Encode; + import prerna.auth.User; import prerna.auth.utils.AbstractSecurityUtils; import prerna.engine.api.IEngine; @@ -20,10 +24,14 @@ import prerna.util.Utility; public class UserExistsFilter extends NoUserInSessionFilter { + + private static final Logger logger = LogManager.getLogger(UserExistsFilter.class); + private static final String STACKTRACE = "StackTrace: "; @Override - public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { - if(AbstractSecurityUtils.securityEnabled()) { + public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) + throws IOException, ServletException { + if (AbstractSecurityUtils.securityEnabled()) { HttpSession session = ((HttpServletRequest) arg0).getSession(true); User user = (User) session.getAttribute(Constants.SESSION_USER); @@ -32,40 +40,42 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 String fullUrl = ((HttpServletRequest) arg0).getRequestURL().toString(); // REALLY DISLIKE THIS CHECK!!! - if(!isIgnored(fullUrl)) { + if (!isIgnored(fullUrl)) { // how you got here without a user, i am unsure given the other filters // but just in case // i will redirect you to login - if(user == null || user.getLogins().isEmpty()) { + if (user == null || user.getLogins().isEmpty()) { ((HttpServletResponse) arg1).setStatus(302); String redirectUrl = ((HttpServletRequest) arg0).getHeader("referer"); redirectUrl = redirectUrl + "#!/login"; - ((HttpServletResponse) arg1).setHeader("redirect", redirectUrl); - ((HttpServletResponse) arg1).sendError(302, "Need to redirect to " + redirectUrl); + String encodedRedirectUrl = Encode.forHtml(redirectUrl); + ((HttpServletResponse) arg1).setHeader("redirect", encodedRedirectUrl); + ((HttpServletResponse) arg1).sendError(302, "Need to redirect to " + encodedRedirectUrl); return; } else { // okay, need to make sure the user is a valid one IEngine engine = Utility.getEngine(Constants.SECURITY_DB); - String q = "SELECT * FROM USER WHERE ID='" + user.getAccessToken(user.getLogins().get(0)).getId() + "'"; + String q = "SELECT * FROM USER WHERE ID='" + user.getAccessToken(user.getLogins().get(0)).getId() + + "'"; IRawSelectWrapper wrapper = null; try { wrapper = WrapperManager.getInstance().getRawWrapper(engine, q); boolean hasUser = wrapper.hasNext(); // this user is not registered // just take them to the login page again - if(!hasUser) { + if (!hasUser) { ((HttpServletResponse) arg1).setStatus(302); String redirectUrl = ((HttpServletRequest) arg0).getHeader("referer"); redirectUrl = redirectUrl + "#!/login"; - ((HttpServletResponse) arg1).setHeader("redirect", redirectUrl); - ((HttpServletResponse) arg1).sendError(302, "Need to redirect to " + redirectUrl); - return; + String encodedRedirectUrl = Encode.forHtml(redirectUrl); + ((HttpServletResponse) arg1).setHeader("redirect", encodedRedirectUrl); + ((HttpServletResponse) arg1).sendError(302, "Need to redirect to " + encodedRedirectUrl); } } catch (Exception e) { - e.printStackTrace(); + logger.error(STACKTRACE, e); } finally { - if(wrapper != null) { + if (wrapper != null) { wrapper.cleanUp(); } } @@ -78,13 +88,12 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 @Override public void destroy() { - // TODO Auto-generated method stub + // destroy } @Override public void init(FilterConfig arg0) throws ServletException { - // TODO Auto-generated method stub - + // initialize } } diff --git a/src/prerna/web/conf/util/UserFileLogUtil.java b/src/prerna/web/conf/util/UserFileLogUtil.java index a537d2107..da48d4e15 100644 --- a/src/prerna/web/conf/util/UserFileLogUtil.java +++ b/src/prerna/web/conf/util/UserFileLogUtil.java @@ -8,9 +8,12 @@ import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; -public class UserFileLogUtil { +import org.apache.log4j.LogManager; +import org.apache.log4j.Logger; - private static Map singletonStore = new HashMap(); +public class UserFileLogUtil { + + private static Map singletonStore = new HashMap<>(); /* * Creating a class to write to a file the users who are signing in @@ -24,7 +27,7 @@ public class UserFileLogUtil { public UserFileLogUtil(String filePath, String sep) throws IOException { this.filePath = filePath; this.sep = sep; - this.queue = new ArrayBlockingQueue(50); + this.queue = new ArrayBlockingQueue<>(50); this.fileLogger = new FileAppender(this.filePath, this.sep, this.queue); new Thread(this.fileLogger).start(); @@ -34,12 +37,10 @@ public static UserFileLogUtil getInstance(String filePath, String sep) throws IO if(filePath == null || filePath.trim().isEmpty()) { throw new IOException("Must pass in a valid filePath"); } - if(!singletonStore.containsKey(filePath)) { - synchronized (UserFileLogUtil.class) { - if(!singletonStore.containsKey(filePath)) { - UserFileLogUtil trackingUtil = new UserFileLogUtil(filePath, sep); - singletonStore.put(filePath, trackingUtil); - } + synchronized (UserFileLogUtil.class) { + if(!singletonStore.containsKey(filePath)) { + UserFileLogUtil trackingUtil = new UserFileLogUtil(filePath, sep); + singletonStore.put(filePath, trackingUtil); } } return singletonStore.get(filePath); @@ -52,7 +53,8 @@ public void addToQueue(String[] row) { } class FileAppender implements Runnable { - + private static final Logger logger = LogManager.getLogger(FileAppender.class); + private static final String STACKTRACE = "StackTrace: "; private File f = null; private FileWriter fw = null; private String filePath = null; @@ -95,19 +97,20 @@ public void run() { fw.write(builder.toString()); fw.flush(); } catch (IOException e) { - e.printStackTrace(); + logger.error(STACKTRACE, e); } } - } catch (InterruptedException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); + logger.error(STACKTRACE, ie); + } catch (IOException ioe) { + logger.error(STACKTRACE, ioe); } finally { if(fw != null) { try { fw.close(); - } catch (IOException e) { - e.printStackTrace(); + } catch (IOException ioe) { + logger.error(STACKTRACE, ioe); } } fw = null; diff --git a/src/prerna/web/services/util/InstanceStreamer.java b/src/prerna/web/services/util/InstanceStreamer.java index e2d6e932c..5e6a77c6f 100644 --- a/src/prerna/web/services/util/InstanceStreamer.java +++ b/src/prerna/web/services/util/InstanceStreamer.java @@ -21,13 +21,16 @@ import java.util.Comparator; import java.util.LinkedHashSet; import java.util.List; +import java.util.Locale; import java.util.Set; import org.apache.commons.lang3.RandomStringUtils; - -import prerna.util.Utility; +import org.apache.log4j.LogManager; +import org.apache.log4j.Logger; public class InstanceStreamer { + + private static final Logger logger = LogManager.getLogger(InstanceStreamer.class); private ArrayList list; private int size; @@ -35,8 +38,8 @@ public class InstanceStreamer { private String ID; public InstanceStreamer(List tempList) { - Set set = new LinkedHashSet(tempList); - list = new ArrayList(set); + Set set = new LinkedHashSet<>(tempList); + list = new ArrayList<>(set); sortList(list); // sort into order: O(N log N) size = list.size(); } @@ -50,98 +53,114 @@ public String getID() { } /** - * Get unique items start (inclusive) through end (exclusive). - * This is accomplished by creating a TreeSet item from the ArrayList. + * Get unique items start (inclusive) through end (exclusive). This is + * accomplished by creating a TreeSet item from the ArrayList. * - * @param start index of start unique row (inclusive) - * @param end index of end unique row (exclusive) - * @return Object[] of unique rows start (inclusive) through end (exclusive) + * @param start index of start unique row (inclusive) + * @param end index of end unique row (exclusive) + * @return Object[] of unique rows start (inclusive) through end (exclusive) */ public ArrayList getUnique(int start, int end) { - if (start > size) { return new ArrayList(); } - if (start < 0) { start = 0; }; - if (end > size) { end = size; }; - return new ArrayList(list.subList(start, end)); + if (start > size) { + return new ArrayList<>(); + } + if (start < 0) { + start = 0; + } + ; + if (end > size) { + end = size; + } + ; + return new ArrayList<>(list.subList(start, end)); } /** * Return number of unique items in list. - * @return int of items in list + * + * @return int of items in list */ public int getSize() { return list.size(); } - + public ArrayList getList() { return this.list; } /** - * Implementation of binary search. Returns the first index that - * starts with the search term: O(lg N) + * Implementation of binary search. Returns the first index that starts with the + * search term: O(lg N) * - * @param searchTerm key to search for - * @param lo low bound of index - * @param hi high bound of index - * @return first index that starts with the search term + * @param searchTerm key to search for + * @param lo low bound of index + * @param hi high bound of index + * @return first index that starts with the search term */ private int findFirstTerm(String searchTerm, int lo, int hi) { - if (hi < lo) { + if (hi < lo) { return -1; // not found - } + } int mid = lo + ((hi - lo) / 2); // use .getInstanceName() to strip URI - String middleTerm = list.get(mid).toString().toLowerCase(); + String middleTerm = list.get(mid).toString().toLowerCase(Locale.ENGLISH); if (middleTerm.indexOf(searchTerm) == 0) { - return mid; - } - else if (middleTerm.compareTo(searchTerm) > 0) { - return findFirstTerm(searchTerm, lo, mid-1); - } - else { - return findFirstTerm(searchTerm, mid+1, hi); + return mid; + } else if (middleTerm.compareTo(searchTerm) > 0) { + return findFirstTerm(searchTerm, lo, mid - 1); + } else { + return findFirstTerm(searchTerm, mid + 1, hi); } } /** - * Returns ArrayList of all values that start with term searchTerm. - * Searching is case-insensitive; this is accomplished by using String.toLowerCase(). - * O(lg N) time. - * @param searchTermObj key to search for - * @return list of values + * Returns ArrayList of all values that start with term searchTerm. Searching is + * case-insensitive; this is accomplished by using String.toLowerCase(). O(lg N) + * time. + * + * @param searchTermObj key to search for + * @return list of values */ public ArrayList search(Object searchTermObj) { - String searchTerm = searchTermObj.toString().toLowerCase(); + String searchTerm = searchTermObj.toString().toLowerCase(Locale.ENGLISH); - ArrayList results = new ArrayList(); + ArrayList results = new ArrayList<>(); // get first index of term - int firstIndex = findFirstTerm(searchTerm, 0, size-1); - + int firstIndex = findFirstTerm(searchTerm, 0, size - 1); + // look for searchTerm with spaces replaced with underscores if (firstIndex == -1) { - firstIndex = findFirstTerm(searchTerm.replaceAll(" ", "_"), 0, size-1); + firstIndex = findFirstTerm(searchTerm.replace(" ", "_"), 0, size - 1); } - // if result found: move left and right from firstIndex to find more + // if result found: move left and right from firstIndex to find more if (firstIndex != -1) { results.add(list.get(firstIndex).toString()); // add first value - for (int i = firstIndex-1; i >= 0; i--) { // add all relevant values to the left - String value = list.get(i).toString().toLowerCase(); - if (value.contains(searchTerm) || value.contains(searchTerm.replaceAll(" ", "_"))) { // check for searchTerm with and without underscores + for (int i = firstIndex - 1; i >= 0; i--) { // add all relevant values to the left + String value = list.get(i).toString().toLowerCase(Locale.ENGLISH); + if (value.contains(searchTerm) || value.contains(searchTerm.replace(" ", "_"))) { // check for + // searchTerm with + // and without + // underscores results.add(list.get(i).toString()); + } else { + break; } - else break; } - for (int i = firstIndex+1; i < size; i++) { // add all relevant values to the right - String value = list.get(i).toString().toLowerCase(); - if (value.contains(searchTerm) || value.contains(searchTerm.replaceAll(" ", "_"))) { // check for searchTerm with and without underscores + for (int i = firstIndex + 1; i < size; i++) { // add all relevant values to the right + String value = list.get(i).toString().toLowerCase(Locale.ENGLISH); + if (value.contains(searchTerm) || value.contains(searchTerm.replace(" ", "_"))) { // check for + // searchTerm with + // and without + // underscores results.add(list.get(i).toString()); + } else { + break; } - else break; } } @@ -150,19 +169,20 @@ public ArrayList search(Object searchTermObj) { } /** - * Returns ArrayList of all values that contain term searchTerm. - * Searching is case-insensitive; this is accomplished by using String.toLowerCase(). - * O(N) time. - * @param searchTermObj key to search for - * @return list of values + * Returns ArrayList of all values that contain term searchTerm. Searching is + * case-insensitive; this is accomplished by using String.toLowerCase(). O(N) + * time. + * + * @param searchTermObj key to search for + * @return list of values */ public ArrayList regexSearch(Object searchTermObj) { - String searchTerm = searchTermObj.toString().toLowerCase(); + String searchTerm = searchTermObj.toString().toLowerCase(Locale.ENGLISH); - ArrayList results = new ArrayList(); + ArrayList results = new ArrayList<>(); for (int i = 0; i < list.size(); i++) { - String value = list.get(i).toString().toLowerCase(); + String value = list.get(i).toString().toLowerCase(Locale.ENGLISH); if (value.contains(searchTerm)) { results.add(list.get(i).toString()); } @@ -174,120 +194,220 @@ public ArrayList regexSearch(Object searchTermObj) { /** * Custom comparator for list (since ArrayList of Objects and not Strings) * - * @param list arrayList of Objects + * @param list arrayList of Objects */ private void sortList(ArrayList list) { Collections.sort(list, new Comparator() { public int compare(Object o1, Object o2) { - return o1.toString().toLowerCase().compareTo(o2.toString().toLowerCase()); + return o1.toString().toLowerCase(Locale.ENGLISH).compareTo(o2.toString().toLowerCase(Locale.ENGLISH)); } }); } /** - * Testing section. + * Testing section. * - * 1) Search for words starting with and containing 'b-a' in a list of 1000 random words - * 2) Identify all numbers starting with and containing '5' in this list - * 3) Create 1M random strings with length 10, time how long it takes to create tree, and search if any of them start with "tomato". + * 1) Search for words starting with and containing 'b-a' in a list of 1000 + * random words 2) Identify all numbers starting with and containing '5' in this + * list 3) Create 1M random strings with length 10, time how long it takes to + * create tree, and search if any of them start with "tomato". */ public static void main(String[] args) { - Object[] strArray = {"course","dearth","overseas","podcast","portrait","advertising","contract","clean","endurance","fresh","guitar","wear","jackpot","tool","post","space","brunette","big","cheek","internet","high","sleep","have","interior","musing","excite","rise","earth","strength","media","alcohol","time","emotion","pure","paper","topless","tribune","relief","minute","group","retail","ringtone","value","note","kid","conflict","cute","win","flirt","forest","prepare","buy","design","office","compassion","question","look","place","golf","dictionary","happen","booth","recipe","strong","makeup","tower","call","category","carnival","stairway","punishment","exotic","begin","aspiration","climb","quality","manual","blur","rare","discovery","misc","society","petal","drugs","frame","world","student","silver","game","dead","flag","article","delicious","taxes","event","scenic","aim","dress","offer","past","drop","company","circus","priceless","degree","print","tiny","reward","show","independence","wonder","red","hear","visit","positive","temptation","run","destiny","compare","curiosity","girl","exercise","fragance","TV","babe","parent","score","tell","present","finish","marketing","reason","stop","lonely","desire","hair","original","cosmetic","make","music","audio","formation","bill","competition","drink","stone","shine","saint","gun","muscle","instant","trouble","respect","difficult","bike","talk","jump","nail","mini","chief","brainstorm","apprentice","toe","security","figure","tropic","one","well","adult","life","directory","accountant","acrobat","consider","together","funny","frozen","panties","section","town","stress","race","install","communication","gold","terrorism","age","ruin","organ","mask","greeting","discuss","affection","java","DIY","observe","romance","research","depend","consumer","eternity","engine","diversity","journey","commute","need","democracy","thousand","lady","robe","mother","electronic","clear","software","white","must","star","complex","mile","huge","lost","spice","build","fruit","home","splash","warm","skirt","clown","pool","surprise","puppy","face","buddy","destination","result","noise","wireless","hero","object","wrong","fly","skill","stationary","product","tourism","sound","mentor","egg","mob","baby","dragon","sugar","shop","sophisticated","background","work","boy","CD","flash","aviation","support","archive","black","restaurant","blood","nightlife","architecture","lust","athlete","piece","laugh","religion","resort","phone","doctor","outdoors","copy","spiritual","dark","soldier","relationship","afraid","sail","record","story","tribute","gadget","hour","device","position","root","seduce","commerce","meet","men","label","open","expand","select","exterior","care","road","quote","halloween","play","attention","spray","thin","follow","born","fireworks","practice","problem","tip","song","answer","point","idea","fantasy","courage","garden","holiday","smell","public","fun","enter","DVD","heroic","general","movie","hardware","naked","cellphone","agree","medecine","diet","size","trip","concept","busy","emergency","name","auction","detail","herb","newlywed","cruise","forever","real","decide","future","arrest","sign","loan","logo","doll","senior","thick","tattoo","water","process","sport","shirt","store","neon","smooth","passion","party","long","branch","concentration","loud","suburb","carry","exact","sword","now","reach","artist","clothe","ray","subway","adorable","groom","learn","bone","edge","ice","young","thanksgiving","bad","out","defeat","land","stuff","ceremony","police","roulette","because","heavy","camera","update","guess","pop","nostalgia","please","MP3","spend","deep","homosexuality","take","fight","download","system","basket","poem","luxury","dog","good","motor","master","blow","sell","element","case","blog","beast","create","indoor","cuisine","portable","erotic","repeat","free","climate","planet","extravaganza","lake","save","silence","blackjack","chat","stability","air","tradition","orchestra","palm","skin","curve","dry","suggest","rental","modern","happy","anger","share","pier","smoke","find","finger","film","female","say","minority","gamble","safe","flat","number","card","nation","pet","calm","beverage","oil","island","thong","symbol","money","beach","PC","local","politic","exit","war","end","attitude","despair","rainbow","today","order","magic","special","bazaar","quick","motivation","major","leisure","sad","palace","picture","court","comfort","seat","metal","entertainment","soccer","pub","trade","ocean","sea","style","dawn","business","moon","patriot","rule","base","laundry","husband","generation","summer","bottom","joke","cold","television","empty","platform","adolescent","street","listen","bell","cyber","park","hand","speech","reserve","cry","area","spot","drive","wine","sin","never","email","culture","radio","community","stick","cinema","favor","exam","environment","first","iron","imagine","attractive","correct","body","quiet","disco","speed","simple","change","sharp","intense","customer","bride","lead","finance","humor","furniture","heat","million","sensation","precision","car","human","journal","ready","plant","dear","love","spam","queen","motion","fitness","melody","vote","aggression","flower","nature","miracle","path","elegance","poker","choice","wife","optimism","online","prove","join","hi-tech","gender","dream","job","nude","solitude","leave","church","bright","energy","private","woman","lounge","sex","shape","kill","mystery","color","food","clock","center","always","temperature","calorie","push","off","basic","maturity","honor","short","bonding","desktop","addict","health","jewelry","innovation","rally","art","mate","mirror","laptop","VOIP","mortgage","traffic","raise","burn","explode","great","rain","activity","crime","theater","barbary","campus","nobody","demonstration","fish","random","pink","nothing","bank","stay","risk","decoration","sofa","shadow","search","costume","smile","lesbian","final","experience","thing","broadband","scream","main","museum","heart","government","weather","cartoon","mix","blonde","ask","paradise","cloud","dollar","enforcement","lyric","feet","grocery","toy","gorgeous","light","digital","relaxation","habitat","bar","notice","earring","bikini","chocolate","friend","military","dance","fix","close","luck","sky","glass","know","supreme","old","mouth","hope","lingerie","barefoot","hot","send","wild","capitalism","behind","feeling","hug","example","solidarity","actor","legal","day","desert","gossip","solver","liberation","bread","hobby","wish","majestic","father","go","comic","cat","message","cycle","goddess","joy","annual","chick","poor","casino","identity","hurricane","sensual","lips","gay","protest","eat","people","apartment","stage","bizarre","confidence","butt","taxi","cemetery","machine","rose","coast","appear","year","slim","technology","phenomena","lawyer","fashion","like","claim","oxygen","rescue","football","ecology","innocence","fast","gas","fact","cream","entrance","sun","enemy","tear","school","expect","straight","season","surf","rich","target","male","might","glamour","apple","memory","education","band","departure","pride","will","trap","murmur","survival","justice","brother","leg","fear","college","sister","chest","bed","gift","match","allow","border","credit","library","pay","interest","mind","yes","board","move","deal","full","AIDS","grow","screensaver","review","science","phrase","supermarket","force","declaration","wallpaper","graphic","fat","pollution","scale","cowboy","illusion","famous","mood","range","president","slow","peace","boat","website","noon","both","do","cook","break","perfume","soda","crowd","philosophy","step","century","marriage","international","press","weight","christmas","hiphop","jazz","think","forward","daughter","club","anime","celebration","possible","breast","hit","start","action","bath","develop","fame","advice","news","best","power","reply","allergy","character","accessory","eye","magazine","true","depression","cash","spectacular","birthday","animal","sympathy","beautiful","relative","landscape","spider","video","steam","effect","hotel","mountain","history","house","gateway","different","tan","subject","glad","success","silhouette","complete","translation","grass","treasury","help","pupil","next","industry","model","cost","arrive","captive","ticket","single","map","pretty","satisfaction","teach","dirt","king","funky","coffee","computer","remember","believe","tribal","fair","wait","family","baseball","mobile","track","against","connect","come","continent","angel","direction","obituary","chance","arrow","conversation","wide","expression","about","limit","view","jeans","shoe","activist","flame","couple","cool","concert","royalty","guide","danger","handmade","book","alone","army","provide","beat","turn","language","lottery","kiss","photo","mail","travel","city","graduate"}; - Object[] intArray = {87,52,85,97,51,68,18,31,57,11,36,76,96,91,96,12,68,23,57,44,16,84,2,35,32,15,31,64,2,84,31,83,49,45,50,86,16,54,13,22,29,36,6,35,28,83,63,71,77,62,11,95,92,98,46,88,94,77,9,24,49,86,14,18,15,47,86,60,68,73,22,13,3,69,91,57,80,66,81,87,61,70,74,70,73,6,12,56,59,29,81,71,95,76,96,90,32,24,31,93}; + Object[] strArray = { "course", "dearth", "overseas", "podcast", "portrait", "advertising", "contract", "clean", + "endurance", "fresh", "guitar", "wear", "jackpot", "tool", "post", "space", "brunette", "big", "cheek", + "internet", "high", "sleep", "have", "interior", "musing", "excite", "rise", "earth", "strength", + "media", "alcohol", "time", "emotion", "pure", "paper", "topless", "tribune", "relief", "minute", + "group", "retail", "ringtone", "value", "note", "kid", "conflict", "cute", "win", "flirt", "forest", + "prepare", "buy", "design", "office", "compassion", "question", "look", "place", "golf", "dictionary", + "happen", "booth", "recipe", "strong", "makeup", "tower", "call", "category", "carnival", "stairway", + "punishment", "exotic", "begin", "aspiration", "climb", "quality", "manual", "blur", "rare", + "discovery", "misc", "society", "petal", "drugs", "frame", "world", "student", "silver", "game", "dead", + "flag", "article", "delicious", "taxes", "event", "scenic", "aim", "dress", "offer", "past", "drop", + "company", "circus", "priceless", "degree", "print", "tiny", "reward", "show", "independence", "wonder", + "red", "hear", "visit", "positive", "temptation", "run", "destiny", "compare", "curiosity", "girl", + "exercise", "fragance", "TV", "babe", "parent", "score", "tell", "present", "finish", "marketing", + "reason", "stop", "lonely", "desire", "hair", "original", "cosmetic", "make", "music", "audio", + "formation", "bill", "competition", "drink", "stone", "shine", "saint", "gun", "muscle", "instant", + "trouble", "respect", "difficult", "bike", "talk", "jump", "nail", "mini", "chief", "brainstorm", + "apprentice", "toe", "security", "figure", "tropic", "one", "well", "adult", "life", "directory", + "accountant", "acrobat", "consider", "together", "funny", "frozen", "panties", "section", "town", + "stress", "race", "install", "communication", "gold", "terrorism", "age", "ruin", "organ", "mask", + "greeting", "discuss", "affection", "java", "DIY", "observe", "romance", "research", "depend", + "consumer", "eternity", "engine", "diversity", "journey", "commute", "need", "democracy", "thousand", + "lady", "robe", "mother", "electronic", "clear", "software", "white", "must", "star", "complex", "mile", + "huge", "lost", "spice", "build", "fruit", "home", "splash", "warm", "skirt", "clown", "pool", + "surprise", "puppy", "face", "buddy", "destination", "result", "noise", "wireless", "hero", "object", + "wrong", "fly", "skill", "stationary", "product", "tourism", "sound", "mentor", "egg", "mob", "baby", + "dragon", "sugar", "shop", "sophisticated", "background", "work", "boy", "CD", "flash", "aviation", + "support", "archive", "black", "restaurant", "blood", "nightlife", "architecture", "lust", "athlete", + "piece", "laugh", "religion", "resort", "phone", "doctor", "outdoors", "copy", "spiritual", "dark", + "soldier", "relationship", "afraid", "sail", "record", "story", "tribute", "gadget", "hour", "device", + "position", "root", "seduce", "commerce", "meet", "men", "label", "open", "expand", "select", + "exterior", "care", "road", "quote", "halloween", "play", "attention", "spray", "thin", "follow", + "born", "fireworks", "practice", "problem", "tip", "song", "answer", "point", "idea", "fantasy", + "courage", "garden", "holiday", "smell", "public", "fun", "enter", "DVD", "heroic", "general", "movie", + "hardware", "naked", "cellphone", "agree", "medecine", "diet", "size", "trip", "concept", "busy", + "emergency", "name", "auction", "detail", "herb", "newlywed", "cruise", "forever", "real", "decide", + "future", "arrest", "sign", "loan", "logo", "doll", "senior", "thick", "tattoo", "water", "process", + "sport", "shirt", "store", "neon", "smooth", "passion", "party", "long", "branch", "concentration", + "loud", "suburb", "carry", "exact", "sword", "now", "reach", "artist", "clothe", "ray", "subway", + "adorable", "groom", "learn", "bone", "edge", "ice", "young", "thanksgiving", "bad", "out", "defeat", + "land", "stuff", "ceremony", "police", "roulette", "because", "heavy", "camera", "update", "guess", + "pop", "nostalgia", "please", "MP3", "spend", "deep", "homosexuality", "take", "fight", "download", + "system", "basket", "poem", "luxury", "dog", "good", "motor", "master", "blow", "sell", "element", + "case", "blog", "beast", "create", "indoor", "cuisine", "portable", "erotic", "repeat", "free", + "climate", "planet", "extravaganza", "lake", "save", "silence", "blackjack", "chat", "stability", "air", + "tradition", "orchestra", "palm", "skin", "curve", "dry", "suggest", "rental", "modern", "happy", + "anger", "share", "pier", "smoke", "find", "finger", "film", "female", "say", "minority", "gamble", + "safe", "flat", "number", "card", "nation", "pet", "calm", "beverage", "oil", "island", "thong", + "symbol", "money", "beach", "PC", "local", "politic", "exit", "war", "end", "attitude", "despair", + "rainbow", "today", "order", "magic", "special", "bazaar", "quick", "motivation", "major", "leisure", + "sad", "palace", "picture", "court", "comfort", "seat", "metal", "entertainment", "soccer", "pub", + "trade", "ocean", "sea", "style", "dawn", "business", "moon", "patriot", "rule", "base", "laundry", + "husband", "generation", "summer", "bottom", "joke", "cold", "television", "empty", "platform", + "adolescent", "street", "listen", "bell", "cyber", "park", "hand", "speech", "reserve", "cry", "area", + "spot", "drive", "wine", "sin", "never", "email", "culture", "radio", "community", "stick", "cinema", + "favor", "exam", "environment", "first", "iron", "imagine", "attractive", "correct", "body", "quiet", + "disco", "speed", "simple", "change", "sharp", "intense", "customer", "bride", "lead", "finance", + "humor", "furniture", "heat", "million", "sensation", "precision", "car", "human", "journal", "ready", + "plant", "dear", "love", "spam", "queen", "motion", "fitness", "melody", "vote", "aggression", "flower", + "nature", "miracle", "path", "elegance", "poker", "choice", "wife", "optimism", "online", "prove", + "join", "hi-tech", "gender", "dream", "job", "nude", "solitude", "leave", "church", "bright", "energy", + "private", "woman", "lounge", "sex", "shape", "kill", "mystery", "color", "food", "clock", "center", + "always", "temperature", "calorie", "push", "off", "basic", "maturity", "honor", "short", "bonding", + "desktop", "addict", "health", "jewelry", "innovation", "rally", "art", "mate", "mirror", "laptop", + "VOIP", "mortgage", "traffic", "raise", "burn", "explode", "great", "rain", "activity", "crime", + "theater", "barbary", "campus", "nobody", "demonstration", "fish", "random", "pink", "nothing", "bank", + "stay", "risk", "decoration", "sofa", "shadow", "search", "costume", "smile", "lesbian", "final", + "experience", "thing", "broadband", "scream", "main", "museum", "heart", "government", "weather", + "cartoon", "mix", "blonde", "ask", "paradise", "cloud", "dollar", "enforcement", "lyric", "feet", + "grocery", "toy", "gorgeous", "light", "digital", "relaxation", "habitat", "bar", "notice", "earring", + "bikini", "chocolate", "friend", "military", "dance", "fix", "close", "luck", "sky", "glass", "know", + "supreme", "old", "mouth", "hope", "lingerie", "barefoot", "hot", "send", "wild", "capitalism", + "behind", "feeling", "hug", "example", "solidarity", "actor", "legal", "day", "desert", "gossip", + "solver", "liberation", "bread", "hobby", "wish", "majestic", "father", "go", "comic", "cat", "message", + "cycle", "goddess", "joy", "annual", "chick", "poor", "casino", "identity", "hurricane", "sensual", + "lips", "gay", "protest", "eat", "people", "apartment", "stage", "bizarre", "confidence", "butt", + "taxi", "cemetery", "machine", "rose", "coast", "appear", "year", "slim", "technology", "phenomena", + "lawyer", "fashion", "like", "claim", "oxygen", "rescue", "football", "ecology", "innocence", "fast", + "gas", "fact", "cream", "entrance", "sun", "enemy", "tear", "school", "expect", "straight", "season", + "surf", "rich", "target", "male", "might", "glamour", "apple", "memory", "education", "band", + "departure", "pride", "will", "trap", "murmur", "survival", "justice", "brother", "leg", "fear", + "college", "sister", "chest", "bed", "gift", "match", "allow", "border", "credit", "library", "pay", + "interest", "mind", "yes", "board", "move", "deal", "full", "AIDS", "grow", "screensaver", "review", + "science", "phrase", "supermarket", "force", "declaration", "wallpaper", "graphic", "fat", "pollution", + "scale", "cowboy", "illusion", "famous", "mood", "range", "president", "slow", "peace", "boat", + "website", "noon", "both", "do", "cook", "break", "perfume", "soda", "crowd", "philosophy", "step", + "century", "marriage", "international", "press", "weight", "christmas", "hiphop", "jazz", "think", + "forward", "daughter", "club", "anime", "celebration", "possible", "breast", "hit", "start", "action", + "bath", "develop", "fame", "advice", "news", "best", "power", "reply", "allergy", "character", + "accessory", "eye", "magazine", "true", "depression", "cash", "spectacular", "birthday", "animal", + "sympathy", "beautiful", "relative", "landscape", "spider", "video", "steam", "effect", "hotel", + "mountain", "history", "house", "gateway", "different", "tan", "subject", "glad", "success", + "silhouette", "complete", "translation", "grass", "treasury", "help", "pupil", "next", "industry", + "model", "cost", "arrive", "captive", "ticket", "single", "map", "pretty", "satisfaction", "teach", + "dirt", "king", "funky", "coffee", "computer", "remember", "believe", "tribal", "fair", "wait", + "family", "baseball", "mobile", "track", "against", "connect", "come", "continent", "angel", + "direction", "obituary", "chance", "arrow", "conversation", "wide", "expression", "about", "limit", + "view", "jeans", "shoe", "activist", "flame", "couple", "cool", "concert", "royalty", "guide", "danger", + "handmade", "book", "alone", "army", "provide", "beat", "turn", "language", "lottery", "kiss", "photo", + "mail", "travel", "city", "graduate" }; + Object[] intArray = { 87, 52, 85, 97, 51, 68, 18, 31, 57, 11, 36, 76, 96, 91, 96, 12, 68, 23, 57, 44, 16, 84, 2, + 35, 32, 15, 31, 64, 2, 84, 31, 83, 49, 45, 50, 86, 16, 54, 13, 22, 29, 36, 6, 35, 28, 83, 63, 71, 77, + 62, 11, 95, 92, 98, 46, 88, 94, 77, 9, 24, 49, 86, 14, 18, 15, 47, 86, 60, 68, 73, 22, 13, 3, 69, 91, + 57, 80, 66, 81, 87, 61, 70, 74, 70, 73, 6, 12, 56, 59, 29, 81, 71, 95, 76, 96, 90, 32, 24, 31, 93 }; // try with strings - ArrayList arrayList = new ArrayList(Arrays.asList(strArray)); + ArrayList arrayList = new ArrayList<>(Arrays.asList(strArray)); InstanceStreamer stringTest = new InstanceStreamer(arrayList); - System.out.println("Searching for all strings that start with 'ba':"); + logger.debug("Searching for all strings that start with 'ba':"); Iterable searchResults = stringTest.search("ba"); - for (Object o: searchResults) { - System.out.println(o.toString()); + for (Object o : searchResults) { + logger.debug(o.toString()); } - System.out.println("Searching for all strings that contain 'ba':"); + logger.debug("Searching for all strings that contain 'ba':"); searchResults = stringTest.regexSearch("ba"); - for (Object o: searchResults) { - System.out.println(o.toString()); + for (Object o : searchResults) { + logger.debug(o.toString()); } // try with ints ArrayList intList = new ArrayList(Arrays.asList(intArray)); stringTest = new InstanceStreamer(intList); - System.out.println("Searching for all numbers that start with 5:"); + logger.debug("Searching for all numbers that start with 5:"); searchResults = stringTest.search("5"); - for (Object o: searchResults) { - System.out.println(o.toString()); + for (Object o : searchResults) { + logger.debug(o.toString()); } - System.out.println("Searching for all numbers that contain 5:"); + logger.debug("Searching for all numbers that contain 5:"); searchResults = stringTest.regexSearch("5"); - for (Object o: searchResults) { - System.out.println(o.toString()); + for (Object o : searchResults) { + logger.debug(o.toString()); } - // create 1M Strings of length 10 - ArrayList bigList = new ArrayList(); - System.out.println("Generating random strings:"); + // create 1M Strings of length 10 + ArrayList bigList = new ArrayList<>(); + logger.debug("Generating random strings:"); int sampleSize = 1000000; for (int i = 0; i < sampleSize; i++) { bigList.add(RandomStringUtils.randomAlphabetic(10)); - if (i % (sampleSize/100) == 0) {System.out.print(i/(sampleSize/100)+"% ");} + if (i % (sampleSize / 100) == 0) { + logger.debug(i / (sampleSize / 100) + "% "); + } } // load into tree and time it - System.out.println(); - System.out.print("Loading into Tree:"); + logger.debug("Loading into Tree:"); long start = System.currentTimeMillis(); stringTest = new InstanceStreamer(bigList); long t = System.currentTimeMillis() - start; - System.out.println("took " + t + "ms."); - System.out.println(); + logger.debug("took " + t + "ms."); // search for words with t, to, tom, toma, tomat, tomato start = System.currentTimeMillis(); searchResults = stringTest.search("t"); t = System.currentTimeMillis() - start; - System.out.println("1 char: " + t + "ms."); + logger.debug("1 char: " + t + "ms."); assertTrue("Timing, char", t < 150); start = System.currentTimeMillis(); searchResults = stringTest.search("to"); t = System.currentTimeMillis() - start; assertTrue("Timing, 2char", t < 10); - System.out.println("2 char: " + t + "ms."); + logger.debug("2 char: " + t + "ms."); start = System.currentTimeMillis(); searchResults = stringTest.search("tom"); t = System.currentTimeMillis() - start; assertTrue("Timing, 3char", t < 10); - System.out.println("3 char: " + t + "ms."); + logger.debug("3 char: " + t + "ms."); start = System.currentTimeMillis(); searchResults = stringTest.search("toma"); t = System.currentTimeMillis() - start; - System.out.println("4 char: " + t + "ms."); + logger.debug("4 char: " + t + "ms."); assertTrue("Timing, 4char", t < 10); - for (Object o: searchResults) { - System.out.println(o.toString()); + for (Object o : searchResults) { + logger.debug(o.toString()); } start = System.currentTimeMillis(); searchResults = stringTest.search("tomat"); t = System.currentTimeMillis() - start; - System.out.println("5 char: " + t + "ms."); + logger.debug("5 char: " + t + "ms."); assertTrue("Timing, 5char", t < 10); - for (Object o: searchResults) { - System.out.println(o.toString()); + for (Object o : searchResults) { + logger.debug(o.toString()); } start = System.currentTimeMillis(); searchResults = stringTest.search("tomato"); t = System.currentTimeMillis() - start; - System.out.println("6 char: " + t + "ms."); + logger.debug("6 char: " + t + "ms."); assertTrue("Timing, 6char", t < 10); - for (Object o: searchResults) { - System.out.println(o.toString()); + for (Object o : searchResults) { + logger.debug(o.toString()); } - - System.out.println("Testing complete."); - + logger.debug("Testing complete."); } -} \ No newline at end of file +} From 09a7d89aeb9af49ce0f09aeac53b15a5851f7e8e Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 28 Apr 2020 17:02:16 +0000 Subject: [PATCH 0568/1906] UPDATE ::: Pushing fortify fixes git-svn-id: svn://107.170.10.188:8080/Monolith/dev@38444 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 8955476594eaa28228e23ebc00e7450e1a075e3c --- .../semoss/web/services/local/NameServer.java | 4 +- .../web/services/local/SessionResource.java | 1 - .../web/services/local/UserResource.java | 39 +++++++++---------- src/prerna/web/conf/DBLoader.java | 2 +- 4 files changed, 22 insertions(+), 24 deletions(-) diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index 9960908c8..a5b0946e9 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -118,7 +118,7 @@ @Path("/engine") public class NameServer { - + private static final Logger logger = LogManager.getLogger(NameServer.class); private static final String ERROR_MESSAGE = "errorMessage"; @@ -854,7 +854,7 @@ public String getJobOutput(@QueryParam("jobId") String jobId, @Context HttpServl public void killJob(@QueryParam("jobId") String jobId, @Context HttpServletRequest request) { // AsyncResponse myResponse = // (AsyncResponse)ResponseHashSingleton.getResponseforJobId(jobId); - SemossThread thread = (SemossThread) ResponseHashSingleton.getThread(jobId); + SemossThread thread = ResponseHashSingleton.getThread(jobId); thread.setComplete(true); ResponseHashSingleton.removeThread(jobId); diff --git a/src/prerna/semoss/web/services/local/SessionResource.java b/src/prerna/semoss/web/services/local/SessionResource.java index 3e638ac03..721969c9f 100644 --- a/src/prerna/semoss/web/services/local/SessionResource.java +++ b/src/prerna/semoss/web/services/local/SessionResource.java @@ -1,7 +1,6 @@ package prerna.semoss.web.services.local; import java.io.IOException; -import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.HashSet; diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index 0aa3df825..3104bebf7 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -117,8 +117,8 @@ @Path("/auth") public class UserResource { - - private static final Logger logger = LogManager.getLogger(UserResource.class.getName()); + + private static final Logger logger = LogManager.getLogger(UserResource.class); private static final String STACKTRACE = "StackTrace: "; private static Properties socialData = null; @@ -173,7 +173,7 @@ private static void setLoginsAllowed() { boolean dropboxLogin = Boolean.parseBoolean(socialData.getProperty("dropbox_login")); boolean cacLogin = Boolean.parseBoolean(socialData.getProperty("cac_login")); boolean registration = Boolean.parseBoolean(socialData.getProperty("native_registration")); - UserResource.loginsAllowed = new HashMap(); + UserResource.loginsAllowed = new HashMap<>(); UserResource.loginsAllowed.put("native", nativeLogin); UserResource.loginsAllowed.put("google", googleLogin); UserResource.loginsAllowed.put("github", githubLogin); @@ -611,15 +611,16 @@ public Response userinfoGithub(@Context HttpServletRequest request) { String output = AbstractHttpHelper.makeGetCall(url, accessString, null, true); - AccessToken accessToken2 = (AccessToken)BeanFiller.fillFromJson(output, jsonPattern, beanProps, new AccessToken()); + AccessToken accessToken2 = (AccessToken) BeanFiller.fillFromJson(output, jsonPattern, beanProps, + new AccessToken()); try { ret.put("name", accessToken2.getProfile()); } catch (Exception e) { - e.printStackTrace(); + logger.error(STACKTRACE, e); } return WebUtility.getResponse(ret, 200); } - + ////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////// @@ -656,7 +657,7 @@ public Response loginSF(@Context HttpServletRequest request, @Context HttpServle String clientSecret = socialData.getProperty(prefix + "secret_key"); String redirectUri = socialData.getProperty(prefix + "redirect_uri"); - logger.debug(">> " + request.getQueryString()); + logger.debug(">> " + Utility.cleanLogString(request.getQueryString())); Hashtable params = new Hashtable(); params.put("client_id", clientId); @@ -732,7 +733,7 @@ public Response loginSurveyMonkey(@Context HttpServletRequest request, @Context String clientSecret = socialData.getProperty(prefix + "secret_key"); String redirectUri = socialData.getProperty(prefix + "redirect_uri"); - logger.debug(">> " + request.getQueryString()); + logger.debug(">> " + Utility.cleanLogString(request.getQueryString())); Hashtable params = new Hashtable(); params.put("client_id", clientId); @@ -809,7 +810,7 @@ public Response loginGithub(@Context HttpServletRequest request, @Context HttpSe String clientSecret = socialData.getProperty(prefix + "secret_key"); String redirectUri = socialData.getProperty(prefix + "redirect_uri"); - logger.debug(">> " + request.getQueryString()); + logger.debug(">> " + Utility.cleanLogString(request.getQueryString())); Hashtable params = new Hashtable(); params.put("client_id", clientId); @@ -898,7 +899,7 @@ public Response loginMS(@Context HttpServletRequest request, @Context HttpServle String tenant = socialData.getProperty(prefix + "tenant"); String scope = socialData.getProperty(prefix + "scope"); - logger.debug(">> " + request.getQueryString()); + logger.debug(">> " + Utility.cleanLogString(request.getQueryString())); Hashtable params = new Hashtable(); params.put("client_id", clientId); @@ -981,7 +982,7 @@ public Response loginDropBox(@Context HttpServletRequest request, @Context HttpS String clientSecret = socialData.getProperty(prefix + "secret_key"); String redirectUri = socialData.getProperty(prefix + "redirect_uri"); - logger.debug(">> " + request.getQueryString()); + logger.debug(">> " + Utility.cleanLogString(request.getQueryString())); Hashtable params = new Hashtable(); params.put("client_id", clientId); @@ -1059,7 +1060,7 @@ public Response loginGoogle(@Context HttpServletRequest request, @Context HttpSe String clientSecret = socialData.getProperty(prefix + "secret_key"); String redirectUri = socialData.getProperty(prefix + "redirect_uri"); - logger.debug(">> " + request.getQueryString()); + logger.debug(">> " + Utility.cleanLogString(request.getQueryString())); // I need to decode the return code from google since the default param's are // encoded on the post of getAccessToken String codeDecode = URLDecoder.decode(outputs[0]); @@ -1166,7 +1167,6 @@ private void performGoogleOps(HttpServletRequest request, Map ret) { try { ret.put("files", BeanFiller.getJson(fileList)); } catch (Exception e) { - // TODO Auto-generated catch block logger.error(STACKTRACE, e); } @@ -1208,7 +1208,7 @@ public Response loginProducthunt(@Context HttpServletRequest request, @Context H String clientSecret = socialData.getProperty(prefix + "secret_key"); String redirectUri = socialData.getProperty(prefix + "redirect_uri"); - logger.debug(">> " + request.getQueryString()); + logger.debug(">> " + Utility.cleanLogString(request.getQueryString())); Hashtable params = new Hashtable(); @@ -1286,7 +1286,7 @@ public Response loginIn(@Context HttpServletRequest request, @Context HttpServle String clientSecret = socialData.getProperty(prefix + "secret_key"); String redirectUri = socialData.getProperty(prefix + "redirect_uri"); - logger.debug(">> " + request.getQueryString()); + logger.debug(">> " + Utility.cleanLogString(request.getQueryString())); Hashtable params = new Hashtable(); params.put("client_id", clientId); @@ -1357,7 +1357,7 @@ public Response loginTwitter(@Context HttpServletRequest request, @Context HttpS User userObj = (User) request.getSession().getAttribute(Constants.SESSION_USER); String queryString = request.getQueryString(); if (queryString != null && queryString.contains("code=")) { - if (userObj == null || ((User) userObj).getAccessToken(AuthProvider.GITHUB) == null) { + if (userObj == null || userObj.getAccessToken(AuthProvider.GITHUB) == null) { String[] outputs = AbstractHttpHelper.getCodes(queryString); @@ -1367,7 +1367,7 @@ public Response loginTwitter(@Context HttpServletRequest request, @Context HttpS String clientSecret = socialData.getProperty(prefix + "secret_key"); String redirectUri = socialData.getProperty(prefix + "redirect_uri"); - logger.debug(">> " + request.getQueryString()); + logger.debug(">> " + Utility.cleanLogString(request.getQueryString())); Hashtable params = new Hashtable(); params.put("client_id", clientId); @@ -1395,7 +1395,7 @@ public Response loginTwitter(@Context HttpServletRequest request, @Context HttpS // grab the user again userObj = (User) request.getSession().getAttribute(Constants.SESSION_USER); - if (userObj == null || ((User) userObj).getAccessToken(AuthProvider.GITHUB) == null) { + if (userObj == null || userObj.getAccessToken(AuthProvider.GITHUB) == null) { // not authenticated response.setStatus(302); response.sendRedirect(getTwitterRedirect(request)); @@ -1523,7 +1523,6 @@ public Response logoutNative(@Context HttpServletRequest request) throws IOExcep if (request.getSession(false) != null) { HttpSession session = request.getSession(false); User print = (User) session.getAttribute(Constants.SESSION_USER); - // LOGGER.info("Logging out with: " + print); print.dropAccessToken(AuthProvider.NATIVE.name().toUpperCase()); request.getSession().setAttribute(Constants.SESSION_USER, print); } else { @@ -1793,7 +1792,7 @@ public StreamingOutput manCookie(@Context HttpServletRequest request, @Context H InsightToken token = new InsightToken(); Hashtable outputHash = new Hashtable(); try { - MessageDigest md = MessageDigest.getInstance("MD5"); + MessageDigest md = MessageDigest.getInstance("SHA-256"); // create the insight token and add to the user // the user has secret and salt token.setSecret(secret); diff --git a/src/prerna/web/conf/DBLoader.java b/src/prerna/web/conf/DBLoader.java index 72a013bb7..14792842e 100644 --- a/src/prerna/web/conf/DBLoader.java +++ b/src/prerna/web/conf/DBLoader.java @@ -129,7 +129,7 @@ public void contextInitialized(ServletContextEvent arg0) { DBLoader.SESSION_ID_KEY = cookieConfig.getName(); } } - + logger.info("Initializing application context..." + Utility.cleanLogString(contextPath)); // Set default file separator system variable From 2129b2809ac40442690128e6c7b719ab74dc5f7f Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Sat, 2 May 2020 14:38:58 +0000 Subject: [PATCH 0569/1906] UPDATE ::: Shifting CACFilter back to running with cac id instead of email. Adding in logic to try to revert previous emails to the id when the user enters the application. git-svn-id: svn://107.170.10.188:8080/Monolith/dev@38505 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: ef5c4f1489c32732dc9a95de79a1aa146c49049e --- src/prerna/web/conf/CACFilter.java | 204 +++++++++++++++++++---------- 1 file changed, 132 insertions(+), 72 deletions(-) diff --git a/src/prerna/web/conf/CACFilter.java b/src/prerna/web/conf/CACFilter.java index d58de4737..b90012484 100644 --- a/src/prerna/web/conf/CACFilter.java +++ b/src/prerna/web/conf/CACFilter.java @@ -3,6 +3,7 @@ import java.io.IOException; import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; +import java.sql.SQLException; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; @@ -29,7 +30,13 @@ import prerna.auth.AuthProvider; import prerna.auth.User; import prerna.auth.utils.SecurityUpdateUtils; +import prerna.ds.util.RdbmsQueryBuilder; +import prerna.engine.api.IRawSelectWrapper; +import prerna.engine.impl.rdbms.RDBMSNativeEngine; +import prerna.forms.FormBuilder; +import prerna.rdf.engine.wrappers.WrapperManager; import prerna.util.Constants; +import prerna.util.Utility; import prerna.web.conf.util.CACTrackingUtil; import prerna.web.conf.util.UserFileLogUtil; @@ -44,19 +51,19 @@ public class CACFilter implements Filter { private static final String LOG_USER_INFO = "logUserInfo"; private static final String LOG_USER_INFO_PATH = "logUserInfoPath"; private static final String LOG_USER_INFO_SEP = "logUserInfoSep"; - + // realization of init params private static Boolean autoAdd = null; private CACTrackingUtil tracker = null; private UserFileLogUtil userLogger = null; private FilterConfig filterConfig; - + // TODO >>>timb: WORKSPACE - call logic to pull workspace here, or make into a reactor @Override public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { setInitParams(arg0); - + X509Certificate[] certs = (X509Certificate[]) arg0.getAttribute("javax.servlet.request.X509Certificate"); HttpSession session = ((HttpServletRequest)arg0).getSession(true); @@ -69,19 +76,19 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 user = new User(); token = new AccessToken(); token.setProvider(AuthProvider.CAC); - + // values we are trying to grab String cacId = null; String name = null; String email = null; - + // loop through all the certs CERT_LOOP : for(int i = 0; i < certs.length; i++) { X509Certificate cert = certs[i]; String fullName = cert.getSubjectX500Principal().getName(); System.out.println("REQUEST COMING FROM " + fullName); - + LdapName ldapDN; try { ldapDN = new LdapName(fullName); @@ -91,7 +98,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 // try next rdn continue; } - + // get the full value String value = rdn.getValue().toString(); @@ -122,7 +129,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 // try next rdn continue; } - + // just going to validate the cac has length 10 cacId = split[split.length-1]; if(cacId.length() < 10) { @@ -130,7 +137,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 // try next rdn continue; } - + // if we got to here, we have a valid cac! name = Stream.of(split).limit(split.length-1).collect(Collectors.joining(" ")); // we also need to get the email since that is what we will store @@ -153,23 +160,18 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 e.printStackTrace(); } - // lets make sure we have all the stuff - if(email != null & name != null) { - // we have everything! - // this is the only time we populate the token - // and then exit the cert loop - + if(email != null) { // lower case the email + // and try to update it in all the different locations email = email.toLowerCase(); - - token.setId(email); - token.setEmail(email); - token.setName(name); - - // if we get here, we have a valid cac -// updateCacUsersStorage(cacId, email); - break CERT_LOOP; + updateCacUsersStorage(email, cacId); } + token.setId(email); + token.setEmail(email); + token.setName(name); + + // if we get here, we have a valid cac + break CERT_LOOP; } // end rdn loop } catch (InvalidNameException e) { LOGGER.error("ERROR WITH PARSING CAC INFORMATION!"); @@ -189,13 +191,13 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 if(CACFilter.autoAdd) { SecurityUpdateUtils.addOAuthUser(token); } - + // new user has entered! // do we need to count? if(tracker != null && !token.getName().equals("TOPAZ")) { tracker.addToQueue(LocalDate.now()); } - + // are we logging their information? if(userLogger != null && !token.getName().equals("TOPAZ")) { userLogger.addToQueue(new String[] {cacId, email, name, LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))}); @@ -212,12 +214,12 @@ public void destroy() { // TODO Auto-generated method stub } - + @Override public void init(FilterConfig arg0) throws ServletException { this.filterConfig = arg0; } - + private void setInitParams(ServletRequest arg0) { if(CACFilter.autoAdd == null) { String autoAddStr = this.filterConfig.getInitParameter(AUTO_ADD); @@ -259,7 +261,7 @@ private void setInitParams(ServletRequest arg0) { } else { countUsers = false; } - + if(countUsers) { String countDatabaseId = this.filterConfig.getInitParameter(COUNT_USER_ENTRY_DATABASE); if(countDatabaseId == null) { @@ -280,48 +282,106 @@ private void setInitParams(ServletRequest arg0) { } } -// @Deprecated -// /** -// * We only have this because we need to update the way we store these users -// */ -// private void updateCacUsersStorage(String previousId, String email) { -// String cleanEmail = RdbmsQueryBuilder.escapeForSQLStatement(email); -// RDBMSNativeEngine securityDb = (RDBMSNativeEngine) Utility.getEngine(Constants.SECURITY_DB); -// -// // let us not try to run this multiple times... -// String requireUpdateQuery = "SELECT * FROM USER WHERE ID='" + previousId +"'"; -// IRawSelectWrapper wrapper = WrapperManager.getInstance().getRawWrapper(securityDb, requireUpdateQuery); -// try { -// // if we have next -// // that means we need to update -// // from id to email -// if(wrapper.hasNext()) { -// // need to update all the places the user id is used -// String updateQuery = "UPDATE USER SET ID='" + cleanEmail +"', EMAIL='" + cleanEmail + "' WHERE ID='" + previousId + "'"; -// try { -// securityDb.insertData(updateQuery); -// } catch (SQLException e) { -// e.printStackTrace(); -// } -// -// // need to update all the places the user id is used -// updateQuery = "UPDATE ENGINEPERMISSION SET USERID='" + cleanEmail +"' WHERE USERID='" + previousId + "'"; -// try { -// securityDb.insertData(updateQuery); -// } catch (SQLException e) { -// e.printStackTrace(); -// } -// -// // need to update all the places the user id is used -// updateQuery = "UPDATE USERINSIGHTPERMISSION SET USERID='" + cleanEmail +"' WHERE USERID='" + previousId + "'"; -// try { -// securityDb.insertData(updateQuery); -// } catch (SQLException e) { -// e.printStackTrace(); -// } -// } -// } finally { -// wrapper.cleanUp(); -// } -// } + /** + * We only have this because we need to update the way we store these users + */ + @Deprecated + private void updateCacUsersStorage(String previousId, String newId) { + String cleanOldId = RdbmsQueryBuilder.escapeForSQLStatement(previousId); + String cleanNewId = RdbmsQueryBuilder.escapeForSQLStatement(newId); + { + // security update block + RDBMSNativeEngine securityDb = (RDBMSNativeEngine) Utility.getEngine(Constants.SECURITY_DB); + + // let us not try to run this multiple times... + String requireUpdateQuery = "SELECT * FROM USER WHERE ID='" + cleanOldId +"'"; + IRawSelectWrapper wrapper = null; + try { + wrapper = WrapperManager.getInstance().getRawWrapper(securityDb, requireUpdateQuery); + // if we have next + // that means we need to update + // from id to email + if(wrapper.hasNext()) { + // need to update all the places the user id is used + String updateQuery = "UPDATE USER SET ID='" + cleanNewId +"' WHERE ID='" + cleanOldId + "'"; + try { + securityDb.insertData(updateQuery); + } catch (SQLException e) { + e.printStackTrace(); + } + + // need to update all the places the user id is used + updateQuery = "UPDATE ENGINEPERMISSION SET USERID='" + cleanNewId +"' WHERE USERID='" + cleanOldId + "'"; + try { + securityDb.insertData(updateQuery); + } catch (SQLException e) { + e.printStackTrace(); + } + + // need to update all the places the user id is used + updateQuery = "UPDATE USERINSIGHTPERMISSION SET USERID='" + cleanNewId +"' WHERE USERID='" + cleanOldId + "'"; + try { + securityDb.insertData(updateQuery); + } catch (SQLException e) { + e.printStackTrace(); + } + } + } catch (Exception e1) { + e1.printStackTrace(); + } finally { + if(wrapper != null) { + wrapper.cleanUp(); + } + } + } + + { + RDBMSNativeEngine formEngine = (RDBMSNativeEngine) Utility.getEngine(FormBuilder.FORM_BUILDER_ENGINE_NAME); + if(formEngine != null) { + // let us not try to run this multiple times... + String requireUpdateQuery = "SELECT * FROM FORMS_USER_ACCESS WHERE USER_ID='" + cleanOldId +"'"; + IRawSelectWrapper wrapper = null; + try { + wrapper = WrapperManager.getInstance().getRawWrapper(formEngine, requireUpdateQuery); + // if we have next + // that means we need to update + // from id to email + if(wrapper.hasNext()) { + + // form builder update block + String emailColumnExists = "SELECT COLUMN_NAME, TYPE_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'FORMS_USER_ACCESS' AND COLUMN_NAME='EMAIL'"; + IRawSelectWrapper requireFormUpdateWrapper = null; + try { + requireFormUpdateWrapper = WrapperManager.getInstance().getRawWrapper(formEngine, emailColumnExists); + if(!requireFormUpdateWrapper.hasNext()) { + formEngine.insertData("ALTER TABLE FORMS_USER_ACCESS ADD COLUMN IF NOT EXISTS EMAIL VARCHAR(200);"); + formEngine.insertData("UPDATE FORMS_USER_ACCESS SET EMAIL = USER_ID;"); + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + if(requireFormUpdateWrapper != null) { + requireFormUpdateWrapper.cleanUp(); + } + } + + // now that the schema is in place, lets update the values + String updateQuery = "UPDATE FORMS_USER_ACCESS SET USER_ID='" + cleanNewId +"' WHERE USER_ID='" + cleanOldId + "'"; + try { + formEngine.insertData(updateQuery); + } catch (SQLException e) { + e.printStackTrace(); + } + + } + } catch (Exception e1) { + e1.printStackTrace(); + } finally { + if(wrapper != null) { + wrapper.cleanUp(); + } + } + } + } + } } From 47de6c6508c0e42e403dfbb386ddd1ab488febf0 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Sat, 2 May 2020 15:08:17 +0000 Subject: [PATCH 0570/1906] BUGFIX ::: Switching the id properly to cacid instead of email on the user itself git-svn-id: svn://107.170.10.188:8080/Monolith/dev@38506 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 144e67a9d1fc335fb7bfa600c71396604f96685e --- src/prerna/web/conf/CACFilter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prerna/web/conf/CACFilter.java b/src/prerna/web/conf/CACFilter.java index b90012484..b2f747ad9 100644 --- a/src/prerna/web/conf/CACFilter.java +++ b/src/prerna/web/conf/CACFilter.java @@ -166,7 +166,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 email = email.toLowerCase(); updateCacUsersStorage(email, cacId); } - token.setId(email); + token.setId(cacId); token.setEmail(email); token.setName(name); From df56d816b2519130382a4e880392b556c0b10a4d Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 5 May 2020 17:08:21 +0000 Subject: [PATCH 0571/1906] UPDATE ::: Resolving double-checked locking git-svn-id: svn://107.170.10.188:8080/Monolith/dev@38543 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: c82f9e65ac36380f3901bbbbdc54577d74882545 --- .../config/ServerConfigurationResource.java | 160 ++++++++++-------- 1 file changed, 86 insertions(+), 74 deletions(-) diff --git a/src/prerna/semoss/web/services/config/ServerConfigurationResource.java b/src/prerna/semoss/web/services/config/ServerConfigurationResource.java index b67f1e0da..1d5d9d6e5 100644 --- a/src/prerna/semoss/web/services/config/ServerConfigurationResource.java +++ b/src/prerna/semoss/web/services/config/ServerConfigurationResource.java @@ -31,7 +31,7 @@ @Path("/config") public class ServerConfigurationResource { - private static Map config = null; + private static volatile Map config = null; /** * Generate the configuration options for this instance Only need to make this @@ -49,85 +49,97 @@ private static Map getConfig(@Context HttpServletRequest request } catch (IllegalAccessException e) { // ignore } + + if(config != null) { + return getConfiguration(session, user); + } + + // make thread safe + synchronized (ServerConfigurationResource.class) { + if (config == null) { + loadConfig(session); + } + } - if (config == null) { - // make thread safe - synchronized (ServerConfigurationResource.class) { - if (config == null) { - config = new HashMap<>(); - // session timeout - config.put("timeout", (double) session.getMaxInactiveInterval() / 60); - - // r enabled - boolean useR = true; - String useRStr = DIHelper.getInstance().getProperty(Constants.USE_R); - if (useRStr != null) { - useR = Boolean.parseBoolean(useRStr); - } - config.put("r", useR); - - // python enabled - config.put("python", PyUtils.pyEnabled()); - - // security enabled - config.put("security", AbstractSecurityUtils.securityEnabled()); - config.put("anonymousUsers", AbstractSecurityUtils.anonymousUsersEnabled()); - config.put("anonymousUserUploadData", AbstractSecurityUtils.anonymousUserUploadData()); - // admin set public enabled - boolean adminSetPublic = false; - String adminSetPublicStr = (String) DIHelper.getInstance().getLocalProp(Constants.ADMIN_SET_PUBLIC); - if (adminSetPublicStr != null) { - adminSetPublic = Boolean.parseBoolean(adminSetPublicStr); - } - config.put("adminSetPublic", adminSetPublic); - - // return a boolean if we want to use a dedicated logout page - // instead of redirecting to the login page - config.put("useLogoutPage", DBLoader.useLogoutPage()); - - // max file transfer size - String fileTransferMax = DIHelper.getInstance().getProperty(Constants.FILE_TRANSFER_LIMIT); - if (fileTransferMax != null) { - try { - config.put("file-limit", Integer.parseInt(fileTransferMax)); - } catch (Exception e) { - // ignore - } - } + return getConfiguration(session, user); + } + + private static void loadConfig(HttpSession session) { + Map loadConfig = new HashMap<>(); + // session timeout + loadConfig.put("timeout", (double) session.getMaxInactiveInterval() / 60); + + // r enabled + boolean useR = true; + String useRStr = DIHelper.getInstance().getProperty(Constants.USE_R); + if (useRStr != null) { + useR = Boolean.parseBoolean(useRStr); + } + loadConfig.put("r", useR); + + // python enabled + loadConfig.put("python", PyUtils.pyEnabled()); + + // security enabled + loadConfig.put("security", AbstractSecurityUtils.securityEnabled()); + loadConfig.put("anonymousUsers", AbstractSecurityUtils.anonymousUsersEnabled()); + loadConfig.put("anonymousUserUploadData", AbstractSecurityUtils.anonymousUserUploadData()); + // admin set public enabled + boolean adminSetPublic = false; + String adminSetPublicStr = (String) DIHelper.getInstance().getLocalProp(Constants.ADMIN_SET_PUBLIC); + if (adminSetPublicStr != null) { + adminSetPublic = Boolean.parseBoolean(adminSetPublicStr); + } + loadConfig.put("adminSetPublic", adminSetPublic); + + // return a boolean if we want to use a dedicated logout page + // instead of redirecting to the login page + loadConfig.put("useLogoutPage", DBLoader.useLogoutPage()); + + // max file transfer size + String fileTransferMax = DIHelper.getInstance().getProperty(Constants.FILE_TRANSFER_LIMIT); + if (fileTransferMax != null) { + try { + loadConfig.put("file-limit", Integer.parseInt(fileTransferMax)); + } catch (Exception e) { + // ignore + } + } - // version of the application - try { - Map versionMap = VersionReactor.getVersionMap(); - config.put("version", versionMap); - } catch (Exception e) { - // ignore - } + // version of the application + try { + Map versionMap = VersionReactor.getVersionMap(); + loadConfig.put("version", versionMap); + } catch (Exception e) { + // ignore + } - // send the default frame type - String defaultFrameType = DIHelper.getInstance().getProperty(Constants.DEFAULT_FRAME_TYPE); - if (defaultFrameType == null) { - defaultFrameType = "GRID"; - } - config.put("defaultFrameType", defaultFrameType); + // send the default frame type + String defaultFrameType = DIHelper.getInstance().getProperty(Constants.DEFAULT_FRAME_TYPE); + if (defaultFrameType == null) { + defaultFrameType = "GRID"; + } + loadConfig.put("defaultFrameType", defaultFrameType); - String defaultScriptingLanguage = DIHelper.getInstance() - .getProperty(Constants.DEFAULT_SCRIPTING_LANGUAGE); - if (defaultScriptingLanguage == null) { - defaultScriptingLanguage = "R"; - } - config.put("defaultScriptingLanguage", defaultScriptingLanguage); + String defaultScriptingLanguage = DIHelper.getInstance() + .getProperty(Constants.DEFAULT_SCRIPTING_LANGUAGE); + if (defaultScriptingLanguage == null) { + defaultScriptingLanguage = "R"; + } + loadConfig.put("defaultScriptingLanguage", defaultScriptingLanguage); - // local mode - boolean localMode = false; - String localModeStr = DIHelper.getInstance().getProperty(Constants.LOCAL_DEPLOYMENT); - if (localModeStr != null) { - localMode = Boolean.parseBoolean(localModeStr); - } - config.put("localDeployment", localMode); - } - } + // local mode + boolean localMode = false; + String localModeStr = DIHelper.getInstance().getProperty(Constants.LOCAL_DEPLOYMENT); + if (localModeStr != null) { + localMode = Boolean.parseBoolean(localModeStr); } + loadConfig.put("localDeployment", localMode); + + ServerConfigurationResource.config = loadConfig; + } + private static Map getConfiguration(HttpSession session, User user) { // do not keep this session // if no user and it is new if (session.isNew() && user == null) { @@ -145,7 +157,7 @@ private static Map getConfig(@Context HttpServletRequest request myConfiguration.put("theme", AdminThemeUtils.getActiveAdminTheme()); return myConfiguration; } - + @GET @Path("/") @Produces("application/json") From 8e2d0fc00825391720271287fcd4640ae5470dd2 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 6 May 2020 21:23:39 +0000 Subject: [PATCH 0572/1906] UPDATE ::: Resolving double lock on run pixel for python loading git-svn-id: svn://107.170.10.188:8080/Monolith/dev@38586 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 3f3de8bc2b08a5e11b2126da2ffcf12fdc4f7698 --- .../semoss/web/services/local/NameServer.java | 364 +++++++++--------- 1 file changed, 182 insertions(+), 182 deletions(-) diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index a5b0946e9..ac5b71074 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -363,11 +363,7 @@ public Response runPixelSync(@Context HttpServletRequest request) { HttpSession session = null; String sessionId = null; User user = null; - - PyTranslator pyt = null; Insight insight = null; - PyExecutorThread jepThread = null; - String port = null; boolean securityEnabled = AbstractSecurityUtils.securityEnabled(); // If security is enabled try to get an existing session. @@ -389,60 +385,7 @@ public Response runPixelSync(@Context HttpServletRequest request) { user = ((User) session.getAttribute(Constants.SESSION_USER)); sessionId = session.getId(); } - // need to see if the user is enabling python here.. I will assume it is here - if (session.getAttribute(Constants.PYTHON) != null) { - pyt = (PyTranslator) session.getAttribute(Constants.PYTHON); - port = (String) session.getAttribute("PORT"); - } - - if (PyUtils.pyEnabled() && pyt == null) { - // i do not want to make more than 1 py thread per session - // and this method is called many times - synchronized (sessionId) { - boolean useFilePy = DIHelper.getInstance().getProperty("USE_PY_FILE") != null - && DIHelper.getInstance().getProperty("USE_PY_FILE").equalsIgnoreCase("true"); - boolean useTCP = DIHelper.getInstance().getProperty("USE_TCP_PY") != null - && DIHelper.getInstance().getProperty("USE_TCP_PY").equalsIgnoreCase("true"); - useTCP = useFilePy; // forcing it to be same as TCP - - if (!useFilePy) { - if (session.getAttribute(Constants.PYTHON) != null) { - pyt = (PyTranslator) session.getAttribute(Constants.PYTHON); - } - if (jepThread == null) { - jepThread = PyUtils.getInstance().getJep(); - pyt = new PyTranslator(); - pyt.setPy(jepThread); - } - } - // check to see if the py translator needs to be set ? - else if (useFilePy && session.getAttribute("USER_TUPLE") == null) { - if (useTCP) { - port = DIHelper.getInstance().getProperty("FORCE_PORT"); // this means someone has started it - // for debug - if (port == null) { - port = Utility.findOpenPort(); - session.setAttribute("USER_TUPLE", PyUtils.getInstance().startPyServe(user, - DIHelper.getInstance().getProperty(Constants.INSIGHT_CACHE_DIR), port)); - NettyClient nc = new NettyClient(); - nc.connect("127.0.0.1", Integer.parseInt(port), false); - Thread t = new Thread(nc); - t.start(); - user.setPyServe(nc); - pyt = new TCPPyTranslator(); - ((TCPPyTranslator) pyt).nc = nc; - } - session.setAttribute("PORT", port); - } else { - session.setAttribute("USER_TUPLE", PyUtils.getInstance().getTempTupleSpace(user, - DIHelper.getInstance().getProperty(Constants.INSIGHT_CACHE_DIR))); - pyt = new FilePyTranslator(); - } - } - session.setAttribute(Constants.PYTHON, pyt); - } - } - + String jobId = ""; String insightId = request.getParameter("insightId"); String expression = request.getParameter("expression"); @@ -467,54 +410,50 @@ else if (useFilePy && session.getAttribute("USER_TUPLE") == null) { errorMap.put(ERROR_MESSAGE, "Could not find the insight id"); return WebUtility.getResponse(errorMap, 400); } - // make sure we have the correct session trying to get this id - // #soMuchSecurity - // Set sessionStore = - // InsightStore.getInstance().getInsightIDsForSession(sessionId); - // if(sessionStore == null || !sessionStore.contains(insightId)) { - // Map errorMap = new HashMap(); - // errorMap.put(ERROR_MESSAGE, "Trying to access insight id from incorrect - // session"); - // return WebUtility.getResponse(errorMap, 400); - // } } - // synchronized(insight) { // set the user insight.setUser(user); - // if(jepThread != null) - // insight.setPy(jepThread); - insight.setPyTranslator(pyt); - - if (insight.getTupleSpace() == null && session.getAttribute("USER_TUPLE") != null) { - // try to see if the insight directory has been created in the tuplespace - String curTupleSpace = session.getAttribute("USER_TUPLE") + ""; - insight.setTupleSpace(createInsightTupleSpace(curTupleSpace, insightId)); - } - - JobManager manager = JobManager.getManager(); - JobThread jt = manager.makeJob(insightId); - jobId = jt.getJobId(); - session.setAttribute(jobId + "", "TRUE"); - - // set in thread - ThreadStore.setInsightId(insightId); - ThreadStore.setSessionId(sessionId); - ThreadStore.setJobId(jobId); - ThreadStore.setUser(user); - String job = "META | Job(\"" + jobId + "\", \"" + insightId + "\", \"" + sessionId + "\");"; -// // add the job first -// // so we can do things like logging - jt.addPixel(job); - // then add the expression - jt.addPixel(expression); - jt.setInsight(insight); - jt.run(); - PixelRunner pixelRunner = jt.getRunner(); + // if no python, we are done + // execute and return + if(!PyUtils.pyEnabled()) { + return runPixelJob(user, insight, expression, jobId, insightId, sessionId); + } + + // set python into the insight + PyTranslator pyt = null; + // need to see if the user is enabling python here.. I will assume it is here + if (session.getAttribute(Constants.PYTHON) != null) { + pyt = (PyTranslator) session.getAttribute(Constants.PYTHON); + } - manager.flushJob(jobId); - return Response.status(200).entity(PixelStreamUtility.collectPixelData(pixelRunner)).build(); -// } + if(pyt != null) { + insight.setPyTranslator(pyt); + if (insight.getTupleSpace() == null && session.getAttribute("USER_TUPLE") != null) { + // try to see if the insight directory has been created in the tuplespace + String curTupleSpace = session.getAttribute("USER_TUPLE") + ""; + insight.setTupleSpace(createInsightTupleSpace(curTupleSpace, insightId)); + } + return runPixelJob(user, insight, expression, jobId, insightId, sessionId); + } + + // i do not want to make more than 1 py thread per session + // and this method is called many times + synchronized (sessionId) { + if(pyt == null) { + setPythonForSession(session, sessionId, user); + } + + pyt = (PyTranslator) session.getAttribute(Constants.PYTHON); + insight.setPyTranslator(pyt); + if (insight.getTupleSpace() == null && session.getAttribute("USER_TUPLE") != null) { + // try to see if the insight directory has been created in the tuplespace + String curTupleSpace = session.getAttribute("USER_TUPLE") + ""; + insight.setTupleSpace(createInsightTupleSpace(curTupleSpace, insightId)); + } + + return runPixelJob(user, insight, expression, jobId, insightId, sessionId); + } } @POST @@ -524,10 +463,7 @@ public Response getPixelPipelinePlan(@Context HttpServletRequest request) { HttpSession session = null; String sessionId = null; User user = null; - PyExecutorThread jepThread = null; - PyTranslator pyt = null; - String port = null; - + boolean securityEnabled = AbstractSecurityUtils.securityEnabled(); // If security is enabled try to get an existing session. // Otherwise get a session with the default user. @@ -549,96 +485,160 @@ public Response getPixelPipelinePlan(@Context HttpServletRequest request) { user = ((User) session.getAttribute(Constants.SESSION_USER)); sessionId = session.getId(); } + + String insightId = request.getParameter("insightId"); + String expression = request.getParameter("expression"); + Insight insight = InsightStore.getInstance().get(insightId); + if (insight == null) { + Map errorMap = new HashMap<>(); + errorMap.put(ERROR_MESSAGE, "Could not find the insight id"); + return WebUtility.getResponse(errorMap, 400); + } + + // set the user + insight.setUser(user); + // set in thread + ThreadStore.setInsightId(insightId); + ThreadStore.setSessionId(sessionId); + ThreadStore.setUser(user); + + // if no python, we are done + // execute and return + if(!PyUtils.pyEnabled()) { + return getInsightPipeline(insight, expression); + } + + // set python into the insight + PyTranslator pyt = null; // need to see if the user is enabling python here.. I will assume it is here if (session.getAttribute(Constants.PYTHON) != null) { pyt = (PyTranslator) session.getAttribute(Constants.PYTHON); } - if (session.getAttribute("PORT") != null) - port = (String) session.getAttribute("PORT"); + if(pyt != null) { + insight.setPyTranslator(pyt); + if (insight.getTupleSpace() == null && session.getAttribute("USER_TUPLE") != null) { + // try to see if the insight directory has been created in the tuplespace + String curTupleSpace = session.getAttribute("USER_TUPLE") + ""; + insight.setTupleSpace(createInsightTupleSpace(curTupleSpace, insightId)); + } + return getInsightPipeline(insight, expression); + } + + // i do not want to make more than 1 py thread per session + // and this method is called many times + synchronized (sessionId) { + if(pyt == null) { + setPythonForSession(session, sessionId, user); + } + + pyt = (PyTranslator) session.getAttribute(Constants.PYTHON); + insight.setPyTranslator(pyt); + if (insight.getTupleSpace() == null && session.getAttribute("USER_TUPLE") != null) { + // try to see if the insight directory has been created in the tuplespace + String curTupleSpace = session.getAttribute("USER_TUPLE") + ""; + insight.setTupleSpace(createInsightTupleSpace(curTupleSpace, insightId)); + } + + return getInsightPipeline(insight, expression); + } + } + + + /** + * + * @param user + * @param insight + * @param expression + * @param jobId + * @param insightId + * @param sessionId + * @return + */ + private Response runPixelJob(User user, Insight insight, String expression, String jobId, String insightId, String sessionId) { + JobManager manager = JobManager.getManager(); + JobThread jt = manager.makeJob(insightId); + jobId = jt.getJobId(); - if (PyUtils.pyEnabled() && pyt == null) { - // i do not want to make more than 1 py thread per session - // and this method is called many times - synchronized (sessionId) { - if (session.getAttribute(Constants.PYTHON) != null) { - pyt = (PyTranslator) session.getAttribute(Constants.PYTHON); - } + // set in thread + ThreadStore.setInsightId(insightId); + ThreadStore.setSessionId(sessionId); + ThreadStore.setJobId(jobId); + ThreadStore.setUser(user); - boolean useFilePy = DIHelper.getInstance().getProperty("USE_PY_FILE") != null - && DIHelper.getInstance().getProperty("USE_PY_FILE").equalsIgnoreCase("true"); - boolean useTCP = DIHelper.getInstance().getProperty("USE_TCP_PY") != null - && DIHelper.getInstance().getProperty("USE_TCP_PY").equalsIgnoreCase("true"); - useTCP = useFilePy; // forcing it to be same as TCP + String job = "META | Job(\"" + jobId + "\", \"" + insightId + "\", \"" + sessionId + "\");"; + // add the job first + // so we can do things like logging + jt.addPixel(job); + // then add the expression + jt.addPixel(expression); + jt.setInsight(insight); + jt.run(); + PixelRunner pixelRunner = jt.getRunner(); - if (!useFilePy) { - if (session.getAttribute(Constants.PYTHON) != null) { - pyt = (PyTranslator) session.getAttribute(Constants.PYTHON); - } - if (jepThread == null) { - jepThread = PyUtils.getInstance().getJep(); - pyt = new PyTranslator(); - pyt.setPy(jepThread); - } - } - // check to see if the py translator needs to be set ? - else if (useFilePy && session.getAttribute("USER_TUPLE") == null) { - if (useTCP) { - port = DIHelper.getInstance().getProperty("FORCE_PORT"); // this means someone has started it - // for debug - if (port == null) { - port = Utility.findOpenPort(); - session.setAttribute("USER_TUPLE", PyUtils.getInstance().startPyServe(user, - DIHelper.getInstance().getProperty(Constants.INSIGHT_CACHE_DIR), port)); - NettyClient nc = new NettyClient(); - nc.connect("127.0.0.1", Integer.parseInt(port), false); - Thread t = new Thread(nc); - t.start(); - user.setPyServe(nc); - pyt = new TCPPyTranslator(); - ((TCPPyTranslator) pyt).nc = nc; - } - session.setAttribute("PORT", port); - } else { - session.setAttribute("USER_TUPLE", PyUtils.getInstance().getTempTupleSpace(user, - DIHelper.getInstance().getProperty(Constants.INSIGHT_CACHE_DIR))); - pyt = new FilePyTranslator(); - } - } - session.setAttribute(Constants.PYTHON, pyt); + manager.flushJob(jobId); + return Response.status(200).entity(PixelStreamUtility.collectPixelData(pixelRunner)).build(); + } + + /** + * + * @param session + * @param sessionId + * @param user + */ + private void setPythonForSession(HttpSession session, String sessionId, User user) { + PyTranslator pyt = null; + PyExecutorThread jepThread = null; + String port = null; + + boolean useFilePy = Boolean.parseBoolean(DIHelper.getInstance().getProperty("USE_PY_FILE")); + boolean useTCP = Boolean.parseBoolean(DIHelper.getInstance().getProperty("USE_TCP_PY")); + useTCP = useFilePy; // forcing it to be same as TCP + if (!useFilePy) { + if (session.getAttribute(Constants.PYTHON) != null) { + pyt = (PyTranslator) session.getAttribute(Constants.PYTHON); + } + if (jepThread == null) { + jepThread = PyUtils.getInstance().getJep(); + pyt = new PyTranslator(); + pyt.setPy(jepThread); } } - - String insightId = request.getParameter("insightId"); - String expression = request.getParameter("expression"); - Insight insight = InsightStore.getInstance().get(insightId); - if (insight == null) { - Map errorMap = new HashMap<>(); - errorMap.put(ERROR_MESSAGE, "Could not find the insight id"); - return WebUtility.getResponse(errorMap, 400); + // check to see if the py translator needs to be set ? + else if (useFilePy && session.getAttribute("USER_TUPLE") == null) { + if (useTCP) { + port = DIHelper.getInstance().getProperty("FORCE_PORT"); // this means someone has started it + if (port == null) { + port = Utility.findOpenPort(); + session.setAttribute("USER_TUPLE", PyUtils.getInstance().startPyServe(user, + DIHelper.getInstance().getProperty(Constants.INSIGHT_CACHE_DIR), port)); + NettyClient nc = new NettyClient(); + nc.connect("127.0.0.1", Integer.parseInt(port), false); + Thread t = new Thread(nc); + t.start(); + user.setPyServe(nc); + pyt = new TCPPyTranslator(); + ((TCPPyTranslator) pyt).nc = nc; + } + session.setAttribute("PORT", port); + } else { + String userTuple = PyUtils.getInstance().getTempTupleSpace(user, DIHelper.getInstance().getProperty(Constants.INSIGHT_CACHE_DIR)); + session.setAttribute("USER_TUPLE", userTuple); + pyt = new FilePyTranslator(); + } } - // make sure we have the correct session trying to get this id - // #soMuchSecurity - // Set sessionStore = - // InsightStore.getInstance().getInsightIDsForSession(sessionId); - // if(sessionStore == null || !sessionStore.contains(insightId)) { - // Map errorMap = new HashMap(); - // errorMap.put(ERROR_MESSAGE, "Trying to access insight id from incorrect - // session"); - // return WebUtility.getResponse(errorMap, 400); - // } + session.setAttribute(Constants.PYTHON, pyt); + } + + /** + * + * @param insight + * @param expression + * @return + */ + private Response getInsightPipeline(Insight insight, String expression) { synchronized (insight) { - // set the user - insight.setUser(user); - insight.setPy(jepThread); - insight.setPyTranslator(pyt); - - // set in thread - ThreadStore.setInsightId(insightId); - ThreadStore.setSessionId(sessionId); - ThreadStore.setUser(user); - try { return Response.status(200) .entity(GsonUtility.getDefaultGson().toJson(PixelUtility.generatePipeline(insight, expression))) From 79999b8b669ddfce3718ad101fbbef76b67b0d10 Mon Sep 17 00:00:00 2001 From: kunalppatel9 Date: Thu, 7 May 2020 14:22:21 +0000 Subject: [PATCH 0573/1906] BUGFIX ::: Adding an extra check for python from the session in the sync block to prevent multiple initations of setPythonForSession git-svn-id: svn://107.170.10.188:8080/Monolith/dev@38596 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 444e47e57a9a92f479394ae453688d988806af09 --- .../semoss/web/services/local/NameServer.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index ac5b71074..73c41b008 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -440,10 +440,17 @@ public Response runPixelSync(@Context HttpServletRequest request) { // i do not want to make more than 1 py thread per session // and this method is called many times synchronized (sessionId) { + + // adding in a check here again to see if pyt from the session is null. This is because the previous check is outside the sync + //block and multiple threads see it as null + //moving the sync block up will lead to sync's on the run pixel job when unneeded + if (session.getAttribute(Constants.PYTHON) != null) { + pyt = (PyTranslator) session.getAttribute(Constants.PYTHON); + } + if(pyt == null) { setPythonForSession(session, sessionId, user); } - pyt = (PyTranslator) session.getAttribute(Constants.PYTHON); insight.setPyTranslator(pyt); if (insight.getTupleSpace() == null && session.getAttribute("USER_TUPLE") != null) { @@ -528,6 +535,12 @@ public Response getPixelPipelinePlan(@Context HttpServletRequest request) { // i do not want to make more than 1 py thread per session // and this method is called many times synchronized (sessionId) { + // adding in a check here again to see if pyt from the session is null. This is because the previous check is outside the sync + //block and multiple threads see it as null + if (session.getAttribute(Constants.PYTHON) != null) { + pyt = (PyTranslator) session.getAttribute(Constants.PYTHON); + } + if(pyt == null) { setPythonForSession(session, sessionId, user); } From bc1f85d4fb62cd4c6a795a739f19ee7c81ac3dc8 Mon Sep 17 00:00:00 2001 From: kunalppatel9 Date: Mon, 11 May 2020 14:15:48 +0000 Subject: [PATCH 0574/1906] BUGFIX ::: cleaning log messages for fortify git-svn-id: svn://107.170.10.188:8080/Monolith/dev@38633 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: adb86a7e374d56cbbdc5db5478bd36a638ebfe16 --- .../web/services/local/UserResource.java | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index 3104bebf7..56196c539 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -704,7 +704,7 @@ private String getSFRedirect(HttpServletRequest request) throws UnsupportedEncod + "&response_type=code" + "&redirect_uri=" + redirectUri + "&scope=" + URLEncoder.encode("api", "UTF-8"); - logger.debug("Sending redirect.. " + redirectUrl); + logger.debug("Sending redirect.. " + Utility.cleanLogString(redirectUrl)); return redirectUrl; } @@ -780,7 +780,7 @@ private String getSurveyMonkeyRedirect(HttpServletRequest request) throws Unsupp String redirectUrl = "https://api.surveymonkey.com/oauth/authorize?" + "client_id=" + clientId + "&response_type=code" + "&redirect_uri=" + redirectUri; - logger.debug("Sending redirect.. " + redirectUrl); + logger.debug("Sending redirect.. " + Utility.cleanLogString(redirectUrl)); return redirectUrl; } @@ -868,7 +868,7 @@ private String getGithubRedirect(HttpServletRequest request) throws UnsupportedE + redirectUri + "&state=" + UUID.randomUUID().toString() + "&allow_signup=true" + "&scope=" + URLEncoder.encode(scope, "UTF-8"); - logger.debug("Sending redirect.. " + redirectUrl); + logger.debug("Sending redirect.. " + Utility.cleanLogString(redirectUrl)); return redirectUrl; } @@ -952,7 +952,7 @@ private String getMSRedirect(HttpServletRequest request) throws UnsupportedEncod + clientId + "&response_type=code" + "&redirect_uri=" + URLEncoder.encode(redirectUri, "UTF-8") + "&response_mode=query" + "&scope=" + URLEncoder.encode(scope) + "&state=" + state; - logger.debug("Sending redirect.. " + redirectUrl); + logger.debug("Sending redirect.. " + Utility.cleanLogString(redirectUrl)); return redirectUrl; } @@ -1030,7 +1030,7 @@ private String getDBRedirect(HttpServletRequest request) throws UnsupportedEncod + "&response_type=code" + "&redirect_uri=" + URLEncoder.encode(redirectUri, "UTF-8") + "&require_role=" + role + "&disable_signup=false"; - logger.debug("Sending redirect.. " + redirectUrl); + logger.debug("Sending redirect.. " + Utility.cleanLogString(redirectUrl)); return redirectUrl; } @@ -1123,7 +1123,7 @@ private String getGoogleRedirect(HttpServletRequest request) throws UnsupportedE + "&response_type=code" + "&redirect_uri=" + URLEncoder.encode(redirectUri, "UTF-8") + "&access_type=" + accessType + "&scope=" + URLEncoder.encode(scope, "UTF-8") + "&state=" + state; - logger.debug("Sending redirect.. " + redirectUrl); + logger.debug("Sending redirect.. " + Utility.cleanLogString(redirectUrl)); return redirectUrl; } @@ -1257,7 +1257,7 @@ private String getProducthuntRedirect(HttpServletRequest request) throws Unsuppo + "&response_type=code" + "&redirect_uri=" + URLEncoder.encode(redirectUri, "UTF-8") + "&scope=" + URLEncoder.encode(scope, "UTF-8"); - logger.debug("Sending redirect.. " + redirectUrl); + logger.debug("Sending redirect.. " + Utility.cleanLogString(redirectUrl)); return redirectUrl; } @@ -1331,7 +1331,7 @@ private String getInRedirect(HttpServletRequest request) throws UnsupportedEncod + "&redirect_uri=" + redirectUri + "&state=" + UUID.randomUUID().toString() + "&response_type=code" + "&scope=" + URLEncoder.encode(scope, "UTF-8"); - logger.debug("Sending redirect.. " + redirectUrl); + logger.debug("Sending redirect.. " + Utility.cleanLogString(redirectUrl)); return redirectUrl; } @@ -1433,7 +1433,7 @@ private String getTwitterRedirect(HttpServletRequest request) throws Unsupported + "&oauth_callback=" + redirectUri + "&oauth_nonce=" + nonce + "&oauth_timestamp=" + timestamp + "&scope=" + URLEncoder.encode(scope, "UTF-8"); - logger.debug("Sending redirect.. " + redirectUrl); + logger.debug("Sending redirect.. " + Utility.cleanLogString(redirectUrl)); return redirectUrl; } @@ -1825,7 +1825,7 @@ public StreamingOutput manCookie(@Context HttpServletRequest request, @Context H } } - logger.debug("Redirect URL " + redir); + logger.debug("Redirect URL " + Utility.cleanLogString(redir)); outputHash.put("PARAM", redir); // also tell the system that this session is not fully validated so if someone // comes without secret on this session From 8c9e5e0aaa9572683798901818b2a2421fb73731 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 11 May 2020 16:57:06 +0000 Subject: [PATCH 0575/1906] BUGFIX ::: Cannot use prepared statement for "CREATE" statements UPDATE ::: Adding no-cache headers for runPixel/config endpoints UPDATE ::: Adding web.xml filter to X-Content-Type-Options: nosniff and X-Frame-Options DENY git-svn-id: svn://107.170.10.188:8080/Monolith/dev@38641 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 818b1cf649c5c138b1f70903eca01d7d3c55b84a --- WebContent/WEB-INF/web.xml | 10 ++++++++- .../config/ServerConfigurationResource.java | 4 ++-- .../semoss/web/services/local/NameServer.java | 18 ++++++++------- src/prerna/web/services/util/WebUtility.java | 22 +++++++++++++++++++ 4 files changed, 43 insertions(+), 11 deletions(-) diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index 93d03b8ce..5a0899c87 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -18,7 +18,15 @@ SetCharacterEncoding /* - + + HeaderSecurityFilter + org.apache.catalina.filters.HttpHeaderSecurityFilter + + + HeaderSecurityFilter + /* + + StartUpSuccessFilter diff --git a/src/prerna/semoss/web/services/config/ServerConfigurationResource.java b/src/prerna/semoss/web/services/config/ServerConfigurationResource.java index 1d5d9d6e5..317a561eb 100644 --- a/src/prerna/semoss/web/services/config/ServerConfigurationResource.java +++ b/src/prerna/semoss/web/services/config/ServerConfigurationResource.java @@ -183,8 +183,8 @@ public Response getServerConfig(@Context HttpServletRequest request, @Context Ht } } } - - return WebUtility.getResponse(getConfig(request), 200, newCookies.toArray(new NewCookie[] {})); + + return WebUtility.getResponseNoCache(getConfig(request), 200, newCookies.toArray(new NewCookie[] {})); } } diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index 73c41b008..0ec4ea437 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -589,8 +589,10 @@ private Response runPixelJob(User user, Insight insight, String expression, Stri jt.run(); PixelRunner pixelRunner = jt.getRunner(); - manager.flushJob(jobId); - return Response.status(200).entity(PixelStreamUtility.collectPixelData(pixelRunner)).build(); + return Response.status(200).entity(PixelStreamUtility.collectPixelData(pixelRunner)) + .header("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0, post-check=0, pre-check=0") + .header("Pragma", "no-cache") + .build(); } /** @@ -754,21 +756,21 @@ public StreamingOutput result(MultivaluedMap form, @Context Http @POST @Path("/status") @Produces("application/json") - public StreamingOutput status(MultivaluedMap form, @Context HttpServletRequest request) { + public Response status(MultivaluedMap form, @Context HttpServletRequest request) { Object dataReturn = "NULL"; HttpSession session = request.getSession(true); String jobId = form.getFirst("jobId"); if (session.getAttribute(jobId) != null) { dataReturn = JobManager.getManager().getStatus(jobId); } - return WebUtility.getSO(dataReturn); + return WebUtility.getResponseNoCache(dataReturn, 200); } // std outputs and errors @POST @Path("/console") @Produces("application/json") - public StreamingOutput console(MultivaluedMap form, @Context HttpServletRequest request) { + public Response console(MultivaluedMap form, @Context HttpServletRequest request) { Object dataReturn = "NULL"; String jobId = form.getFirst("jobId"); // HttpSession session = request.getSession(true); @@ -776,20 +778,20 @@ public StreamingOutput console(MultivaluedMap form, @Context Htt // if(jobId != null) dataReturn = JobManager.getManager().getStdOut(jobId); // } - return WebUtility.getSO(dataReturn); + return WebUtility.getResponseNoCache(dataReturn, 200); } @POST @Path("/error") @Produces("application/json") - public StreamingOutput error(MultivaluedMap form, @Context HttpServletRequest request) { + public Response error(MultivaluedMap form, @Context HttpServletRequest request) { Object dataReturn = "NULL"; String jobId = form.getFirst("jobId"); // HttpSession session = request.getSession(true); // if(session.getAttribute(jobId) != null) { dataReturn = JobManager.getManager().getError(jobId); // } - return WebUtility.getSO(dataReturn); + return WebUtility.getResponseNoCache(dataReturn, 200); } // close / terminate job diff --git a/src/prerna/web/services/util/WebUtility.java b/src/prerna/web/services/util/WebUtility.java index 31a94ac88..f7e8d7780 100644 --- a/src/prerna/web/services/util/WebUtility.java +++ b/src/prerna/web/services/util/WebUtility.java @@ -31,6 +31,8 @@ import java.io.OutputStream; import java.io.PrintStream; import java.io.UnsupportedEncodingException; +import java.util.List; +import java.util.Vector; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.NewCookie; @@ -53,6 +55,12 @@ public class WebUtility { private static final String CLASS_NAME = WebUtility.class.getName(); private static final Logger LOGGER = Logger.getLogger(CLASS_NAME); + private static final List noCacheHeaders = new Vector(); + static { + noCacheHeaders.add(new String[] {"Cache-Control", "no-store, no-cache, must-revalidate, max-age=0, post-check=0, pre-check=0"}); + noCacheHeaders.add(new String[] {"Pragma", "no-cache"}); + } + private static Gson getDefaultGson() { return GsonUtility.getDefaultGson(); } @@ -82,12 +90,26 @@ public void write(OutputStream outputStream) throws IOException, WebApplicationE } public static Response getResponse(Object vec, int status, NewCookie... cookies) { + return getResponse(vec, status, null, cookies); + } + + public static Response getResponseNoCache(Object vec, int status, NewCookie... cookies) { + return getResponse(vec, status, noCacheHeaders, cookies); + } + + public static Response getResponse(Object vec, int status, List addHeaders, NewCookie... cookies) { if(vec != null) { Gson gson = getDefaultGson(); try { final byte[] output = gson.toJson(vec).getBytes("UTF8"); int length = output.length; ResponseBuilder builder = Response.status(status).entity(WebUtility.getSO(output)).header("Content-Length", length); + if(addHeaders != null && !addHeaders.isEmpty()) { + for(int i = 0; i < addHeaders.size(); i++) { + String[] headerInfo = addHeaders.get(i); + builder.header(headerInfo[0], headerInfo[1]); + } + } if(cookies != null && cookies.length > 0) { builder.cookie(cookies); } From ccac88e8574019d9e45f743a3501f9fe2d7420c3 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 13 May 2020 11:24:26 +0000 Subject: [PATCH 0576/1906] UPDATE ::: Patching files for header manipulation fortify fixes git-svn-id: svn://107.170.10.188:8080/Monolith/dev@38672 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 5025651acf0acd0cb436003ea5f725bc4425afdc --- .../web/services/local/SessionResource.java | 6 ++++++ .../semoss/web/services/local/UserResource.java | 8 ++++++-- src/prerna/web/conf/NoUserExistsFilter.java | 2 +- src/prerna/web/conf/NoUserInSessionFilter.java | 15 ++++++++------- .../conf/NoUserInSessionTrustedTokenFilter.java | 7 ++++--- src/prerna/web/conf/StartUpSuccessFilter.java | 4 +++- 6 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/prerna/semoss/web/services/local/SessionResource.java b/src/prerna/semoss/web/services/local/SessionResource.java index 721969c9f..5fa0e5658 100644 --- a/src/prerna/semoss/web/services/local/SessionResource.java +++ b/src/prerna/semoss/web/services/local/SessionResource.java @@ -187,6 +187,12 @@ public void invalidateSession(@Context HttpServletRequest request, @Context Http response.sendError(302, "Need to redirect to " + customUrl); } else { String scheme = request.getScheme(); // http + + if (!scheme.trim().equalsIgnoreCase("https") && + !scheme.trim().equalsIgnoreCase("http")) { + throw new IllegalArgumentException("scheme is invalid, please input proper scheme"); + } + String serverName = request.getServerName(); // hostname.com int serverPort = request.getServerPort(); // 8080 String contextPath = request.getContextPath(); // /Monolith diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index 56196c539..58f0d36f0 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -313,7 +313,11 @@ public Void call() throws Exception { } else { String redirectUrl = request.getHeader("referer"); if (DBLoader.useLogoutPage()) { - String scheme = request.getScheme(); // http + String scheme = request.getScheme(); + if (!scheme.trim().equalsIgnoreCase("https") && + !scheme.trim().equalsIgnoreCase("http")) { + throw new IllegalArgumentException("scheme is invalid, please input proper scheme"); + } String serverName = request.getServerName(); // hostname.com int serverPort = request.getServerPort(); // 8080 String contextPath = request.getContextPath(); // /Monolith @@ -1473,7 +1477,7 @@ public Response loginNative(@Context HttpServletRequest request, @Context HttpSe try { String username = request.getParameter("username"); String password = request.getParameter("password"); - String redirect = request.getParameter("redirect"); + String redirect = Utility.cleanHttpResponse(request.getParameter("redirect")); Boolean disableRedirect = Boolean.parseBoolean(request.getParameter("enableRedirect") + ""); boolean emptyCredentials = (username == null || password == null || username.isEmpty() diff --git a/src/prerna/web/conf/NoUserExistsFilter.java b/src/prerna/web/conf/NoUserExistsFilter.java index 496075ad2..7ae38e5a0 100644 --- a/src/prerna/web/conf/NoUserExistsFilter.java +++ b/src/prerna/web/conf/NoUserExistsFilter.java @@ -52,7 +52,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 // this will be the full path of the request // like http://localhost:8080/Monolith_Dev/api/engine/runPixel - String fullUrl = ((HttpServletRequest) arg0).getRequestURL().toString(); + String fullUrl = Utility.cleanHttpResponse(((HttpServletRequest) arg0).getRequestURL().toString()); // we redirect to the index.html page where we have pushed the admin page String redirectUrl = fullUrl.substring(0, fullUrl.indexOf(contextPath) + contextPath.length()) + SET_ADMIN_HTML; diff --git a/src/prerna/web/conf/NoUserInSessionFilter.java b/src/prerna/web/conf/NoUserInSessionFilter.java index be8838db6..fa4a0f5d7 100644 --- a/src/prerna/web/conf/NoUserInSessionFilter.java +++ b/src/prerna/web/conf/NoUserInSessionFilter.java @@ -32,6 +32,7 @@ import prerna.auth.utils.AbstractSecurityUtils; import prerna.semoss.web.services.local.UserResource; import prerna.util.Constants; +import prerna.util.Utility; import prerna.web.requests.MultiReadHttpServletRequest; public class NoUserInSessionFilter implements Filter { @@ -81,7 +82,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 // this will be the full path of the request // like http://localhost:8080/Monolith_Dev/api/engine/runPixel - String fullUrl = ((HttpServletRequest) arg0).getRequestURL().toString(); + String fullUrl = Utility.cleanHttpResponse(((HttpServletRequest) arg0).getRequestURL().toString()); String contextPath = ((HttpServletRequest) arg0).getContextPath(); // REALLY DISLIKE THIS CHECK!!! @@ -115,7 +116,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 HttpServletRequest req = (HttpServletRequest) arg0; if (req.getParameter(DBLoader.getSessionIdKey()) != null) { - String sessionId = req.getParameter(DBLoader.getSessionIdKey()); + String sessionId = Utility.cleanHttpResponse(req.getParameter(DBLoader.getSessionIdKey())); // create the cookie add it and sent it back Cookie k = new Cookie(DBLoader.getSessionIdKey(), sessionId); k.setPath(contextPath); @@ -136,7 +137,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 .filter(s -> s.startsWith("route")).collect(Collectors.toSet()); if (routes != null && !routes.isEmpty()) { for (String r : routes) { - Cookie c = new Cookie(r, req.getParameter(r)); + Cookie c = new Cookie(r, Utility.cleanHttpResponse(req.getParameter(r))); c.setPath(contextPath); ((HttpServletResponse) arg1).addCookie(c); } @@ -144,7 +145,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 // add the hash cookie String hash = req.getParameter("hash"); - Cookie h = new Cookie("HASH", hash); + Cookie h = new Cookie("HASH", Utility.cleanHttpResponse(hash)); h.setPath(contextPath); ((HttpServletResponse) arg1).addCookie(h); @@ -194,7 +195,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 // {@link UserResource#setMainPageRedirect(@Context HttpServletRequest request, // @Context HttpServletResponse response)} // is sent to the pop-up for OAuth login - String endpointRedirectUrl = (String) session.getAttribute(NoUserInSessionFilter.ENDPOINT_REDIRECT_KEY); + String endpointRedirectUrl = Utility.cleanHttpResponse((String) session.getAttribute(NoUserInSessionFilter.ENDPOINT_REDIRECT_KEY)); if (endpointRedirectUrl != null && !endpointRedirectUrl.isEmpty()) { ((HttpServletResponse) arg1).setHeader("redirect", endpointRedirectUrl); ((HttpServletResponse) arg1).sendError(302, "Need to redirect to " + endpointRedirectUrl); @@ -244,7 +245,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 // we have the required input, but is it valid InsightToken token = user.getInsight(insightId); try { - MessageDigest md = MessageDigest.getInstance("MD5"); + MessageDigest md = MessageDigest.getInstance("SHA-256"); String finalData = token.getSalt() + secret; byte[] digest = md.digest(finalData.getBytes()); StringBuffer sb = new StringBuffer(); @@ -291,7 +292,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 * @throws IOException */ private void setInvalidEntryRedirect(ServletContext context, ServletRequest arg0, ServletResponse arg1, String endpoint) throws IOException { - String fullUrl = ((HttpServletRequest) arg0).getRequestURL().toString(); + String fullUrl = Utility.cleanHttpResponse(((HttpServletRequest) arg0).getRequestURL().toString()); ((HttpServletResponse) arg1).setStatus(302); String redirectUrl = ((HttpServletRequest) arg0).getHeader("referer"); // if no referrer diff --git a/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java b/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java index 76697cff9..28c0c2db0 100644 --- a/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java +++ b/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java @@ -24,6 +24,7 @@ import prerna.auth.utils.AbstractSecurityUtils; import prerna.auth.utils.SecurityQueryUtils; import prerna.util.Constants; +import prerna.util.Utility; public class NoUserInSessionTrustedTokenFilter implements Filter { @@ -34,7 +35,7 @@ public class NoUserInSessionTrustedTokenFilter implements Filter { private static List trustedDomains = null; // maps from the IP the user is coming in with the cookie - private static Map sessionMapper = new Hashtable(); + private static Map sessionMapper = new Hashtable<>(); private FilterConfig filterConfig; @@ -45,7 +46,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 if(AbstractSecurityUtils.securityEnabled()) { // this will be the full path of the request // like http://localhost:8080/Monolith_Dev/api/engine/runPixel - String fullUrl = ((HttpServletRequest) arg0).getRequestURL().toString(); + String fullUrl = Utility.cleanHttpResponse(((HttpServletRequest) arg0).getRequestURL().toString()); String contextPath = ((HttpServletRequest) arg0).getContextPath(); HttpSession session = ((HttpServletRequest) arg0).getSession(false); @@ -178,7 +179,7 @@ private void setInitParams(ServletRequest arg0) { // the token domains if(NoUserInSessionTrustedTokenFilter.trustedDomains == null) { String [] trustedIPs = this.filterConfig.getInitParameter(NoUserInSessionTrustedTokenFilter.TRUSTED_TOKEN_DOMAIN).split(";"); - NoUserInSessionTrustedTokenFilter.trustedDomains = new Vector(); + NoUserInSessionTrustedTokenFilter.trustedDomains = new Vector<>(); for(String trustedIP : trustedIPs) { NoUserInSessionTrustedTokenFilter.trustedDomains.add(trustedIP.toLowerCase()); } diff --git a/src/prerna/web/conf/StartUpSuccessFilter.java b/src/prerna/web/conf/StartUpSuccessFilter.java index 12b3d0e0a..041666983 100644 --- a/src/prerna/web/conf/StartUpSuccessFilter.java +++ b/src/prerna/web/conf/StartUpSuccessFilter.java @@ -12,6 +12,8 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import prerna.util.Utility; + public class StartUpSuccessFilter implements Filter { private static boolean startUpSuccess = true; @@ -27,7 +29,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 // this will be the full path of the request // like http://localhost:8080/Monolith_Dev/api/engine/runPixel - String fullUrl = ((HttpServletRequest) arg0).getRequestURL().toString(); + String fullUrl = Utility.cleanHttpResponse(((HttpServletRequest) arg0).getRequestURL().toString()); if(!fullUrl.endsWith(FAIL_HTML)) { // we redirect to the index.html page where we have pushed the admin page From 1cc8c6df33394b1c00cd61556da262640e18fe70 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 13 May 2020 11:33:06 +0000 Subject: [PATCH 0577/1906] UPDATE ::: Adding timing bound regex functions for DNS fortify fixes git-svn-id: svn://107.170.10.188:8080/Monolith/dev@38673 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: b441544eaf27690a38989544d98e91995af1fefb --- pom.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pom.xml b/pom.xml index 9f392f935..72842a053 100644 --- a/pom.xml +++ b/pom.xml @@ -2408,6 +2408,11 @@ encoder 1.2.2 + + com.google.re2j + re2j + 1.3 + net.lingala.zip4j zip4j From 719123dd9be5a15c7ec10ba0253c9a182aa45e02 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 13 May 2020 13:20:48 +0000 Subject: [PATCH 0578/1906] UPDATE ::: Making the session counter volatile git-svn-id: svn://107.170.10.188:8080/Monolith/dev@38676 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 3feeb353682a9c2a882afe5277f68337eb20cecb --- src/prerna/web/conf/SessionCounter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prerna/web/conf/SessionCounter.java b/src/prerna/web/conf/SessionCounter.java index 5e51768ac..9f3d656e0 100644 --- a/src/prerna/web/conf/SessionCounter.java +++ b/src/prerna/web/conf/SessionCounter.java @@ -7,7 +7,7 @@ public class SessionCounter implements HttpSessionListener { - private static AtomicInteger activeSessions = new AtomicInteger(0); + private static volatile AtomicInteger activeSessions = new AtomicInteger(0); /* * Simple listener to count the number of active sessions From e3b0799cde9140d3ac8f98721b98e0624143c4de Mon Sep 17 00:00:00 2001 From: kunalppatel9 Date: Wed, 13 May 2020 14:32:03 +0000 Subject: [PATCH 0579/1906] BUGFIX ::: cleaning log messages for fortify git-svn-id: svn://107.170.10.188:8080/Monolith/dev@38679 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 9e7bd4873c53a25eb9ea22d180637d38bfafc28b --- .../cluster/RawSelectWrapperService.java | 6 +++ .../config/ServerConfigurationResource.java | 12 ++++-- .../web/services/local/DataframeResource.java | 3 +- .../services/remote/EngineRemoteResource.java | 30 +++++++------ src/prerna/upload/DatabaseUploader.java | 8 ++-- src/prerna/web/conf/CACFilter.java | 42 +++++++++---------- .../NoUserInSessionTrustedTokenFilter.java | 7 +++- src/prerna/web/conf/PIVFilter.java | 5 ++- src/prerna/web/conf/UserDBLoader.java | 7 +++- .../services/util/ResponseHashSingleton.java | 11 ++++- .../web/services/util/SemossThread.java | 10 ++++- .../services/util/TupleStreamingOutput.java | 9 +++- 12 files changed, 98 insertions(+), 52 deletions(-) diff --git a/src/prerna/cluster/RawSelectWrapperService.java b/src/prerna/cluster/RawSelectWrapperService.java index 54659c0ea..5e2502d6e 100644 --- a/src/prerna/cluster/RawSelectWrapperService.java +++ b/src/prerna/cluster/RawSelectWrapperService.java @@ -16,6 +16,7 @@ import prerna.engine.api.IHeadersDataRow; import prerna.engine.api.IRawSelectWrapper; import prerna.rdf.engine.wrappers.WrapperManager; +import prerna.sablecc2.om.execptions.SemossPixelException; import prerna.util.Utility; import prerna.web.services.util.WebUtility; @@ -57,6 +58,11 @@ private IRawSelectWrapper getRawSelectWrapper(String appId, String wrapperId) th * @throws Exception */ private IRawSelectWrapper getRawSelectWrapper(String appId, String wrapperId, String query) throws Exception { + + if(appId ==null) { + throw new SemossPixelException("App is currently disabled by owner"); + } + String wrapperKey = wrapperId + "@" + appId; if (activeWrappers.containsKey(wrapperKey)) { return activeWrappers.get(wrapperKey); diff --git a/src/prerna/semoss/web/services/config/ServerConfigurationResource.java b/src/prerna/semoss/web/services/config/ServerConfigurationResource.java index 317a561eb..7d8b963c5 100644 --- a/src/prerna/semoss/web/services/config/ServerConfigurationResource.java +++ b/src/prerna/semoss/web/services/config/ServerConfigurationResource.java @@ -16,6 +16,9 @@ import javax.ws.rs.core.NewCookie; import javax.ws.rs.core.Response; +import org.apache.log4j.LogManager; +import org.apache.log4j.Logger; + import prerna.auth.User; import prerna.auth.utils.AbstractSecurityUtils; import prerna.ds.py.PyUtils; @@ -30,6 +33,9 @@ @Path("/config") public class ServerConfigurationResource { + + private static final Logger logger = LogManager.getLogger(ServerConfigurationResource.class); + private static volatile Map config = null; @@ -47,7 +53,7 @@ private static Map getConfig(@Context HttpServletRequest request try { user = ResourceUtility.getUser(request); } catch (IllegalAccessException e) { - // ignore + logger.error("Stack Trace: ", e); } if(config != null) { @@ -102,7 +108,7 @@ private static void loadConfig(HttpSession session) { try { loadConfig.put("file-limit", Integer.parseInt(fileTransferMax)); } catch (Exception e) { - // ignore + logger.error("Stack Trace: ", e); } } @@ -111,7 +117,7 @@ private static void loadConfig(HttpSession session) { Map versionMap = VersionReactor.getVersionMap(); loadConfig.put("version", versionMap); } catch (Exception e) { - // ignore + logger.error("Stack Trace: ", e); } // send the default frame type diff --git a/src/prerna/semoss/web/services/local/DataframeResource.java b/src/prerna/semoss/web/services/local/DataframeResource.java index d837c96a5..699d7a326 100644 --- a/src/prerna/semoss/web/services/local/DataframeResource.java +++ b/src/prerna/semoss/web/services/local/DataframeResource.java @@ -26,12 +26,11 @@ public class DataframeResource { - private static final Logger LOGGER = LogManager.getLogger(DataframeResource.class.getName()); + private static final Logger logger = LogManager.getLogger(DataframeResource.class); @Context ServletContext context; - Logger logger = Logger.getLogger(DataframeResource.class.getName()); Insight insight = null; // @POST diff --git a/src/prerna/semoss/web/services/remote/EngineRemoteResource.java b/src/prerna/semoss/web/services/remote/EngineRemoteResource.java index 95267e5e1..b5e2078f3 100644 --- a/src/prerna/semoss/web/services/remote/EngineRemoteResource.java +++ b/src/prerna/semoss/web/services/remote/EngineRemoteResource.java @@ -40,6 +40,9 @@ import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.StreamingOutput; +import org.apache.log4j.LogManager; +import org.apache.log4j.Logger; + import prerna.engine.api.IConstructWrapper; import prerna.engine.api.IEngine; import prerna.engine.api.IRemoteQueryable; @@ -51,6 +54,7 @@ import prerna.rdf.engine.wrappers.WrapperManager; import prerna.util.Constants; import prerna.util.DIHelper; +import prerna.util.Utility; import prerna.web.services.util.GraphStreamingOutput; import prerna.web.services.util.QueryResultHash; import prerna.web.services.util.TupleStreamingOutput; @@ -60,6 +64,8 @@ public class EngineRemoteResource { + private static final Logger logger = LogManager.getLogger(EngineRemoteResource.class); + public IEngine coreEngine = null; String output = null; String uriBase = null; @@ -107,7 +113,7 @@ public Object execGraphQuery(@FormParam("query") String query) { // Create a wrapper object // The wrapper consists of a unique number, the actual output object // sets this wrapper in the memory - System.out.println("Executing GRAPH Query " + query); + logger.info("Executing GRAPH Query " + Utility.cleanLogString(query)); IConstructWrapper sjw = null; try { @@ -133,7 +139,7 @@ public Object execGraphQuery(@FormParam("query") String query) { @Produces("application/json") public Object execSelectQuery(@FormParam("query") String query) { // TODO Auto-generated method stub - System.out.println("Executing Select Query " + query); + logger.info("Executing Select Query " + Utility.cleanLogString(query)); AbstractWrapper sjsw = null; try { sjsw = (AbstractWrapper) WrapperManager.getInstance().getSWrapper(coreEngine, query); @@ -154,7 +160,7 @@ public Object execSelectQuery(@FormParam("query") String query) { @Produces("application/json") public Object execCheaterQuery(@FormParam("query") String query) { // TODO Auto-generated method stub - System.out.println("Executing Select Query " + query); + logger.info("Executing Select Query " + Utility.cleanLogString(query)); AbstractWrapper sjsw = null; try { sjsw = (AbstractWrapper) WrapperManager.getInstance().getChWrapper(coreEngine, query); @@ -207,7 +213,7 @@ public StreamingOutput execAskQuery(@FormParam("query") String query) { @Produces("application/text") public String getInsightDefinition() { // TODO Auto-generated method stub - System.out.println("ENgine is " + coreEngine); + logger.info("ENgine is " + coreEngine); return coreEngine.getInsightDefinition(); } @@ -226,12 +232,12 @@ public String getOWLDefinition() { public StreamingOutput hasNext(@FormParam("id") String id) { boolean retValue = false; - System.out.println("Got the id " + id); + logger.info("Got the id " + id); if(id != null) { Object wrapper = QueryResultHash.getInstance().getObject(id); - System.out.println("Got the object as well" + wrapper); + logger.info("Got the object as well" + wrapper); // if(wrapper instanceof SesameJenaConstructWrapper) // retValue = ((SesameJenaConstructWrapper)wrapper).hasNext(); // else if(wrapper instanceof SesameJenaSelectWrapper) @@ -254,12 +260,12 @@ public StreamingOutput hasNext(@FormParam("id") String id) public StreamingOutput getDisplayVariables(@FormParam("id") String id) { String [] retValue = null; - System.out.println("Got the id " + id); + logger.info("Got the id " + id); if(id != null) { Object wrapper = QueryResultHash.getInstance().getObject(id); - System.out.println("Got the object as well" + wrapper); + logger.info("Got the object as well" + wrapper); // if(wrapper instanceof SesameJenaConstructWrapper) // retValue = ((SesameJenaConstructWrapper)wrapper).hasNext(); // else if(wrapper instanceof SesameJenaSelectWrapper) @@ -269,7 +275,7 @@ public StreamingOutput getDisplayVariables(@FormParam("id") String id) if(wrapper instanceof SesameSelectWrapper) { - System.out.println(" Select.... "); + logger.info(" Select.... "); retValue = ((SesameSelectWrapper)wrapper).getDisplayVariables(); //return new TupleStreamingOutput(((SesameSelectWrapper)(wrapper)).tqr); } @@ -291,17 +297,17 @@ public StreamingOutput next(@FormParam("id") String id) QueryResultHash.getInstance().cleanObject(id); if(wrapper instanceof SesameSelectCheater) { - System.out.println(" Cheater.... "); + logger.info(" Cheater.... "); return new TupleStreamingOutput(((SesameSelectCheater)wrapper).tqr); } else if(wrapper instanceof SesameConstructWrapper) { - System.out.println(" Construct.... "); + logger.info(" Construct.... "); return new GraphStreamingOutput(((SesameConstructWrapper)(wrapper)).gqr); } else if(wrapper instanceof SesameSelectWrapper) { - System.out.println(" Select.... "); + logger.info(" Select.... "); return new TupleStreamingOutput(((SesameSelectWrapper)(wrapper)).tqr); } } diff --git a/src/prerna/upload/DatabaseUploader.java b/src/prerna/upload/DatabaseUploader.java index 311ef4c11..f0e3c127b 100644 --- a/src/prerna/upload/DatabaseUploader.java +++ b/src/prerna/upload/DatabaseUploader.java @@ -533,7 +533,7 @@ public Response uploadCsvFileAndPredictMetamodel(@Context HttpServletRequest req @Produces("application/json") public Response uploadCSVFile(MultivaluedMap form, @Context HttpServletRequest request) { Gson gson = new Gson(); - System.out.println(form); + logger.info(form); ImportOptions options = null; String[] propFileArr = null; @@ -986,7 +986,7 @@ public Response uploadExcelPOIFormat(@Context HttpServletRequest request) List fileItems = processRequest(request, null); // collect all of the data input on the form Hashtable inputData = getInputData(fileItems); - System.out.println(inputData); + logger.info(inputData); Gson gson = new Gson(); ImportOptions options = null; @@ -1289,7 +1289,7 @@ public Response processExcelFile(@Context HttpServletRequest request) List fileItems = processRequest(request, null); // collect all of the data input on the form Hashtable inputData = getInputData(fileItems); - System.out.println(inputData); + logger.info(inputData); ImportOptions options = null; String[] propFileArr = null; @@ -1435,7 +1435,7 @@ public Response uploadNLPFile(@Context HttpServletRequest request) { List fileItems = processRequest(request, null); // collect all of the data input on the form Hashtable inputData = getInputData(fileItems); - System.out.println(inputData); + logger.info(inputData); Gson gson = new Gson(); // we need to keep track of which NLP items loaded are files verses websites diff --git a/src/prerna/web/conf/CACFilter.java b/src/prerna/web/conf/CACFilter.java index b2f747ad9..aa7ee4c06 100644 --- a/src/prerna/web/conf/CACFilter.java +++ b/src/prerna/web/conf/CACFilter.java @@ -42,7 +42,7 @@ public class CACFilter implements Filter { - private static final Logger LOGGER = LogManager.getLogger(CACFilter.class.getName()); + private static final Logger logger = LogManager.getLogger(CACFilter.class); // filter init params private static final String AUTO_ADD = "autoAdd"; @@ -87,7 +87,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 X509Certificate cert = certs[i]; String fullName = cert.getSubjectX500Principal().getName(); - System.out.println("REQUEST COMING FROM " + fullName); + logger.info("REQUEST COMING FROM " + Utility.cleanLogString(fullName)); LdapName ldapDN; try { @@ -113,7 +113,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 // now set the other properties token.setToken_type(cert.getIssuerDN().getName()); token.setExpires_in((int) cert.getNotAfter().getTime()); - LOGGER.info("Request coming from TOPAZ"); + logger.info("Request coming from TOPAZ"); break CERT_LOOP; } @@ -174,7 +174,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 break CERT_LOOP; } // end rdn loop } catch (InvalidNameException e) { - LOGGER.error("ERROR WITH PARSING CAC INFORMATION!"); + logger.error("ERROR WITH PARSING CAC INFORMATION!"); e.printStackTrace(); } } @@ -183,7 +183,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 // and it has values filled in // we know we can populate the user if(token.getName() != null) { - LOGGER.info("Valid request coming from user " + token.getName()); + logger.info("Valid request coming from user " + token.getName()); user.setAccessToken(token); session.setAttribute(Constants.SESSION_USER, user); @@ -239,18 +239,18 @@ private void setInitParams(ServletRequest arg0) { String logInfoPath = this.filterConfig.getInitParameter(LOG_USER_INFO_PATH); String logInfoSep = this.filterConfig.getInitParameter(LOG_USER_INFO_SEP); if(logInfoPath == null) { - LOGGER.info("SYSTEM HAS REGISTERED TO PERFORM A USER FILE LOG BUT NOT FILE PATH HAS BEEN ENTERED!!!"); - LOGGER.info("SYSTEM HAS REGISTERED TO PERFORM A USER FILE LOG BUT NOT FILE PATH HAS BEEN ENTERED!!!"); - LOGGER.info("SYSTEM HAS REGISTERED TO PERFORM A USER FILE LOG BUT NOT FILE PATH HAS BEEN ENTERED!!!"); - LOGGER.info("SYSTEM HAS REGISTERED TO PERFORM A USER FILE LOG BUT NOT FILE PATH HAS BEEN ENTERED!!!"); + logger.info("SYSTEM HAS REGISTERED TO PERFORM A USER FILE LOG BUT NOT FILE PATH HAS BEEN ENTERED!!!"); + logger.info("SYSTEM HAS REGISTERED TO PERFORM A USER FILE LOG BUT NOT FILE PATH HAS BEEN ENTERED!!!"); + logger.info("SYSTEM HAS REGISTERED TO PERFORM A USER FILE LOG BUT NOT FILE PATH HAS BEEN ENTERED!!!"); + logger.info("SYSTEM HAS REGISTERED TO PERFORM A USER FILE LOG BUT NOT FILE PATH HAS BEEN ENTERED!!!"); } try { userLogger = UserFileLogUtil.getInstance(logInfoPath, logInfoSep); } catch(Exception e) { - LOGGER.info(e.getMessage()); - LOGGER.info(e.getMessage()); - LOGGER.info(e.getMessage()); - LOGGER.info(e.getMessage()); + logger.info(e.getMessage()); + logger.info(e.getMessage()); + logger.info(e.getMessage()); + logger.info(e.getMessage()); } } @@ -265,18 +265,18 @@ private void setInitParams(ServletRequest arg0) { if(countUsers) { String countDatabaseId = this.filterConfig.getInitParameter(COUNT_USER_ENTRY_DATABASE); if(countDatabaseId == null) { - LOGGER.info("SYSTEM HAS REGISTERED TO PERFORM A COUNT BUT NO DATABASE ID HAS BEEN ENTERED!!!"); - LOGGER.info("SYSTEM HAS REGISTERED TO PERFORM A COUNT BUT NO DATABASE ID HAS BEEN ENTERED!!!"); - LOGGER.info("SYSTEM HAS REGISTERED TO PERFORM A COUNT BUT NO DATABASE ID HAS BEEN ENTERED!!!"); - LOGGER.info("SYSTEM HAS REGISTERED TO PERFORM A COUNT BUT NO DATABASE ID HAS BEEN ENTERED!!!"); + logger.info("SYSTEM HAS REGISTERED TO PERFORM A COUNT BUT NO DATABASE ID HAS BEEN ENTERED!!!"); + logger.info("SYSTEM HAS REGISTERED TO PERFORM A COUNT BUT NO DATABASE ID HAS BEEN ENTERED!!!"); + logger.info("SYSTEM HAS REGISTERED TO PERFORM A COUNT BUT NO DATABASE ID HAS BEEN ENTERED!!!"); + logger.info("SYSTEM HAS REGISTERED TO PERFORM A COUNT BUT NO DATABASE ID HAS BEEN ENTERED!!!"); } try { tracker = CACTrackingUtil.getInstance(countDatabaseId); } catch(Exception e) { - LOGGER.info(e.getMessage()); - LOGGER.info(e.getMessage()); - LOGGER.info(e.getMessage()); - LOGGER.info(e.getMessage()); + logger.info(e.getMessage()); + logger.info(e.getMessage()); + logger.info(e.getMessage()); + logger.info(e.getMessage()); } } } diff --git a/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java b/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java index 28c0c2db0..b1122791a 100644 --- a/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java +++ b/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java @@ -18,6 +18,9 @@ import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; +import org.apache.log4j.LogManager; +import org.apache.log4j.Logger; + import prerna.auth.AccessToken; import prerna.auth.AuthProvider; import prerna.auth.User; @@ -28,6 +31,8 @@ public class NoUserInSessionTrustedTokenFilter implements Filter { + private static final Logger logger = LogManager.getLogger(NoUserInSessionTrustedTokenFilter.class); + private static String TRUSTED_TOKEN_PREFIX = "trustedTokenPrefix"; private static String TRUSTED_TOKEN_DOMAIN = "trustedTokenDomain"; @@ -114,7 +119,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 // replace any other session id cookies Cookie[] cookies = req.getCookies(); if (cookies != null) { - System.err.println("Forcing session value !"); + logger.info("Forcing session value !"); for (Cookie c : cookies) { if (c.getName().equals(DBLoader.getSessionIdKey())) { if(c.getName().equalsIgnoreCase(DBLoader.getSessionIdKey())) { diff --git a/src/prerna/web/conf/PIVFilter.java b/src/prerna/web/conf/PIVFilter.java index 91433a72e..4266dacc9 100644 --- a/src/prerna/web/conf/PIVFilter.java +++ b/src/prerna/web/conf/PIVFilter.java @@ -26,12 +26,13 @@ import prerna.auth.User; import prerna.auth.utils.SecurityUpdateUtils; import prerna.util.Constants; +import prerna.util.Utility; import prerna.web.conf.util.CACTrackingUtil; import prerna.web.conf.util.UserFileLogUtil; public class PIVFilter implements Filter { - private static final Logger logger = LogManager.getLogger(PIVFilter.class.getName()); + private static final Logger logger = LogManager.getLogger(PIVFilter.class); // filter init params private static final String AUTO_ADD = "autoAdd"; @@ -75,7 +76,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 X509Certificate cert = certs[i]; String fullName = cert.getSubjectX500Principal().getName(); - System.out.println("REQUEST COMING FROM " + fullName); + logger.info("REQUEST COMING FROM " + Utility.cleanLogString(fullName)); LdapName ldapDN; try { diff --git a/src/prerna/web/conf/UserDBLoader.java b/src/prerna/web/conf/UserDBLoader.java index 2582a83a3..33234185d 100644 --- a/src/prerna/web/conf/UserDBLoader.java +++ b/src/prerna/web/conf/UserDBLoader.java @@ -32,10 +32,15 @@ import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; +import org.apache.log4j.LogManager; +import org.apache.log4j.Logger; + import prerna.cluster.util.ZKClient; public class UserDBLoader implements ServletContextListener { + private static final Logger logger = LogManager.getLogger(UserDBLoader.class); + @Override public void contextDestroyed(ServletContextEvent arg0) { // TODO Auto-generated method stub @@ -47,7 +52,7 @@ public void contextDestroyed(ServletContextEvent arg0) { public void contextInitialized(ServletContextEvent arg0) { // TODO Auto-generated method stub // given a particular user this would load the databases specific to this user - System.out.println("Initializing the context 2"); + logger.info("Initializing the context 2"); publish(); // need to think through this later // this would add the user specific databases diff --git a/src/prerna/web/services/util/ResponseHashSingleton.java b/src/prerna/web/services/util/ResponseHashSingleton.java index d192430b2..5a9277392 100644 --- a/src/prerna/web/services/util/ResponseHashSingleton.java +++ b/src/prerna/web/services/util/ResponseHashSingleton.java @@ -4,9 +4,16 @@ import javax.ws.rs.container.AsyncResponse; +import org.apache.log4j.LogManager; +import org.apache.log4j.Logger; + +import prerna.util.Utility; + public class ResponseHashSingleton { + private static final Logger logger = LogManager.getLogger(ResponseHashSingleton.class); + static HashMap respoHash = new HashMap(); static HashMap threadHash = new HashMap(); @@ -22,7 +29,7 @@ public static AsyncResponse getResponseforJobId(String jobId) public static void setResponse(String jobId, AsyncResponse response) { - System.out.println("Dropping in job id " + jobId); + logger.info("Dropping in job id " + Utility.cleanLogString(jobId)); respoHash.put(jobId, response); } @@ -33,7 +40,7 @@ public static SemossThread getThread(String jobId) public static void setThread(String jobId, SemossThread thread) { - System.out.println("Dropping in job id " + jobId); + logger.info("Dropping in job id " + Utility.cleanLogString(jobId)); threadHash.put(jobId, thread); } diff --git a/src/prerna/web/services/util/SemossThread.java b/src/prerna/web/services/util/SemossThread.java index 8b78db8f4..88f75ec80 100644 --- a/src/prerna/web/services/util/SemossThread.java +++ b/src/prerna/web/services/util/SemossThread.java @@ -2,7 +2,13 @@ import javax.ws.rs.container.AsyncResponse; +import org.apache.log4j.LogManager; +import org.apache.log4j.Logger; + public class SemossThread extends Thread { + + private static final Logger logger = LogManager.getLogger(SemossThread.class); + String jobId; boolean complete = false; @@ -34,12 +40,12 @@ public void run() { count++; Thread.sleep(2000); } - System.out.println("Complete"); + logger.info("Complete"); }catch(InterruptedException ex) { // try to see who interrupted and why and then possibly kill the thread ? complete = true; - System.out.println("Interrupted.. "); + logger.info("Interrupted.. "); } } diff --git a/src/prerna/web/services/util/TupleStreamingOutput.java b/src/prerna/web/services/util/TupleStreamingOutput.java index 7ef3c34f5..0122f6eef 100644 --- a/src/prerna/web/services/util/TupleStreamingOutput.java +++ b/src/prerna/web/services/util/TupleStreamingOutput.java @@ -34,10 +34,15 @@ import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.StreamingOutput; +import org.apache.log4j.LogManager; +import org.apache.log4j.Logger; import org.openrdf.query.QueryEvaluationException; import org.openrdf.query.TupleQueryResult; public class TupleStreamingOutput implements StreamingOutput { + + private static final Logger logger = LogManager.getLogger(TupleStreamingOutput.class); + TupleQueryResult gqr = null; @@ -52,10 +57,10 @@ public void write(OutputStream outputStream) throws IOException, ObjectOutputStream os = new ObjectOutputStream(outputStream); Integer myInt = null; try { - System.out.println("Writing Objects "); + logger.info("Writing Objects "); while(gqr.hasNext()) { - System.out.print("."); + logger.info("."); os.writeObject(gqr.next()); } os.writeObject("null"); From 7cb6b5d3d5c5b45095a5c6fdcc7705748a8e48f4 Mon Sep 17 00:00:00 2001 From: kunalppatel9 Date: Wed, 13 May 2020 15:41:13 +0000 Subject: [PATCH 0580/1906] BUGFIX ::: removing printing stacktrace for logging them git-svn-id: svn://107.170.10.188:8080/Monolith/dev@38684 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 2aef69c6825491e515df8cdee3b2915b173828a0 --- .../cluster/RawSelectWrapperService.java | 26 +++++++----- src/prerna/semoss/web/form/FormResource.java | 18 ++++---- .../web/services/local/AppResource.java | 8 +++- .../services/local/AuthorizationResource.java | 16 ++++--- .../web/services/local/EngineResource.java | 13 +++--- .../auth/AdminAppAuthorizationResource.java | 6 ++- .../local/auth/AppAuthorizationResource.java | 13 ++++-- .../services/remote/EngineRemoteResource.java | 13 +++--- src/prerna/upload/DatabaseUploader.java | 42 ++++++++++--------- src/prerna/web/conf/CACFilter.java | 19 +++++---- src/prerna/web/conf/DBLoader.java | 2 +- src/prerna/web/conf/NoUserExistsFilter.java | 7 +++- src/prerna/web/conf/PIVFilter.java | 3 +- .../util/SemossExecutorSingleton.java | 6 ++- src/prerna/web/services/util/WebUtility.java | 8 ++-- 15 files changed, 120 insertions(+), 80 deletions(-) diff --git a/src/prerna/cluster/RawSelectWrapperService.java b/src/prerna/cluster/RawSelectWrapperService.java index 5e2502d6e..5edea119e 100644 --- a/src/prerna/cluster/RawSelectWrapperService.java +++ b/src/prerna/cluster/RawSelectWrapperService.java @@ -11,6 +11,9 @@ import javax.ws.rs.core.Context; import javax.ws.rs.core.Response; +import org.apache.log4j.LogManager; +import org.apache.log4j.Logger; + import prerna.algorithm.api.SemossDataType; import prerna.engine.api.IEngine; import prerna.engine.api.IHeadersDataRow; @@ -23,6 +26,9 @@ @Path("/cluster") public class RawSelectWrapperService implements IRawSelectWrapper { + private static final String STACKTRACE = "StackTrace: "; + private static final Logger logger = LogManager.getLogger(RawSelectWrapperService.class); + public static final String APP_ID = "appId"; public static final String WRAPPER_ID = "wrapperId"; public static final String QUERY = "query"; @@ -145,7 +151,7 @@ public Response execute(@Context HttpServletRequest request) { wrapper = getRawSelectWrapper(appId, wrapperId, query); wrapper.execute(); } catch (Exception e) { - e.printStackTrace(); + logger.error(STACKTRACE,e); ret.put("errorMessage", e.getMessage()); return WebUtility.getResponse(ret, 400); } @@ -190,7 +196,7 @@ public Response setQuery(@Context HttpServletRequest request) { wrapper = getRawSelectWrapper(appId, wrapperId, query); wrapper.setQuery(query); } catch (Exception e) { - e.printStackTrace(); + logger.error(STACKTRACE,e); } // Set return values @@ -227,7 +233,7 @@ public Response cleanUp(@Context HttpServletRequest request) { try { wrapper = getRawSelectWrapper(appId, wrapperId); } catch (Exception e) { - e.printStackTrace(); + logger.error(STACKTRACE,e); } finally { if(wrapper != null) { wrapper.cleanUp(); @@ -276,7 +282,7 @@ public Response setEngine(@Context HttpServletRequest request) { IEngine engine = getEngine(appId); wrapper.setEngine(engine); } catch (Exception e) { - e.printStackTrace(); + logger.error(STACKTRACE,e); } // Set return values @@ -314,7 +320,7 @@ public Response hasNext(@Context HttpServletRequest request) { wrapper = getRawSelectWrapper(appId, wrapperId); hasNext = wrapper.hasNext(); } catch (Exception e) { - e.printStackTrace(); + logger.error(STACKTRACE,e); } // Set return values @@ -347,7 +353,7 @@ public Response next(@Context HttpServletRequest request) { wrapper = getRawSelectWrapper(appId, wrapperId); nextRow = wrapper.next(); } catch (Exception e) { - e.printStackTrace(); + logger.error(STACKTRACE,e); } // Set return values @@ -381,7 +387,7 @@ public Response getHeaders(@Context HttpServletRequest request) { headers = wrapper.getHeaders(); } catch (Exception e) { // TODO Auto-generated catch block - e.printStackTrace(); + logger.error(STACKTRACE,e); } // Set return values @@ -414,7 +420,7 @@ public Response getTypes(@Context HttpServletRequest request) { wrapper = getRawSelectWrapper(appId, wrapperId); types = wrapper.getTypes(); } catch (Exception e) { - e.printStackTrace(); + logger.error(STACKTRACE,e); } // Set return values @@ -447,7 +453,7 @@ public Response getNumRecords(@Context HttpServletRequest request) { wrapper = getRawSelectWrapper(appId, wrapperId); numRecords = wrapper.getNumRecords(); } catch (Exception e) { - e.printStackTrace(); + logger.error(STACKTRACE,e); Hashtable ret = new Hashtable(); ret.put("errorMessage", e.getMessage()); return WebUtility.getResponse(ret, 400); @@ -519,7 +525,7 @@ public Response reset(@Context HttpServletRequest request) { wrapper = getRawSelectWrapper(appId, wrapperId); wrapper.reset(); } catch (Exception e) { - e.printStackTrace(); + logger.error(STACKTRACE,e); ret.put("errorMessage", e.getMessage()); return WebUtility.getResponse(ret, 400); } diff --git a/src/prerna/semoss/web/form/FormResource.java b/src/prerna/semoss/web/form/FormResource.java index 619f45090..60cdc19fa 100644 --- a/src/prerna/semoss/web/form/FormResource.java +++ b/src/prerna/semoss/web/form/FormResource.java @@ -16,6 +16,8 @@ import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; +import org.apache.log4j.Logger; + import prerna.auth.AuthProvider; import prerna.auth.User; import prerna.ds.util.RdbmsQueryBuilder; @@ -33,6 +35,8 @@ @Path("/form") public class FormResource { + private static final Logger logger = Logger.getLogger(FormResource.class); + private IEngine formEngine; @POST @@ -89,7 +93,7 @@ public Response modifyUserAccess(@Context HttpServletRequest request, Multivalue // commit to engine formEngine.commit(); } catch (Exception e) { - e.printStackTrace(); + logger.error("Stacktrace: " , e); return WebUtility.getResponse("An error occured to update the user's access!", 400); } @@ -192,8 +196,8 @@ public Response getUserInstanceAuth(@Context HttpServletRequest request) throws userAccessableInstances.put(values[0].toString(), values[1].toString()); } } catch (Exception e) { - e.printStackTrace(); - } finally { + logger.error("Stacktrace: " , e); + } finally { if(wrapper != null) { wrapper.cleanUp(); } @@ -245,8 +249,8 @@ private void throwErrorIfNotAdmin(String cacId) throws IllegalAccessException { throw new IllegalAccessException("User is not an admin and cannot perform this operation"); } } catch (Exception e) { - e.printStackTrace(); - } finally { + logger.error("Stacktrace: " , e); + } finally { if(wrapper != null) { wrapper.cleanUp(); } @@ -272,8 +276,8 @@ private void throwErrorIfNotSysAdmin(String cacId, String system) throws Illegal throw new IllegalAccessException("User is not an admin and cannot perform this operation"); } } catch (Exception e) { - e.printStackTrace(); - } finally { + logger.error("Stacktrace: " , e); + } finally { if(wrapper != null) { wrapper.cleanUp(); } diff --git a/src/prerna/semoss/web/services/local/AppResource.java b/src/prerna/semoss/web/services/local/AppResource.java index 384b70ffa..e20fbb7a0 100644 --- a/src/prerna/semoss/web/services/local/AppResource.java +++ b/src/prerna/semoss/web/services/local/AppResource.java @@ -30,6 +30,7 @@ import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.io.filefilter.WildcardFileFilter; +import org.apache.log4j.Logger; import prerna.auth.User; import prerna.auth.utils.AbstractSecurityUtils; @@ -53,6 +54,9 @@ public class AppResource { private static String defaultEmbedLogo = null; private static boolean noLogo = false; + private static final Logger logger = Logger.getLogger(AppResource.class); + private static final String STACKTRACE = "StackTrace: "; + private boolean canAccessApp(User user, String appId) throws IllegalAccessException { if(AbstractSecurityUtils.securityEnabled()) { appId = SecurityQueryUtils.testUserEngineIdForAlias(user, appId); @@ -536,7 +540,7 @@ protected void closeStream(FileInputStream fis) { try { fis.close(); } catch (IOException e) { - e.printStackTrace(); + logger.error(STACKTRACE, e); } } } @@ -572,7 +576,7 @@ public Response getAppWidget(@PathParam("appId") String app, @QueryParam("widget // return file return Response.status(200).entity(byteArray).build(); } catch (IOException e) { - e.printStackTrace(); + logger.error(STACKTRACE, e); } finally { closeStream(fis); } diff --git a/src/prerna/semoss/web/services/local/AuthorizationResource.java b/src/prerna/semoss/web/services/local/AuthorizationResource.java index 9a1899122..6f166ff54 100644 --- a/src/prerna/semoss/web/services/local/AuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/AuthorizationResource.java @@ -44,6 +44,8 @@ import javax.ws.rs.core.Response; import javax.ws.rs.core.StreamingOutput; +import org.apache.log4j.Logger; + import com.google.gson.Gson; import prerna.auth.User; @@ -57,6 +59,8 @@ @Path("/authorization") public class AuthorizationResource { + private static final Logger logger = Logger.getLogger(AuthorizationResource.class); + private static final String STACKTRACE = "StackTrace: "; @Context protected ServletContext context; @@ -103,11 +107,11 @@ public Response registerUser(@Context HttpServletRequest request, MultivaluedMap return WebUtility.getResponse(errorRet, 400); } } catch (IllegalArgumentException e){ - e.printStackTrace(); + logger.error(STACKTRACE, e); errorRet.put("error", e.getMessage()); return WebUtility.getResponse(errorRet, 400); } catch (Exception e){ - e.printStackTrace(); + logger.error(STACKTRACE, e); errorRet.put("error", "An unexpected error happened. Please try again."); return WebUtility.getResponse(errorRet, 500); } @@ -229,12 +233,12 @@ public Response requestAccess(@Context HttpServletRequest request, MultivaluedMa try { addedRequests = SecurityUpdateUtils.makeRequest(user, engineId, requestedPermission); } catch(IllegalArgumentException e) { - e.printStackTrace(); + logger.error(STACKTRACE, e); Map errorRet = new HashMap(); errorRet.put("error", e.getMessage()); return WebUtility.getResponse(errorRet, 400); } catch (Exception e){ - e.printStackTrace(); + logger.error(STACKTRACE, e); Map errorRet = new HashMap(); errorRet.put("error", "An unexpected error happened. Please try again."); return WebUtility.getResponse(errorRet, 500); @@ -260,12 +264,12 @@ public Response getMyRequests(@Context HttpServletRequest request) { try { userRequests = SecurityQueryUtils.getUserAccessRequests(user); } catch(IllegalArgumentException e) { - e.printStackTrace(); + logger.error(STACKTRACE, e); Map errorRet = new HashMap(); errorRet.put("error", e.getMessage()); return WebUtility.getResponse(errorRet, 400); } catch (Exception e){ - e.printStackTrace(); + logger.error(STACKTRACE, e); Map errorRet = new HashMap(); errorRet.put("error", "An unexpected error happened. Please try again."); return WebUtility.getResponse(errorRet, 500); diff --git a/src/prerna/semoss/web/services/local/EngineResource.java b/src/prerna/semoss/web/services/local/EngineResource.java index a4ee6d9a3..4df5e5064 100644 --- a/src/prerna/semoss/web/services/local/EngineResource.java +++ b/src/prerna/semoss/web/services/local/EngineResource.java @@ -74,7 +74,8 @@ public class EngineResource { - private static final Logger LOGGER = Logger.getLogger(EngineResource.class.getName()); + private static final Logger logger = Logger.getLogger(EngineResource.class); + private static final String STACKTRACE = "StackTrace: "; // gets everything specific to an engine // essentially this is a wrapper over the engine @@ -82,7 +83,7 @@ public class EngineResource { public void setEngine(IEngine coreEngine) { - LOGGER.info("Setting core engine to " + coreEngine); + logger.info("Setting core engine to " + coreEngine); this.coreEngine = coreEngine; } @@ -137,7 +138,7 @@ public Response queryDataSelect(MultivaluedMap form) } } } - System.out.println(query); + logger.info(Utility.cleanLogString(query)); // flush data out List data = new Vector(); @@ -148,7 +149,7 @@ public Response queryDataSelect(MultivaluedMap form) data.add(wrapper.next().getRawValues()); } } catch (Exception e) { - e.printStackTrace(); + logger.error(STACKTRACE,e); } finally { if(wrapper != null) { wrapper.cleanUp(); @@ -273,7 +274,7 @@ public Response commitFormData(@Context HttpServletRequest request, MultivaluedM FormBuilder.commitFormData(this.coreEngine, engineHash, userId); } } catch(Exception e) { - e.printStackTrace(); + logger.error(STACKTRACE,e); return WebUtility.getResponse(gson.toJson(e.getMessage()), 400); } @@ -290,7 +291,7 @@ public Response getAuditLogForEngine(MultivaluedMap form, @Conte try { auditInfo = FormBuilder.getAuditDataForEngine(this.coreEngine.getEngineId()); } catch(Exception e) { - e.printStackTrace(); + logger.error(STACKTRACE,e); return WebUtility.getResponse(gson.toJson(e.getMessage()), 400); } diff --git a/src/prerna/semoss/web/services/local/auth/AdminAppAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/AdminAppAuthorizationResource.java index f698f4183..c25179611 100644 --- a/src/prerna/semoss/web/services/local/auth/AdminAppAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/AdminAppAuthorizationResource.java @@ -14,6 +14,8 @@ import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; +import org.apache.log4j.Logger; + import prerna.auth.utils.SecurityAdminUtils; import prerna.semoss.web.services.local.ResourceUtility; import prerna.web.services.util.WebUtility; @@ -21,6 +23,8 @@ @Path("/auth/admin/app") public class AdminAppAuthorizationResource extends AbstractAdminResource { + private static final Logger logger = Logger.getLogger(AdminAppAuthorizationResource.class); + @Context protected ServletContext context; @@ -210,7 +214,7 @@ public Response setAppGlobal(@Context HttpServletRequest request, MultivaluedMap try { adminUtils.setAppGlobal(engineId, isPublic); } catch (Exception e){ - e.printStackTrace(); + logger.error("Stacktrace: ",e); Map errorRet = new HashMap(); errorRet.put("error", "An unexpected error happened. Please try again."); return WebUtility.getResponse(errorRet, 500); diff --git a/src/prerna/semoss/web/services/local/auth/AppAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/AppAuthorizationResource.java index 919278999..565fb9505 100644 --- a/src/prerna/semoss/web/services/local/auth/AppAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/AppAuthorizationResource.java @@ -15,6 +15,8 @@ import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; +import org.apache.log4j.Logger; + import prerna.auth.User; import prerna.auth.utils.SecurityAppUtils; import prerna.auth.utils.SecurityQueryUtils; @@ -26,6 +28,9 @@ @Path("/auth/app") public class AppAuthorizationResource { + private static final Logger logger = Logger.getLogger(AppAuthorizationResource.class); + private static final String STACKTRACE = "StackTrace: "; + @Context protected ServletContext context; @@ -250,12 +255,12 @@ public Response setAppGlobal(@Context HttpServletRequest request, MultivaluedMap try { SecurityAppUtils.setAppGlobal(user, engineId, isPublic); } catch(IllegalArgumentException e) { - e.printStackTrace(); + logger.error(STACKTRACE, e); Map errorRet = new HashMap(); errorRet.put("error", e.getMessage()); return WebUtility.getResponse(errorRet, 400); } catch (Exception e){ - e.printStackTrace(); + logger.error(STACKTRACE, e); Map errorRet = new HashMap(); errorRet.put("error", "An unexpected error happened. Please try again."); return WebUtility.getResponse(errorRet, 500); @@ -290,12 +295,12 @@ public Response setAppVisibility(@Context HttpServletRequest request, Multivalue try { SecurityUpdateUtils.setDbVisibility(user, appId, isPublic); } catch(IllegalArgumentException e) { - e.printStackTrace(); + logger.error(STACKTRACE, e); Map errorRet = new HashMap(); errorRet.put("error", e.getMessage()); return WebUtility.getResponse(errorRet, 400); } catch (Exception e){ - e.printStackTrace(); + logger.error(STACKTRACE, e); Map errorRet = new HashMap(); errorRet.put("error", "An unexpected error happened. Please try again."); return WebUtility.getResponse(errorRet, 500); diff --git a/src/prerna/semoss/web/services/remote/EngineRemoteResource.java b/src/prerna/semoss/web/services/remote/EngineRemoteResource.java index b5e2078f3..f60ba421d 100644 --- a/src/prerna/semoss/web/services/remote/EngineRemoteResource.java +++ b/src/prerna/semoss/web/services/remote/EngineRemoteResource.java @@ -65,7 +65,8 @@ public class EngineRemoteResource { private static final Logger logger = LogManager.getLogger(EngineRemoteResource.class); - + private static final String STACKTRACE = "StackTrace: "; + public IEngine coreEngine = null; String output = null; String uriBase = null; @@ -128,7 +129,7 @@ public Object execGraphQuery(@FormParam("query") String query) { ((IRemoteQueryable)sjw).setRemoteAPI(uriBase + coreEngine.getEngineId()); QueryResultHash.getInstance().addObject((SesameConstructWrapper)sjw); } catch (Exception e) { - e.printStackTrace(); + logger.error(STACKTRACE,e); } return WebUtility.getSO(sjw); @@ -148,7 +149,7 @@ public Object execSelectQuery(@FormParam("query") String query) { ((IRemoteQueryable)sjsw).setRemoteAPI(uriBase + coreEngine.getEngineId()); QueryResultHash.getInstance().addObject(sjsw); } catch (Exception e) { - e.printStackTrace(); + logger.error(STACKTRACE,e); } return WebUtility.getSO(sjsw); @@ -169,7 +170,7 @@ public Object execCheaterQuery(@FormParam("query") String query) { ((IRemoteQueryable)sjsw).setRemoteAPI(uriBase + coreEngine.getEngineId()); QueryResultHash.getInstance().addObject(sjsw); } catch (Exception e) { - e.printStackTrace(); + logger.error(STACKTRACE,e); } return WebUtility.getSO(sjsw); @@ -191,7 +192,7 @@ public StreamingOutput execAskQuery(@FormParam("query") String query) { try { return WebUtility.getSO(coreEngine.execQuery(query)); } catch (Exception e) { - e.printStackTrace(); + logger.error(STACKTRACE,e); Hashtable ret = new Hashtable(); ret.put("errorMessage", e.getMessage()); return WebUtility.getSO(ret); @@ -366,7 +367,7 @@ public void write(OutputStream outputStream) throws IOException, WebApplicationE Thread.sleep(200); } catch (InterruptedException e) { // TODO Auto-generated catch block - e.printStackTrace(); + logger.error(STACKTRACE,e); } } }}; diff --git a/src/prerna/upload/DatabaseUploader.java b/src/prerna/upload/DatabaseUploader.java index f0e3c127b..079704458 100644 --- a/src/prerna/upload/DatabaseUploader.java +++ b/src/prerna/upload/DatabaseUploader.java @@ -80,6 +80,8 @@ @Deprecated public class DatabaseUploader extends Uploader { private static final Logger logger = LogManager.getLogger(DatabaseUploader.class); + private static final String STACKTRACE = "StackTrace: "; + // we will control the adding of the engine into local master and solr // such that we dont send a success before those processes are complete boolean autoLoad = false; @@ -514,7 +516,7 @@ public Response uploadCsvFileAndPredictMetamodel(@Context HttpServletRequest req helper.clear(); } } catch(Exception e) { - e.printStackTrace(); + logger.error(STACKTRACE, e); // grab the error thrown and send it to the FE HashMap errorMap = new HashMap<>(); @@ -670,18 +672,18 @@ public Response uploadCSVFile(MultivaluedMap form, @Context Http .concat("_").concat(dateName).concat("_PROP.prop")), propFileArr[i]); } } catch (IOException e) { - e.printStackTrace(); + logger.error(STACKTRACE, e); Map errorHash = new HashMap<>(); errorHash.put("errorMessage", "Failure to write CSV Prop File based on user-defined metamodel."); return Response.status(400).entity(gson.toJson(errorHash)).build(); } } catch (IOException e) { - e.printStackTrace(); + logger.error(STACKTRACE, e); Map errorHash = new HashMap<>(); errorHash.put("errorMessage", e.getMessage()); return Response.status(400).entity(gson.toJson(errorHash)).build(); } catch(Exception e) { - e.printStackTrace(); + logger.error(STACKTRACE, e); Map errorHash = new HashMap<>(); errorHash.put("errorMessage", e.getMessage()); return Response.status(400).entity(gson.toJson(errorHash)).build(); @@ -963,7 +965,7 @@ public Response uploadExcelFile(@Context HttpServletRequest request) { metaModelData.add(fileMetaModelData); } } catch(Exception e) { - e.printStackTrace(); + logger.error(STACKTRACE, e); // grab the error thrown and send it to the FE HashMap errorMap = new HashMap<>(); @@ -1022,12 +1024,12 @@ public Response uploadExcelPOIFormat(@Context HttpServletRequest request) ImportDataProcessor importer = new ImportDataProcessor(); importer.runProcessor(options); } catch (IOException e) { - e.printStackTrace(); + logger.error(STACKTRACE,e); Map errorHash = new HashMap<>(); errorHash.put("errorMessage", e.getMessage()); return Response.status(400).entity(gson.toJson(errorHash)).build(); } catch(Exception e) { - e.printStackTrace(); + logger.error(STACKTRACE,e); Map errorHash = new HashMap<>(); errorHash.put("errorMessage", e.getMessage()); return Response.status(400).entity(gson.toJson(errorHash)).build(); @@ -1067,7 +1069,7 @@ public Response getExistingRDBMSMetadata(@Context HttpServletRequest request, Mu try { ret = importer.getSchemaDetails(driver, hostname, port, username, password, schema, additionalProperties); } catch(Exception e) { - e.printStackTrace(); + logger.error(STACKTRACE,e); if(e.getMessage() != null) { ret.put("errorMessage", e.getMessage()); } else { @@ -1260,7 +1262,7 @@ public Response uploadXrayConfig(@Context HttpServletRequest request) { br.close(); } } catch(Exception e) { - e.printStackTrace(); + logger.error(STACKTRACE,e); // grab the error thrown and send it to the FE HashMap errorMap = new HashMap<>(); errorMap.put("errorMessage", e.getMessage()); @@ -1382,12 +1384,12 @@ public Response processExcelFile(@Context HttpServletRequest request) ImportDataProcessor importer = new ImportDataProcessor(); importer.runProcessor(options); } catch (IOException e) { - e.printStackTrace(); + logger.error(STACKTRACE,e); Map errorHash = new HashMap<>(); errorHash.put("errorMessage", e.getMessage()); return Response.status(400).entity(gson.toJson(errorHash)).build(); } catch(Exception e) { - e.printStackTrace(); + logger.error(STACKTRACE,e); Map errorHash = new HashMap<>(); errorHash.put("errorMessage", e.getMessage()); return Response.status(400).entity(gson.toJson(errorHash)).build(); @@ -1416,7 +1418,7 @@ public Response processExcelFile(@Context HttpServletRequest request) .concat("_").concat(dateName).concat("_PROP.prop")), propFileArr[i]); } } catch (IOException e) { - e.printStackTrace(); + logger.error(STACKTRACE,e); Map errorHash = new HashMap<>(); errorHash.put("errorMessage", "Failure to write Excel Prop File based on user-defined metamodel."); return Response.status(400).entity(gson.toJson(errorHash)).build(); @@ -1464,7 +1466,7 @@ public Response uploadNLPFile(@Context HttpServletRequest request) { writer = new PrintWriter(inputText); writer.write(inputData.get("nlptext").toString()); } catch (FileNotFoundException e) { - e.printStackTrace(); + logger.error(STACKTRACE,e); } finally { if(writer != null) { writer.close(); @@ -1508,12 +1510,12 @@ public Response uploadNLPFile(@Context HttpServletRequest request) { ImportDataProcessor importer = new ImportDataProcessor(); importer.runProcessor(options); } catch (IOException e) { - e.printStackTrace(); + logger.error(STACKTRACE,e); Map errorHash = new HashMap<>(); errorHash.put("errorMessage", e.getMessage()); return Response.status(400).entity(gson.toJson(errorHash)).build(); } catch(Exception e) { - e.printStackTrace(); + logger.error(STACKTRACE,e); Map errorHash = new HashMap<>(); errorHash.put("errorMessage", e.getMessage()); return Response.status(400).entity(gson.toJson(errorHash)).build(); @@ -1612,12 +1614,12 @@ public Response uploadNLPFile(@Context HttpServletRequest request) { // ImportDataProcessor importer = new ImportDataProcessor(); // importer.runProcessor(options); // } catch (IOException e) { -// e.printStackTrace(); +// logger.error(STACKTRACE,e); // Map errorHash = new HashMap(); // errorHash.put("errorMessage", e.getMessage()); // return Response.status(400).entity(gson.toJson(errorHash)).build(); // } catch(Exception e) { -// e.printStackTrace(); +// logger.error(STACKTRACE,e); // Map errorHash = new HashMap(); // errorHash.put("errorMessage", e.getMessage()); // return Response.status(400).entity(gson.toJson(errorHash)).build(); @@ -1707,12 +1709,12 @@ public Response uploadNLPFile(@Context HttpServletRequest request) { // ImportDataProcessor importer = new ImportDataProcessor(); // importer.runProcessor(options); // } catch (IOException e) { -// e.printStackTrace(); +// logger.error(STACKTRACE,e); // Map errorHash = new HashMap(); // errorHash.put("errorMessage", e.getMessage()); // return Response.status(400).entity(gson.toJson(errorHash)).build(); // } catch(Exception e) { -// e.printStackTrace(); +// logger.error(STACKTRACE,e); // Map errorHash = new HashMap(); // errorHash.put("errorMessage", e.getMessage()); // return Response.status(400).entity(gson.toJson(errorHash)).build(); @@ -1825,7 +1827,7 @@ public Response uploadNLPFile(@Context HttpServletRequest request) { // try { // connector.processExistingSolrConnection(appName, appID, solrURL, coreName ); // } catch (IOException e) { -// e.printStackTrace(); +// logger.error(STACKTRACE,e); // Map errorMap = new HashMap(); // errorMap.put("errorMessage", e.getMessage()); // return WebUtility.getResponse(errorMap, 400); diff --git a/src/prerna/web/conf/CACFilter.java b/src/prerna/web/conf/CACFilter.java index aa7ee4c06..dc30b435f 100644 --- a/src/prerna/web/conf/CACFilter.java +++ b/src/prerna/web/conf/CACFilter.java @@ -43,6 +43,7 @@ public class CACFilter implements Filter { private static final Logger logger = LogManager.getLogger(CACFilter.class); + private static final String STACKTRACE = "StackTrace: "; // filter init params private static final String AUTO_ADD = "autoAdd"; @@ -157,7 +158,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 } } } catch (CertificateParsingException e) { - e.printStackTrace(); + logger.error(STACKTRACE, e); } if(email != null) { @@ -175,7 +176,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 } // end rdn loop } catch (InvalidNameException e) { logger.error("ERROR WITH PARSING CAC INFORMATION!"); - e.printStackTrace(); + logger.error(STACKTRACE, e); } } @@ -307,7 +308,7 @@ private void updateCacUsersStorage(String previousId, String newId) { try { securityDb.insertData(updateQuery); } catch (SQLException e) { - e.printStackTrace(); + logger.error(STACKTRACE, e); } // need to update all the places the user id is used @@ -315,7 +316,7 @@ private void updateCacUsersStorage(String previousId, String newId) { try { securityDb.insertData(updateQuery); } catch (SQLException e) { - e.printStackTrace(); + logger.error(STACKTRACE, e); } // need to update all the places the user id is used @@ -323,11 +324,11 @@ private void updateCacUsersStorage(String previousId, String newId) { try { securityDb.insertData(updateQuery); } catch (SQLException e) { - e.printStackTrace(); + logger.error(STACKTRACE, e); } } } catch (Exception e1) { - e1.printStackTrace(); + logger.error(STACKTRACE, e1); } finally { if(wrapper != null) { wrapper.cleanUp(); @@ -358,7 +359,7 @@ private void updateCacUsersStorage(String previousId, String newId) { formEngine.insertData("UPDATE FORMS_USER_ACCESS SET EMAIL = USER_ID;"); } } catch (Exception e) { - e.printStackTrace(); + logger.error(STACKTRACE, e); } finally { if(requireFormUpdateWrapper != null) { requireFormUpdateWrapper.cleanUp(); @@ -370,12 +371,12 @@ private void updateCacUsersStorage(String previousId, String newId) { try { formEngine.insertData(updateQuery); } catch (SQLException e) { - e.printStackTrace(); + logger.error(STACKTRACE, e); } } } catch (Exception e1) { - e1.printStackTrace(); + logger.error(STACKTRACE, e1); } finally { if(wrapper != null) { wrapper.cleanUp(); diff --git a/src/prerna/web/conf/DBLoader.java b/src/prerna/web/conf/DBLoader.java index 14792842e..8eb986f61 100644 --- a/src/prerna/web/conf/DBLoader.java +++ b/src/prerna/web/conf/DBLoader.java @@ -208,7 +208,7 @@ public void loadEngines() { } } } catch (Exception ex) { - ex.printStackTrace(); + logger.error(STACKTRACE, ex); } } diff --git a/src/prerna/web/conf/NoUserExistsFilter.java b/src/prerna/web/conf/NoUserExistsFilter.java index 7ae38e5a0..7685dd3a2 100644 --- a/src/prerna/web/conf/NoUserExistsFilter.java +++ b/src/prerna/web/conf/NoUserExistsFilter.java @@ -11,6 +11,9 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.apache.log4j.LogManager; +import org.apache.log4j.Logger; + import prerna.auth.utils.AbstractSecurityUtils; import prerna.engine.api.IEngine; import prerna.engine.api.IRawSelectWrapper; @@ -21,6 +24,8 @@ public class NoUserExistsFilter implements Filter { + private static final Logger logger = LogManager.getLogger(NoUserExistsFilter.class); + private static final String SET_ADMIN_HTML = "/setAdmin/"; private static boolean userDefined = false; @@ -64,7 +69,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 NoUserExistsFilter.userDefined = true; } } catch (Exception e) { - e.printStackTrace(); + logger.error("Stacktrace: ",e); } finally { if(wrapper != null) { wrapper.cleanUp(); diff --git a/src/prerna/web/conf/PIVFilter.java b/src/prerna/web/conf/PIVFilter.java index 4266dacc9..391652818 100644 --- a/src/prerna/web/conf/PIVFilter.java +++ b/src/prerna/web/conf/PIVFilter.java @@ -33,6 +33,7 @@ public class PIVFilter implements Filter { private static final Logger logger = LogManager.getLogger(PIVFilter.class); + private static final String STACKTRACE = "StackTrace: "; // filter init params private static final String AUTO_ADD = "autoAdd"; @@ -113,7 +114,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 } // end rdn loop } catch (InvalidNameException e) { logger.error("ERROR WITH PARSING CAC INFORMATION!"); - e.printStackTrace(); + logger.error(STACKTRACE,e); } } diff --git a/src/prerna/web/services/util/SemossExecutorSingleton.java b/src/prerna/web/services/util/SemossExecutorSingleton.java index 216562e00..6c839fc7b 100644 --- a/src/prerna/web/services/util/SemossExecutorSingleton.java +++ b/src/prerna/web/services/util/SemossExecutorSingleton.java @@ -3,10 +3,14 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import org.apache.log4j.Logger; + import prerna.web.services.util.SemossThread; public class SemossExecutorSingleton { + private static final Logger logger = Logger.getLogger(SemossExecutorSingleton.class); + static SemossExecutorSingleton singleton = null; ExecutorService service = null; int count = 0; @@ -40,7 +44,7 @@ public String execute(Runnable t) String jobId = "j" + count; ((SemossThread)t).setJobId(jobId); service.execute(t); - System.out.println("Serving thread" + "j" + count); + logger.info("Serving thread" + "j" + count); return jobId; } } diff --git a/src/prerna/web/services/util/WebUtility.java b/src/prerna/web/services/util/WebUtility.java index f7e8d7780..30b2503b2 100644 --- a/src/prerna/web/services/util/WebUtility.java +++ b/src/prerna/web/services/util/WebUtility.java @@ -81,8 +81,7 @@ public void write(OutputStream outputStream) throws IOException, WebApplicationE } }}; } catch (UnsupportedEncodingException e) { - e.printStackTrace(); - LOGGER.error("Failed to write object to stream"); + LOGGER.error("Failed to write object to stream. Stacktrace: ", e); } } @@ -115,7 +114,7 @@ public static Response getResponse(Object vec, int status, List addHea } return builder.build(); } catch (UnsupportedEncodingException e) { - e.printStackTrace(); + LOGGER.error("Stacktrace: ", e); } return Response.status(200).entity(WebUtility.getSO(vec)).build(); } @@ -135,8 +134,7 @@ public void write(OutputStream outputStream) throws IOException, WebApplicationE } }}; } catch (Exception e) { - e.printStackTrace(); - LOGGER.error("Failed to write object to stream"); + LOGGER.error("Failed to write object to stream. Stacktrace: ",e); } return null; From f03be511764eb42e911d534e7cb492d102c56938 Mon Sep 17 00:00:00 2001 From: kunalppatel9 Date: Wed, 13 May 2020 18:12:47 +0000 Subject: [PATCH 0581/1906] BUGFIX ::: reverting back to ignoring the error thrown. No need to print it as it is expected to fail at times and that is okay. git-svn-id: svn://107.170.10.188:8080/Monolith/dev@38690 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 13cde31fbb0568a3056b119ecfaf5ee1b5ede1e3 --- .../semoss/web/services/config/ServerConfigurationResource.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prerna/semoss/web/services/config/ServerConfigurationResource.java b/src/prerna/semoss/web/services/config/ServerConfigurationResource.java index 7d8b963c5..651a313a7 100644 --- a/src/prerna/semoss/web/services/config/ServerConfigurationResource.java +++ b/src/prerna/semoss/web/services/config/ServerConfigurationResource.java @@ -53,7 +53,7 @@ private static Map getConfig(@Context HttpServletRequest request try { user = ResourceUtility.getUser(request); } catch (IllegalAccessException e) { - logger.error("Stack Trace: ", e); + //ignoring user here because it is okay to. This is for health checks or server checks even when users havent been instantiated. } if(config != null) { From fc0c6c044e9bfcfee37d2db605300d4e7cf2bb3d Mon Sep 17 00:00:00 2001 From: kunalppatel9 Date: Wed, 13 May 2020 18:16:12 +0000 Subject: [PATCH 0582/1906] BUGFIX ::: removing testing methods BUGFIX ::: removing unused assignments git-svn-id: svn://107.170.10.188:8080/Monolith/dev@38692 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: efe5d6514a4a2a08e7683cdb442318f585a10487 --- src/prerna/semoss/web/services/local/UserResource.java | 4 ++-- .../semoss/web/services/remote/EngineRemoteResource.java | 1 - src/prerna/web/conf/DBLoader.java | 3 +-- src/prerna/web/services/util/GraphStreamingOutput.java | 1 - src/prerna/web/services/util/InstanceStreamer.java | 4 ++++ src/prerna/web/services/util/TupleStreamingOutput.java | 1 - 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index 58f0d36f0..52b699691 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -276,8 +276,8 @@ public Void call() throws Exception { String workspaceEngineId = null; if (thisUser.getLogins().size() == 1) { - assetEngineId = thisUser.getAssetEngineId(token); - workspaceEngineId = thisUser.getWorkspaceEngineId(token); + thisUser.getAssetEngineId(token); + thisUser.getWorkspaceEngineId(token); } removed = thisUser.dropAccessToken(token); if (thisUser.getLogins().isEmpty()) { diff --git a/src/prerna/semoss/web/services/remote/EngineRemoteResource.java b/src/prerna/semoss/web/services/remote/EngineRemoteResource.java index f60ba421d..cb83c00c5 100644 --- a/src/prerna/semoss/web/services/remote/EngineRemoteResource.java +++ b/src/prerna/semoss/web/services/remote/EngineRemoteResource.java @@ -354,7 +354,6 @@ public StreamingOutput getStreamTester() { return new StreamingOutput() { public void write(OutputStream outputStream) throws IOException, WebApplicationException { - PrintStream ps = new PrintStream(outputStream); ObjectOutputStream os = new ObjectOutputStream(outputStream); Integer myInt = null; for(int i = 0;i< 1000000;i++) diff --git a/src/prerna/web/conf/DBLoader.java b/src/prerna/web/conf/DBLoader.java index 8eb986f61..6e0d3e450 100644 --- a/src/prerna/web/conf/DBLoader.java +++ b/src/prerna/web/conf/DBLoader.java @@ -186,8 +186,7 @@ public void contextInitialized(ServletContextEvent arg0) { } public void loadEngines() { - String watcherStr = DIHelper.getInstance().getProperty(Constants.ENGINE_WEB_WATCHER); - StringTokenizer watchers = new StringTokenizer(watcherStr, ";"); + StringTokenizer watchers = new StringTokenizer(DIHelper.getInstance().getProperty(Constants.ENGINE_WEB_WATCHER), ";"); try { while (watchers.hasMoreElements()) { Object monitor = new Object(); diff --git a/src/prerna/web/services/util/GraphStreamingOutput.java b/src/prerna/web/services/util/GraphStreamingOutput.java index 0262719c2..c0c5a66af 100644 --- a/src/prerna/web/services/util/GraphStreamingOutput.java +++ b/src/prerna/web/services/util/GraphStreamingOutput.java @@ -50,7 +50,6 @@ public GraphStreamingOutput(GraphQueryResult gqr) public void write(OutputStream outputStream) throws IOException, WebApplicationException { ObjectOutputStream os = new ObjectOutputStream(outputStream); - Integer myInt = null; try { while(gqr.hasNext()) os.writeObject(gqr.next()); diff --git a/src/prerna/web/services/util/InstanceStreamer.java b/src/prerna/web/services/util/InstanceStreamer.java index 5e6a77c6f..f90f83838 100644 --- a/src/prerna/web/services/util/InstanceStreamer.java +++ b/src/prerna/web/services/util/InstanceStreamer.java @@ -204,6 +204,7 @@ public int compare(Object o1, Object o2) { }); } + /** * Testing section. * @@ -212,6 +213,8 @@ public int compare(Object o1, Object o2) { * list 3) Create 1M random strings with length 10, time how long it takes to * create tree, and search if any of them start with "tomato". */ + + /* public static void main(String[] args) { Object[] strArray = { "course", "dearth", "overseas", "podcast", "portrait", "advertising", "contract", "clean", "endurance", "fresh", "guitar", "wear", "jackpot", "tool", "post", "space", "brunette", "big", "cheek", @@ -410,4 +413,5 @@ public static void main(String[] args) { } logger.debug("Testing complete."); } + */ } diff --git a/src/prerna/web/services/util/TupleStreamingOutput.java b/src/prerna/web/services/util/TupleStreamingOutput.java index 0122f6eef..585f499e8 100644 --- a/src/prerna/web/services/util/TupleStreamingOutput.java +++ b/src/prerna/web/services/util/TupleStreamingOutput.java @@ -55,7 +55,6 @@ public TupleStreamingOutput(TupleQueryResult gqr) public void write(OutputStream outputStream) throws IOException, WebApplicationException { ObjectOutputStream os = new ObjectOutputStream(outputStream); - Integer myInt = null; try { logger.info("Writing Objects "); while(gqr.hasNext()) From c27e4cb73918f224f9959cb233a15312417ff115 Mon Sep 17 00:00:00 2001 From: pkapaleeswaran Date: Wed, 13 May 2020 21:11:53 +0000 Subject: [PATCH 0583/1906] Commit for onDemand Python - Python Doesn't automatically start up. Will start only when you attempt to do something with it. git-svn-id: svn://107.170.10.188:8080/Monolith/dev@38706 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: e4ebc897d6958ab675e55e45f328e5f744ae42ce --- .../semoss/web/services/local/NameServer.java | 14 +++++++++++--- .../semoss/web/services/local/UserResource.java | 17 +++++++++++++---- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index 0ec4ea437..de6b86f51 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -416,11 +416,15 @@ public Response runPixelSync(@Context HttpServletRequest request) { // if no python, we are done // execute and return - if(!PyUtils.pyEnabled()) { + // this should do it + //if(!PyUtils.pyEnabled()) + { return runPixelJob(user, insight, expression, jobId, insightId, sessionId); } // set python into the insight + // not needed anymore + /* PyTranslator pyt = null; // need to see if the user is enabling python here.. I will assume it is here if (session.getAttribute(Constants.PYTHON) != null) { @@ -460,7 +464,8 @@ public Response runPixelSync(@Context HttpServletRequest request) { } return runPixelJob(user, insight, expression, jobId, insightId, sessionId); - } + } */ + } @POST @@ -511,11 +516,13 @@ public Response getPixelPipelinePlan(@Context HttpServletRequest request) { // if no python, we are done // execute and return - if(!PyUtils.pyEnabled()) { + //if(!PyUtils.pyEnabled()) + { return getInsightPipeline(insight, expression); } // set python into the insight + /* PyTranslator pyt = null; // need to see if the user is enabling python here.. I will assume it is here if (session.getAttribute(Constants.PYTHON) != null) { @@ -555,6 +562,7 @@ public Response getPixelPipelinePlan(@Context HttpServletRequest request) { return getInsightPipeline(insight, expression); } + */ } diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index 52b699691..4ce838bc9 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -253,14 +253,15 @@ public Void call() throws Exception { // stop python too if (PyUtils.pyEnabled()) { - PyTranslator pyt = (PyTranslator) session.getAttribute(Constants.PYTHON); + PyTranslator pyt = thisUser.getPyTranslator(false); + if (pyt instanceof prerna.ds.py.PyTranslator) PyUtils.getInstance().killPyThread(pyt.getPy()); if (pyt instanceof FilePyTranslator && thisUser != null) PyUtils.getInstance().killTempTupleSpace(thisUser); if (pyt instanceof TCPPyTranslator) { NettyClient nc = thisUser.getPyServe(); - String dir = (String) session.getAttribute("USER_TUPLE"); + String dir = thisUser.pyTupleSpace; nc.stopPyServe(dir); } } @@ -379,10 +380,16 @@ private void addAccessToken(AccessToken token, HttpServletRequest request) { User semossUser = null; HttpSession session = request.getSession(); Object user = session.getAttribute(Constants.SESSION_USER); + + + // all of this is now in the user + if (user != null) { semossUser = (User) user; } else { semossUser = new User(); + } + /* PyTranslator pyt = null; // also add the python thread to this user // if security is not on, we have a single py thread for the entire instance @@ -442,8 +449,10 @@ else if (useFilePy && session.getAttribute("USER_TUPLE") == null) { String tupleSpace = PyUtils.getInstance().getTempTupleSpace(token.getName(), DIHelper.getInstance().getProperty(Constants.INSIGHT_CACHE_DIR)); semossUser.setTupleSpace(tupleSpace); session.setAttribute("USER_TUPLE", tupleSpace); - }*/ - } + } + }*/ + + semossUser.setAccessToken(token); semossUser.setAnonymous(false); request.getSession().setAttribute(Constants.SESSION_USER, semossUser); From 57acc8cd05884820d6d5f49270a3b665bde33af0 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 13 May 2020 22:04:45 +0000 Subject: [PATCH 0584/1906] BUGFIX ::: Adding null check git-svn-id: svn://107.170.10.188:8080/Monolith/dev@38714 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 026fa09de95c1aff48768ea6959495da120452fb --- src/prerna/semoss/web/services/local/AppResource.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prerna/semoss/web/services/local/AppResource.java b/src/prerna/semoss/web/services/local/AppResource.java index e20fbb7a0..75ea534c5 100644 --- a/src/prerna/semoss/web/services/local/AppResource.java +++ b/src/prerna/semoss/web/services/local/AppResource.java @@ -289,7 +289,7 @@ public Response getEmbedUrl(@Context final Request coreRequest, @Context HttpSer private static String getEmbedLogo() { if(AppResource.defaultEmbedLogo == null) { String embedFileName = DIHelper.getInstance().getProperty(Constants.EMBED_URL_LOGO); - if(embedFileName.equalsIgnoreCase("NONE")) { + if(embedFileName == null || embedFileName.equalsIgnoreCase("NONE")) { AppResource.noLogo = true; AppResource.defaultEmbedLogo = "NONE"; } else { From 7bf96ac85c0de12f68ba5bdd51e571fde352af2f Mon Sep 17 00:00:00 2001 From: pkapaleeswaran Date: Wed, 13 May 2020 22:52:41 +0000 Subject: [PATCH 0585/1906] Cleaned up the python parts. Now everything is fixed to user. git-svn-id: svn://107.170.10.188:8080/Monolith/dev@38716 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: a88b08d9ebf8befb07c6dfe49fee51dee644a5a0 --- .../semoss/web/services/local/NameServer.java | 101 +----------------- .../web/services/local/UserResource.java | 64 ----------- 2 files changed, 2 insertions(+), 163 deletions(-) diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index de6b86f51..5b6ecdec6 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -414,57 +414,7 @@ public Response runPixelSync(@Context HttpServletRequest request) { // set the user insight.setUser(user); - // if no python, we are done - // execute and return - // this should do it - //if(!PyUtils.pyEnabled()) - { - return runPixelJob(user, insight, expression, jobId, insightId, sessionId); - } - - // set python into the insight - // not needed anymore - /* - PyTranslator pyt = null; - // need to see if the user is enabling python here.. I will assume it is here - if (session.getAttribute(Constants.PYTHON) != null) { - pyt = (PyTranslator) session.getAttribute(Constants.PYTHON); - } - - if(pyt != null) { - insight.setPyTranslator(pyt); - if (insight.getTupleSpace() == null && session.getAttribute("USER_TUPLE") != null) { - // try to see if the insight directory has been created in the tuplespace - String curTupleSpace = session.getAttribute("USER_TUPLE") + ""; - insight.setTupleSpace(createInsightTupleSpace(curTupleSpace, insightId)); - } - return runPixelJob(user, insight, expression, jobId, insightId, sessionId); - } - - // i do not want to make more than 1 py thread per session - // and this method is called many times - synchronized (sessionId) { - - // adding in a check here again to see if pyt from the session is null. This is because the previous check is outside the sync - //block and multiple threads see it as null - //moving the sync block up will lead to sync's on the run pixel job when unneeded - if (session.getAttribute(Constants.PYTHON) != null) { - pyt = (PyTranslator) session.getAttribute(Constants.PYTHON); - } - - if(pyt == null) { - setPythonForSession(session, sessionId, user); - } - pyt = (PyTranslator) session.getAttribute(Constants.PYTHON); - insight.setPyTranslator(pyt); - if (insight.getTupleSpace() == null && session.getAttribute("USER_TUPLE") != null) { - // try to see if the insight directory has been created in the tuplespace - String curTupleSpace = session.getAttribute("USER_TUPLE") + ""; - insight.setTupleSpace(createInsightTupleSpace(curTupleSpace, insightId)); - } - - return runPixelJob(user, insight, expression, jobId, insightId, sessionId); - } */ + return runPixelJob(user, insight, expression, jobId, insightId, sessionId); } @@ -514,55 +464,8 @@ public Response getPixelPipelinePlan(@Context HttpServletRequest request) { ThreadStore.setSessionId(sessionId); ThreadStore.setUser(user); - // if no python, we are done - // execute and return - //if(!PyUtils.pyEnabled()) - { - return getInsightPipeline(insight, expression); - } - - // set python into the insight - /* - PyTranslator pyt = null; - // need to see if the user is enabling python here.. I will assume it is here - if (session.getAttribute(Constants.PYTHON) != null) { - pyt = (PyTranslator) session.getAttribute(Constants.PYTHON); - } - - if(pyt != null) { - insight.setPyTranslator(pyt); - if (insight.getTupleSpace() == null && session.getAttribute("USER_TUPLE") != null) { - // try to see if the insight directory has been created in the tuplespace - String curTupleSpace = session.getAttribute("USER_TUPLE") + ""; - insight.setTupleSpace(createInsightTupleSpace(curTupleSpace, insightId)); - } - return getInsightPipeline(insight, expression); - } + return getInsightPipeline(insight, expression); - // i do not want to make more than 1 py thread per session - // and this method is called many times - synchronized (sessionId) { - // adding in a check here again to see if pyt from the session is null. This is because the previous check is outside the sync - //block and multiple threads see it as null - if (session.getAttribute(Constants.PYTHON) != null) { - pyt = (PyTranslator) session.getAttribute(Constants.PYTHON); - } - - if(pyt == null) { - setPythonForSession(session, sessionId, user); - } - - pyt = (PyTranslator) session.getAttribute(Constants.PYTHON); - insight.setPyTranslator(pyt); - if (insight.getTupleSpace() == null && session.getAttribute("USER_TUPLE") != null) { - // try to see if the insight directory has been created in the tuplespace - String curTupleSpace = session.getAttribute("USER_TUPLE") + ""; - insight.setTupleSpace(createInsightTupleSpace(curTupleSpace, insightId)); - } - - return getInsightPipeline(insight, expression); - } - */ } diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index 4ce838bc9..fd50baf66 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -389,70 +389,6 @@ private void addAccessToken(AccessToken token, HttpServletRequest request) { } else { semossUser = new User(); } - /* - PyTranslator pyt = null; - // also add the python thread to this user - // if security is not on, we have a single py thread for the entire instance - // and we dont want to override those variables due to user login - if (AbstractSecurityUtils.securityEnabled() && PyUtils.pyEnabled()) { - - if (session.getAttribute(Constants.PYTHON) != null) { - pyt = (PyTranslator) session.getAttribute(Constants.PYTHON); - } - - boolean useFilePy = DIHelper.getInstance().getProperty("USE_PY_FILE") != null - && DIHelper.getInstance().getProperty("USE_PY_FILE").equalsIgnoreCase("true"); - boolean useTCP = DIHelper.getInstance().getProperty("USE_TCP_PY") != null - && DIHelper.getInstance().getProperty("USE_TCP_PY").equalsIgnoreCase("true"); - useTCP = useFilePy; // forcing it to be same as TCP - - if (!useFilePy) { - PyExecutorThread jepThread = null; - if (session.getAttribute(Constants.PYTHON) != null) { - pyt = (PyTranslator) session.getAttribute(Constants.PYTHON); - } - if (jepThread == null) { - jepThread = PyUtils.getInstance().getJep(); - pyt = new PyTranslator(); - pyt.setPy(jepThread); - } - } - // check to see if the py translator needs to be set ? - // check to see if the py translator needs to be set ? - else if (useFilePy && session.getAttribute("USER_TUPLE") == null) { - if (useTCP) { - String port = DIHelper.getInstance().getProperty("FORCE_PORT"); // this means someone has - // started it for debug - if (port == null) { - port = Utility.findOpenPort(); - session.setAttribute("USER_TUPLE", PyUtils.getInstance().startPyServe(semossUser, - DIHelper.getInstance().getProperty(Constants.INSIGHT_CACHE_DIR), port)); - NettyClient nc = new NettyClient(); - nc.connect("127.0.0.1", Integer.parseInt(port), false); - Thread t = new Thread(nc); - t.start(); - semossUser.setPyServe(nc); - pyt = new TCPPyTranslator(); - ((TCPPyTranslator) pyt).nc = nc; - } - session.setAttribute("PORT", port); - } else { - session.setAttribute("USER_TUPLE", PyUtils.getInstance().getTempTupleSpace(semossUser, - DIHelper.getInstance().getProperty(Constants.INSIGHT_CACHE_DIR))); - pyt = new FilePyTranslator(); - } - } - session.setAttribute(Constants.PYTHON, pyt); - } - /*if(session.getAttribute("USER_TUPLE") == null) - { - String tupleSpace = PyUtils.getInstance().getTempTupleSpace(token.getName(), DIHelper.getInstance().getProperty(Constants.INSIGHT_CACHE_DIR)); - semossUser.setTupleSpace(tupleSpace); - session.setAttribute("USER_TUPLE", tupleSpace); - } - }*/ - - semossUser.setAccessToken(token); semossUser.setAnonymous(false); request.getSession().setAttribute(Constants.SESSION_USER, semossUser); From a9ad7a6e2f96d3da3ec39cf34e3efdeb671b8e7c Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 14 May 2020 00:52:45 +0000 Subject: [PATCH 0586/1906] UPDATE ::: Setting the session name from dbloader into the chrome driver instead of requiring in rdf_map BUGFIX ::: Fixing error with to pdf parameters due to order change git-svn-id: svn://107.170.10.188:8080/Monolith/dev@38718 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: a5f845ecc008e29cef4616f3fb602ce791c0eff3 --- src/prerna/web/conf/DBLoader.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/prerna/web/conf/DBLoader.java b/src/prerna/web/conf/DBLoader.java index 6e0d3e450..497509858 100644 --- a/src/prerna/web/conf/DBLoader.java +++ b/src/prerna/web/conf/DBLoader.java @@ -45,6 +45,7 @@ import com.ibm.icu.util.StringTokenizer; import prerna.engine.api.IEngine; +import prerna.engine.impl.r.RserveUtil; import prerna.forms.AbstractFormBuilder; import prerna.nameserver.utility.MasterDatabaseUtility; import prerna.om.Insight; @@ -127,6 +128,7 @@ public void contextInitialized(ServletContextEvent arg0) { SessionCookieConfig cookieConfig = context.getSessionCookieConfig(); if (cookieConfig != null && cookieConfig.getName() != null) { DBLoader.SESSION_ID_KEY = cookieConfig.getName(); + ChromeDriverUtility.setSessionCookie(cookieConfig.getName()); } } @@ -145,6 +147,15 @@ public void contextInitialized(ServletContextEvent arg0) { logger.info("Setting log4j property: " + log4jConfig); PropertyConfigurator.configure(log4jConfig); + if(RserveUtil.R_KILL_ON_STARTUP) { + logger.info("Killing existing RServes running on the machine"); + try { + RserveUtil.endR(); + } catch (Exception e) { + logger.info("Unable to kill existing RServes running on the machine"); + } + } + // set security enabled within DIHelper first // this is because security database, on init, will // load it as a boolean instead of us searching within DIHelper From ad6f5ecb5a68e693a4e4f29f9e62eea1cad7fe1c Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 14 May 2020 13:49:36 +0000 Subject: [PATCH 0587/1906] UPDATE ::: Printing the IP address as well to the logs git-svn-id: svn://107.170.10.188:8080/Monolith/dev@38722 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 5dde48d5329762a06af8c8d8a0ae2202c113d190 --- src/prerna/web/conf/CACFilter.java | 6 +++++- src/prerna/web/conf/PIVFilter.java | 6 +++++- src/prerna/web/conf/util/UserFileLogUtil.java | 4 ++-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/prerna/web/conf/CACFilter.java b/src/prerna/web/conf/CACFilter.java index dc30b435f..c8db1070b 100644 --- a/src/prerna/web/conf/CACFilter.java +++ b/src/prerna/web/conf/CACFilter.java @@ -201,7 +201,11 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 // are we logging their information? if(userLogger != null && !token.getName().equals("TOPAZ")) { - userLogger.addToQueue(new String[] {cacId, email, name, LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))}); + // grab the ip address + String ipAddress1 = ((HttpServletRequest)arg0).getHeader("X-FORWARDED-FOR"); + String ipAddress2 = ((HttpServletRequest)arg0).getRemoteAddr(); + + userLogger.addToQueue(new String[] {email, name, LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")), ipAddress1, ipAddress2}); } } } diff --git a/src/prerna/web/conf/PIVFilter.java b/src/prerna/web/conf/PIVFilter.java index 391652818..29c5f98ea 100644 --- a/src/prerna/web/conf/PIVFilter.java +++ b/src/prerna/web/conf/PIVFilter.java @@ -139,7 +139,11 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 // are we logging their information? if(userLogger != null) { - userLogger.addToQueue(new String[] {email, name, LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))}); + // grab the ip address + String ipAddress1 = ((HttpServletRequest)arg0).getHeader("X-FORWARDED-FOR"); + String ipAddress2 = ((HttpServletRequest)arg0).getRemoteAddr(); + + userLogger.addToQueue(new String[] {email, name, LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")), ipAddress1, ipAddress2}); } } } diff --git a/src/prerna/web/conf/util/UserFileLogUtil.java b/src/prerna/web/conf/util/UserFileLogUtil.java index da48d4e15..f87fcec11 100644 --- a/src/prerna/web/conf/util/UserFileLogUtil.java +++ b/src/prerna/web/conf/util/UserFileLogUtil.java @@ -88,9 +88,9 @@ public void run() { } int size = row.length; StringBuilder builder = new StringBuilder(); - builder.append(row[0]); + builder.append(row[0] + ""); for(int i = 1; i < size; i++) { - builder.append(this.sep).append(row[i]); + builder.append(this.sep).append(row[i] + ""); } builder.append("\n"); try { From 2c68449f6ee0f82919edc652dcacd78ed0a1ca9e Mon Sep 17 00:00:00 2001 From: kunalppatel9 Date: Thu, 14 May 2020 15:06:53 +0000 Subject: [PATCH 0588/1906] BUGFIX ::: adding in file creation checks as needed by fortify git-svn-id: svn://107.170.10.188:8080/Monolith/dev@38724 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 1548193fdd03a3c71b7c691ab004399f1df9ef4c --- .../insights/admin/DBAdminResource.java | 6 ++++- .../web/services/local/AppResource.java | 7 +++++- .../semoss/web/services/local/NameServer.java | 5 ++++- src/prerna/upload/FileUploader.java | 6 ++++- src/prerna/upload/ImageUploader.java | 22 +++++++++++++++---- src/prerna/upload/Uploader.java | 10 +++++++-- src/prerna/web/conf/util/UserFileLogUtil.java | 7 +++++- 7 files changed, 52 insertions(+), 11 deletions(-) diff --git a/src/prerna/insights/admin/DBAdminResource.java b/src/prerna/insights/admin/DBAdminResource.java index 85215ff02..084be201b 100644 --- a/src/prerna/insights/admin/DBAdminResource.java +++ b/src/prerna/insights/admin/DBAdminResource.java @@ -44,6 +44,7 @@ import org.apache.log4j.Logger; import prerna.rpa.RPAProps; +import prerna.util.Utility; import prerna.web.services.util.WebUtility; public class DBAdminResource { @@ -90,7 +91,10 @@ public Response unscheduleJob(MultivaluedMap form, @Context Http String jsonFilePath = jsonDirectory + fileName + ".json"; File file = new File(jsonFilePath); try { - file.delete(); + Boolean success = file.delete(); + if(!success) { + LOGGER.info("Unable to delete file at location: " + Utility.cleanLogString(jsonFilePath)); + } } catch (SecurityException e) { String errorMessage = "failed to delete file " + jsonFilePath + ": " + e.toString(); return WebUtility.getResponse(errorMessage.substring(0, diff --git a/src/prerna/semoss/web/services/local/AppResource.java b/src/prerna/semoss/web/services/local/AppResource.java index 75ea534c5..962ec706e 100644 --- a/src/prerna/semoss/web/services/local/AppResource.java +++ b/src/prerna/semoss/web/services/local/AppResource.java @@ -386,7 +386,12 @@ protected File getAppImageFile(String app) { } else { // make the image f = new File(fileLocation); - f.mkdirs(); + if(!f.exists()) { + Boolean success = f.mkdirs(); + if(!success) { + logger.info("Unable to make direction at location: " + Utility.cleanLogString(fileLocation)); + } + } fileLocation = fileLocation + DIR_SEPARATOR + "image.png"; if(app != null) { TextToGraphic.makeImage(app, fileLocation); diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index 5b6ecdec6..13eb0b5fe 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -1190,7 +1190,10 @@ private String createInsightTupleSpace(String baseFolder, String insightId) { String normalizedInsightSpecificFolder = Utility.normalizePath(insightSpecificFolder); File file = new File(normalizedInsightSpecificFolder); if (!file.exists()) { - file.mkdir(); + Boolean success = file.mkdir(); + if(!success) { + logger.info("Unable to created insight tuple space at: " + Utility.cleanLogString(normalizedInsightSpecificFolder)); + } String command = "addFolder@@" + normalizedInsightSpecificFolder; String normalizedCmdFilePath = Utility.normalizePath(baseFolder + "/" + insightId +".admin"); File cmdFile = new File(normalizedCmdFilePath); diff --git a/src/prerna/upload/FileUploader.java b/src/prerna/upload/FileUploader.java index b2260a70a..ea4525350 100644 --- a/src/prerna/upload/FileUploader.java +++ b/src/prerna/upload/FileUploader.java @@ -28,6 +28,7 @@ import prerna.om.InsightStore; import prerna.om.ThreadStore; import prerna.util.AssetUtility; +import prerna.util.Utility; import prerna.web.services.util.WebUtility; public class FileUploader extends Uploader { @@ -133,7 +134,10 @@ private List> getBaseUploadData(List fileItems, In } File fileDir = new File(filePath); if (!fileDir.exists()) { - fileDir.mkdirs(); + Boolean success =fileDir.mkdirs(); + if(!success) { + LOGGER.info("Unable to make direction at location: " + Utility.cleanLogString(filePath)); + } } Iterator iteratorFileItems = fileItems.iterator(); diff --git a/src/prerna/upload/ImageUploader.java b/src/prerna/upload/ImageUploader.java index 1fca80ef5..f72db80bb 100644 --- a/src/prerna/upload/ImageUploader.java +++ b/src/prerna/upload/ImageUploader.java @@ -32,6 +32,7 @@ import prerna.engine.impl.SmssUtilities; import prerna.nameserver.utility.MasterDatabaseUtility; import prerna.util.Constants; +import prerna.util.Utility; import prerna.web.services.util.WebUtility; public class ImageUploader extends Uploader { @@ -124,7 +125,10 @@ public Response uploadAppImage(@Context HttpServletRequest request) { } File f = new File(imageDir); if (!f.exists()) { - f.mkdirs(); + Boolean success = f.mkdirs(); + if(!success) { + logger.info("Unable to make direction at location: " + Utility.cleanLogString(filePath)); + } } f = new File(imageLoc); // find all the existing image files @@ -139,7 +143,10 @@ public Response uploadAppImage(@Context HttpServletRequest request) { // delete if any exist if (oldImages != null) { for (File oldI : oldImages) { - oldI.delete(); + Boolean success = oldI.delete(); + if (!success) { + logger.info("Unable to delete file at location: " + Utility.cleanLogString(oldI.getAbsolutePath())); + } } } writeFile(imageFile, f); @@ -239,7 +246,10 @@ public Response uploadInsightImage(@Context HttpServletRequest request) { + "version" + DIR_SEPARATOR + insightId; File f = new File(imageDir); if (!f.exists()) { - f.mkdirs(); + Boolean success = f.mkdirs(); + if(!success) { + logger.info("Unable to make direction at location: " + Utility.cleanLogString(imageDir)); + } } String imageLoc = imageDir + DIR_SEPARATOR + "image." + imageFile.getContentType().split("/")[1]; f = new File(imageLoc); @@ -249,7 +259,11 @@ public Response uploadInsightImage(@Context HttpServletRequest request) { // delete if any exist if (oldImages != null) { for (File oldI : oldImages) { - oldI.delete(); + Boolean success = oldI.delete(); + if(!success) { + logger.info("Unable to delete file at location: " + Utility.cleanLogString(oldI.getAbsolutePath())); + } + } } writeFile(imageFile, f); diff --git a/src/prerna/upload/Uploader.java b/src/prerna/upload/Uploader.java index 760fb1317..b56435d34 100644 --- a/src/prerna/upload/Uploader.java +++ b/src/prerna/upload/Uploader.java @@ -89,7 +89,10 @@ public void setFilePath(String filePath) { } File f = new File(this.filePath); if(!f.exists() && !f.isDirectory()) { - f.mkdirs(); + Boolean success = f.mkdirs(); + if(!success) { + logger.info("Unable to create file at: " + Utility.cleanLogString(f.getAbsolutePath())); + } } } @@ -101,7 +104,10 @@ public void setTempFilePath(String tempFilePath){ this.tempFilePath = normalizedTempFilePath; File tFile = new File(normalizedTempFilePath); if(!tFile.exists() && !tFile.isDirectory()) { - tFile.mkdirs(); + Boolean success = tFile.mkdirs(); + if(!success) { + logger.info("Unable to create file at: " + Utility.cleanLogString(tFile.getAbsolutePath())); + } } } diff --git a/src/prerna/web/conf/util/UserFileLogUtil.java b/src/prerna/web/conf/util/UserFileLogUtil.java index f87fcec11..022d4aa1e 100644 --- a/src/prerna/web/conf/util/UserFileLogUtil.java +++ b/src/prerna/web/conf/util/UserFileLogUtil.java @@ -11,6 +11,8 @@ import org.apache.log4j.LogManager; import org.apache.log4j.Logger; +import prerna.util.Utility; + public class UserFileLogUtil { private static Map singletonStore = new HashMap<>(); @@ -68,7 +70,10 @@ public FileAppender(String filePath, String sep, BlockingQueue queue) f = new File(this.filePath); if(!f.getParentFile().exists()) { - f.getParentFile().mkdirs(); + Boolean success = f.getParentFile().mkdirs(); + if(!success) { + logger.info("Unable to create file appender at :" + Utility.cleanLogString(f.getAbsolutePath())); + } } // set to append mode From 8bfa12885785a26f0ce2c1050d074243140dfe7b Mon Sep 17 00:00:00 2001 From: kunalppatel9 Date: Thu, 14 May 2020 17:00:46 +0000 Subject: [PATCH 0589/1906] BUGFIX ::: removing printing stacktrace for logging them BUGFIX ::: adding in additoinal null checks git-svn-id: svn://107.170.10.188:8080/Monolith/dev@38728 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 8deda499778bebc31c45a1b8ee7b187fd9fbba18 --- .../cluster/RawSelectWrapperService.java | 21 ++++++++------- .../web/services/local/ResourceUtility.java | 2 +- .../web/services/local/UserResource.java | 27 ++++++++++--------- src/prerna/upload/FileUploader.java | 12 ++++----- src/prerna/web/conf/util/CACTrackingUtil.java | 13 ++++++--- 5 files changed, 41 insertions(+), 34 deletions(-) diff --git a/src/prerna/cluster/RawSelectWrapperService.java b/src/prerna/cluster/RawSelectWrapperService.java index 5edea119e..9465ec36b 100644 --- a/src/prerna/cluster/RawSelectWrapperService.java +++ b/src/prerna/cluster/RawSelectWrapperService.java @@ -143,7 +143,7 @@ public Response execute(@Context HttpServletRequest request) { String wrapperId = request.getParameter(WRAPPER_ID); String query = request.getParameter(QUERY); - Hashtable ret = new Hashtable(); + Hashtable ret = new Hashtable<>(); // Perform action IRawSelectWrapper wrapper = null; @@ -200,7 +200,7 @@ public Response setQuery(@Context HttpServletRequest request) { } // Set return values - Hashtable ret = new Hashtable(); + Hashtable ret = new Hashtable<>(); ret.put("success", true); ret.put("appId", appId); ret.put("wrapperId", wrapperId); @@ -228,6 +228,10 @@ public Response cleanUp(@Context HttpServletRequest request) { String appId = request.getParameter(APP_ID); String wrapperId = request.getParameter(WRAPPER_ID); + if (appId == null) { + throw new IllegalArgumentException("App id cannot be null here, must define app id"); + } + // Perform action IRawSelectWrapper wrapper = null; try { @@ -242,7 +246,7 @@ public Response cleanUp(@Context HttpServletRequest request) { boolean removed = removeRawSelectWrapper(appId, wrapperId); // Also remove from active list // Set return values - Hashtable ret = new Hashtable(); + Hashtable ret = new Hashtable<>(); ret.put("success", true); ret.put("appId", appId); ret.put("wrapperId", wrapperId); @@ -286,7 +290,7 @@ public Response setEngine(@Context HttpServletRequest request) { } // Set return values - Hashtable ret = new Hashtable(); + Hashtable ret = new Hashtable<>(); ret.put("success", true); ret.put("appId", appId); ret.put("wrapperId", wrapperId); @@ -386,7 +390,6 @@ public Response getHeaders(@Context HttpServletRequest request) { wrapper = getRawSelectWrapper(appId, wrapperId); headers = wrapper.getHeaders(); } catch (Exception e) { - // TODO Auto-generated catch block logger.error(STACKTRACE,e); } @@ -454,7 +457,7 @@ public Response getNumRecords(@Context HttpServletRequest request) { numRecords = wrapper.getNumRecords(); } catch (Exception e) { logger.error(STACKTRACE,e); - Hashtable ret = new Hashtable(); + Hashtable ret = new Hashtable<>(); ret.put("errorMessage", e.getMessage()); return WebUtility.getResponse(ret, 400); } @@ -489,7 +492,7 @@ public Response getNumRows(@Context HttpServletRequest request) { wrapper = getRawSelectWrapper(appId, wrapperId); numRecords = wrapper.getNumRows(); } catch (Exception e) { - Hashtable ret = new Hashtable(); + Hashtable ret = new Hashtable<>(); ret.put("errorMessage", e.getMessage()); return WebUtility.getResponse(ret, 400); } @@ -517,7 +520,7 @@ public Response reset(@Context HttpServletRequest request) { String appId = request.getParameter(APP_ID); String wrapperId = request.getParameter(WRAPPER_ID); - Hashtable ret = new Hashtable(); + Hashtable ret = new Hashtable<>(); // Perform action IRawSelectWrapper wrapper = null; @@ -540,13 +543,11 @@ public Response reset(@Context HttpServletRequest request) { @Override public boolean flushable() { - // TODO Auto-generated method stub return false; } @Override public String flush() { - // TODO Auto-generated method stub return null; } diff --git a/src/prerna/semoss/web/services/local/ResourceUtility.java b/src/prerna/semoss/web/services/local/ResourceUtility.java index 814b13616..ae69d1906 100644 --- a/src/prerna/semoss/web/services/local/ResourceUtility.java +++ b/src/prerna/semoss/web/services/local/ResourceUtility.java @@ -11,7 +11,7 @@ public class ResourceUtility { - public static String ERROR_KEY = "errorMessage"; + public static final String ERROR_KEY = "errorMessage"; /** * Get the user diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index fd50baf66..b2a058740 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -122,7 +122,7 @@ public class UserResource { private static final String STACKTRACE = "StackTrace: "; private static Properties socialData = null; - private static Map loginsAllowed; + private static Map loginsAllowedMap; static { loadSocialProperties(); @@ -173,18 +173,18 @@ private static void setLoginsAllowed() { boolean dropboxLogin = Boolean.parseBoolean(socialData.getProperty("dropbox_login")); boolean cacLogin = Boolean.parseBoolean(socialData.getProperty("cac_login")); boolean registration = Boolean.parseBoolean(socialData.getProperty("native_registration")); - UserResource.loginsAllowed = new HashMap<>(); - UserResource.loginsAllowed.put("native", nativeLogin); - UserResource.loginsAllowed.put("google", googleLogin); - UserResource.loginsAllowed.put("github", githubLogin); - UserResource.loginsAllowed.put("ms", onedriveLogin); - UserResource.loginsAllowed.put("dropbox", dropboxLogin); - UserResource.loginsAllowed.put("cac", cacLogin); - UserResource.loginsAllowed.put("registration", registration); + UserResource.loginsAllowedMap = new HashMap<>(); + UserResource.loginsAllowedMap.put("native", nativeLogin); + UserResource.loginsAllowedMap.put("google", googleLogin); + UserResource.loginsAllowedMap.put("github", githubLogin); + UserResource.loginsAllowedMap.put("ms", onedriveLogin); + UserResource.loginsAllowedMap.put("dropbox", dropboxLogin); + UserResource.loginsAllowedMap.put("cac", cacLogin); + UserResource.loginsAllowedMap.put("registration", registration); } public static Map getLoginsAllowed() { - return UserResource.loginsAllowed; + return UserResource.loginsAllowedMap; } @GET @@ -1264,6 +1264,7 @@ public Response loginIn(@Context HttpServletRequest request, @Context HttpServle if (userObj == null || userObj.getAccessToken(AuthProvider.IN) == null) { response.setStatus(302); response.sendRedirect(getInRedirect(request)); + return null; } setMainPageRedirect(request, response); @@ -1359,7 +1360,7 @@ private String getTwitterRedirect(HttpServletRequest request) throws Unsupported String prefix = "twitter_"; String clientId = socialData.getProperty(prefix + "client_id"); - String clientSecret = socialData.getProperty(prefix + "secret_key"); + //String clientSecret = socialData.getProperty(prefix + "secret_key"); String redirectUri = socialData.getProperty(prefix + "redirect_uri"); String scope = socialData.getProperty(prefix + "scope"); String nonce = UUID.randomUUID().toString(); @@ -1374,7 +1375,7 @@ private String getTwitterRedirect(HttpServletRequest request) throws Unsupported parameterString.append("oauth_nonce=").append(nonce).append("&"); parameterString.append("oauth_timestamp=").append(timestamp); - String finalString = signatureString.toString() + parameterString.toString(); + //String finalString = signatureString.toString() + parameterString.toString(); // String signature = @@ -1546,7 +1547,7 @@ public Response createUser(@Context HttpServletRequest request) { @Produces("application/json") @Path("/loginsAllowed/") public Response loginsAllowed(@Context HttpServletRequest request) throws IOException { - return WebUtility.getResponse(UserResource.loginsAllowed, 200); + return WebUtility.getResponse(UserResource.loginsAllowedMap, 200); } @GET diff --git a/src/prerna/upload/FileUploader.java b/src/prerna/upload/FileUploader.java index ea4525350..29a036848 100644 --- a/src/prerna/upload/FileUploader.java +++ b/src/prerna/upload/FileUploader.java @@ -33,7 +33,7 @@ public class FileUploader extends Uploader { - private static final Logger LOGGER = LogManager.getLogger(FileUploader.class); + private static final Logger logger = LogManager.getLogger(FileUploader.class); /* * Moving a file onto the BE cannot be performed through pixel * Thus, we still expose "drag and drop" of a file through a rest call @@ -101,7 +101,7 @@ public Response uploadFile(@Context HttpServletRequest request, @QueryParam("ins // clear the thread store return WebUtility.getResponse(inputData, 200); } catch(Exception e) { - e.printStackTrace(); + logger.error("STACKTRACE: ", e); HashMap errorMap = new HashMap(); errorMap.put("errorMessage", "Error moving file to server"); return WebUtility.getResponse(errorMap, 400); @@ -136,7 +136,7 @@ private List> getBaseUploadData(List fileItems, In if (!fileDir.exists()) { Boolean success =fileDir.mkdirs(); if(!success) { - LOGGER.info("Unable to make direction at location: " + Utility.cleanLogString(filePath)); + logger.info("Unable to make direction at location: " + Utility.cleanLogString(filePath)); } } @@ -183,7 +183,7 @@ private List> getBaseUploadData(List fileItems, In // we will do what a normal OS system does writeFile(fi, file); - LOGGER.info("Saved Filename: " + name + " to "+ file); + logger.info("Saved Filename: " + name + " to "+ file); String savedName = FilenameUtils.getName(fileLocation); Map fileMap = new HashMap(); @@ -194,7 +194,7 @@ private List> getBaseUploadData(List fileItems, In // its a file, but not in a form // i.e. this is a person copy/pasting // the values directly - LOGGER.info("Writing Input To File"); + logger.info("Writing Input To File"); // Date date = new Date(); // String modifiedDate = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_SSSS").format(date); @@ -204,7 +204,7 @@ private List> getBaseUploadData(List fileItems, In String fileLocation = getUniquePath(filePath, "AutoGeneratedFile.txt"); File file = new File(fileLocation); writeFile(fi, file); - LOGGER.info("Saved Pasted Data To "+ file); + logger.info("Saved Pasted Data To "+ file); String savedName = FilenameUtils.getName(fileLocation); Map fileMap = new HashMap(); diff --git a/src/prerna/web/conf/util/CACTrackingUtil.java b/src/prerna/web/conf/util/CACTrackingUtil.java index ecd6deee0..2444e317d 100644 --- a/src/prerna/web/conf/util/CACTrackingUtil.java +++ b/src/prerna/web/conf/util/CACTrackingUtil.java @@ -6,6 +6,9 @@ import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; +import org.apache.log4j.LogManager; +import org.apache.log4j.Logger; + import prerna.engine.api.IEngine; import prerna.engine.api.IRawSelectWrapper; import prerna.rdf.engine.wrappers.WrapperManager; @@ -53,6 +56,7 @@ class CountUpdater implements Runnable { private static final String COUNT_COL = "USER_COUNT"; private static final String DATE_COL = "DATE_RECORDED"; private static final String GET_LATEST_DATE_QUERY = "SELECT MAX(" + DATE_COL + ") FROM " + TABLE; + private static final Logger logger = LogManager.getLogger(CountUpdater.class); // this is how we will keep the last date so we // do not need to query if this date exists every time @@ -85,7 +89,7 @@ public CountUpdater(IEngine engine, BlockingQueue queue) { } } } catch (Exception e) { - e.printStackTrace(); + logger.error("STACKTRACE: ",e); } finally { if(wrapper != null) { wrapper.cleanUp(); @@ -107,7 +111,7 @@ public void run() { try { engine.insertData(insertQuery); } catch (Exception e) { - e.printStackTrace(); + logger.error("STACKTRACE: ",e); } // and we will set the query up for the rest of the @@ -122,14 +126,15 @@ public void run() { try { engine.insertData(this.updateQuery); } catch (Exception e) { - e.printStackTrace(); + + logger.error("STACKTRACE: ",e); } } engine.commit(); } } catch (InterruptedException e) { - e.printStackTrace(); + logger.error("STACKTRACE: ",e); } } From 5dab7821138587a639d943b2492c15938ef0e60c Mon Sep 17 00:00:00 2001 From: kunalppatel9 Date: Thu, 14 May 2020 21:15:50 +0000 Subject: [PATCH 0590/1906] BUGFIX ::: commenting out testing methods. Many of the system prints, reads, paths, main methods are contriubting to fortify issues git-svn-id: svn://107.170.10.188:8080/Monolith/dev@38730 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 40a841e8234b71a79429214102c9f580df4249b4 --- src/prerna/auth/CACReader.java | 332 +++++++++++++++---------------- src/prerna/auth/PIVReader.java | 354 ++++++++++++++++----------------- 2 files changed, 343 insertions(+), 343 deletions(-) diff --git a/src/prerna/auth/CACReader.java b/src/prerna/auth/CACReader.java index 455d9a942..efe995d78 100644 --- a/src/prerna/auth/CACReader.java +++ b/src/prerna/auth/CACReader.java @@ -1,166 +1,166 @@ -package prerna.auth; - -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; -import java.io.InputStreamReader; -import java.security.KeyStore; -import java.security.Provider; -import java.security.Security; -import java.security.cert.CertificateParsingException; -import java.security.cert.X509Certificate; -import java.util.Enumeration; -import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import javax.naming.InvalidNameException; -import javax.naming.ldap.LdapName; -import javax.naming.ldap.Rdn; -import javax.smartcardio.Card; -import javax.smartcardio.CardTerminal; -import javax.smartcardio.TerminalFactory; - -import prerna.test.TestUtilityMethods; -import prerna.util.DIHelper; -import sun.security.pkcs11.SunPKCS11; - -public class CACReader { - - public static void main(String[] args) { - TestUtilityMethods.loadDIHelper("C:\\workspace\\Semoss_Dev\\RDF_Map.prop"); - - try { - BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); - System.out.print("Enter PIN: "); - String pin = reader.readLine(); - reader.close(); - - CACReader t = new CACReader(); - - t.showTerminals(); - t.processCAC(pin); - } catch (Exception e) { - e.printStackTrace(); - } - } - - public void processCAC(String pin) { - if(pin == null || pin.isEmpty()) { - return; - } - - try { - /* - * Load the information to get the CAC data - */ - String config = "showInfo = true" - + "\nlibrary = " + DIHelper.getInstance().getProperty("BaseFolder") + "\\config\\CACauth\\opensc-pkcs11.dll" - + "\nname = SmartCard"; - SunPKCS11 providerMSCAPI = new SunPKCS11(new ByteArrayInputStream(config.getBytes("UTF-8"))); - Provider p = providerMSCAPI; - Security.addProvider(p); - - KeyStore keyStore = KeyStore.getInstance("PKCS11", p); - KeyStore.PasswordProtection pp = new KeyStore.PasswordProtection(pin.toCharArray()); - keyStore.load(null, pp.getPassword()); - - System.out.println("-----------------------"); - System.out.println("-----------------------"); - System.out.println("-----------------------"); - System.out.println("STARTING PROCESS"); - System.out.println("-----------------------"); - System.out.println("-----------------------"); - System.out.println("-----------------------"); - Enumeration xaliasesEnum = keyStore.aliases(); - while (xaliasesEnum.hasMoreElements()) { - Object alias = xaliasesEnum.nextElement(); - try { - X509Certificate cert = (X509Certificate) keyStore.getCertificate(alias.toString()); - - String fullName = cert.getSubjectX500Principal().getName(); - System.out.println("-----------------------"); - System.out.println("PROCESSING CERT >>>"); - System.out.println("REQUEST COMING FROM " + fullName); - LdapName ldapDN; - try { - ldapDN = new LdapName(fullName); - for(Rdn rdn: ldapDN.getRdns()) { - if(rdn.getType().equals("CN")) { - String value = rdn.getValue().toString(); - - String[] split = value.split("\\."); - if(split.length > 3) { - // no idea if middle name is always there or not - // just gonna validate the cac has length 10 - String cacId = split[split.length-1]; - if(cacId.length() >= 10) { - // valid CAC!!! - System.out.println("I HAVE CAC ID :::: " + cacId); - System.out.println("I HAVE NAME :::: " + Stream.of(split).limit(split.length-2).collect(Collectors.joining(" "))); - System.out.println("I HAVE TYPE :::: " + cert.getIssuerDN().getName()); - System.out.println("I HAVE EXPIRATION :::: " + (int) cert.getNotAfter().getTime()); - - // try to get the email - try { - EMAIL_LOOP : for(List altNames : cert.getSubjectAlternativeNames()) { - for(Object alternative : altNames) { - if(alternative instanceof String) { - String altStr = alternative.toString(); - // really simple email check... - if(altStr.contains("@")) { - System.out.println("I HAVE EMAIL :::: " + altStr); - break EMAIL_LOOP; - } - } - } - } - } catch (CertificateParsingException e) { - e.printStackTrace(); - } - } else { - System.out.println("IGNORE THIS VALUE ::: " + value + " , WITH CAC ID ::: " + cacId); - continue; - } - } else { - System.out.println("IGNORE THIS VALUE ::: " + value); - continue; - } - } - } - System.out.println("COMPLETED PROCESSING CERT >>>"); - } catch (InvalidNameException e) { - System.out.println("ERROR WITH PARSING CAC INFORMATION!"); - e.printStackTrace(); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - } catch(Exception e) { - e.printStackTrace(); - } - - System.out.println("-----------------------"); - System.out.println("-----------------------"); - System.out.println("-----------------------"); - System.out.println("FINISHED PROCESS"); - } - - public void showTerminals() { - try { - // Display the list of terminals - TerminalFactory factory = TerminalFactory.getDefault(); - List terminals = factory.terminals().list(); - System.out.println("Terminals: " + terminals); - - // Use the first terminal - CardTerminal terminal = terminals.get(0); - - // Connect with the card - Card card = terminal.connect("*"); - System.out.println("Card: " + card); - } catch(Exception e) { - e.printStackTrace(); - } - } -} +//package prerna.auth; +// +//import java.io.BufferedReader; +//import java.io.ByteArrayInputStream; +//import java.io.InputStreamReader; +//import java.security.KeyStore; +//import java.security.Provider; +//import java.security.Security; +//import java.security.cert.CertificateParsingException; +//import java.security.cert.X509Certificate; +//import java.util.Enumeration; +//import java.util.List; +//import java.util.stream.Collectors; +//import java.util.stream.Stream; +// +//import javax.naming.InvalidNameException; +//import javax.naming.ldap.LdapName; +//import javax.naming.ldap.Rdn; +//import javax.smartcardio.Card; +//import javax.smartcardio.CardTerminal; +//import javax.smartcardio.TerminalFactory; +// +//import prerna.test.TestUtilityMethods; +//import prerna.util.DIHelper; +//import sun.security.pkcs11.SunPKCS11; +// +//public class CACReader { +// +// public static void main(String[] args) { +// TestUtilityMethods.loadDIHelper("C:\\workspace\\Semoss_Dev\\RDF_Map.prop"); +// +// try { +// BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); +// System.out.print("Enter PIN: "); +// String pin = reader.readLine(); +// reader.close(); +// +// CACReader t = new CACReader(); +// +// t.showTerminals(); +// t.processCAC(pin); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +// +// public void processCAC(String pin) { +// if(pin == null || pin.isEmpty()) { +// return; +// } +// +// try { +// /* +// * Load the information to get the CAC data +// */ +// String config = "showInfo = true" +// + "\nlibrary = " + DIHelper.getInstance().getProperty("BaseFolder") + "\\config\\CACauth\\opensc-pkcs11.dll" +// + "\nname = SmartCard"; +// SunPKCS11 providerMSCAPI = new SunPKCS11(new ByteArrayInputStream(config.getBytes("UTF-8"))); +// Provider p = providerMSCAPI; +// Security.addProvider(p); +// +// KeyStore keyStore = KeyStore.getInstance("PKCS11", p); +// KeyStore.PasswordProtection pp = new KeyStore.PasswordProtection(pin.toCharArray()); +// keyStore.load(null, pp.getPassword()); +// +// System.out.println("-----------------------"); +// System.out.println("-----------------------"); +// System.out.println("-----------------------"); +// System.out.println("STARTING PROCESS"); +// System.out.println("-----------------------"); +// System.out.println("-----------------------"); +// System.out.println("-----------------------"); +// Enumeration xaliasesEnum = keyStore.aliases(); +// while (xaliasesEnum.hasMoreElements()) { +// Object alias = xaliasesEnum.nextElement(); +// try { +// X509Certificate cert = (X509Certificate) keyStore.getCertificate(alias.toString()); +// +// String fullName = cert.getSubjectX500Principal().getName(); +// System.out.println("-----------------------"); +// System.out.println("PROCESSING CERT >>>"); +// System.out.println("REQUEST COMING FROM " + fullName); +// LdapName ldapDN; +// try { +// ldapDN = new LdapName(fullName); +// for(Rdn rdn: ldapDN.getRdns()) { +// if(rdn.getType().equals("CN")) { +// String value = rdn.getValue().toString(); +// +// String[] split = value.split("\\."); +// if(split.length > 3) { +// // no idea if middle name is always there or not +// // just gonna validate the cac has length 10 +// String cacId = split[split.length-1]; +// if(cacId.length() >= 10) { +// // valid CAC!!! +// System.out.println("I HAVE CAC ID :::: " + cacId); +// System.out.println("I HAVE NAME :::: " + Stream.of(split).limit(split.length-2).collect(Collectors.joining(" "))); +// System.out.println("I HAVE TYPE :::: " + cert.getIssuerDN().getName()); +// System.out.println("I HAVE EXPIRATION :::: " + (int) cert.getNotAfter().getTime()); +// +// // try to get the email +// try { +// EMAIL_LOOP : for(List altNames : cert.getSubjectAlternativeNames()) { +// for(Object alternative : altNames) { +// if(alternative instanceof String) { +// String altStr = alternative.toString(); +// // really simple email check... +// if(altStr.contains("@")) { +// System.out.println("I HAVE EMAIL :::: " + altStr); +// break EMAIL_LOOP; +// } +// } +// } +// } +// } catch (CertificateParsingException e) { +// e.printStackTrace(); +// } +// } else { +// System.out.println("IGNORE THIS VALUE ::: " + value + " , WITH CAC ID ::: " + cacId); +// continue; +// } +// } else { +// System.out.println("IGNORE THIS VALUE ::: " + value); +// continue; +// } +// } +// } +// System.out.println("COMPLETED PROCESSING CERT >>>"); +// } catch (InvalidNameException e) { +// System.out.println("ERROR WITH PARSING CAC INFORMATION!"); +// e.printStackTrace(); +// } +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +// } catch(Exception e) { +// e.printStackTrace(); +// } +// +// System.out.println("-----------------------"); +// System.out.println("-----------------------"); +// System.out.println("-----------------------"); +// System.out.println("FINISHED PROCESS"); +// } +// +// public void showTerminals() { +// try { +// // Display the list of terminals +// TerminalFactory factory = TerminalFactory.getDefault(); +// List terminals = factory.terminals().list(); +// System.out.println("Terminals: " + terminals); +// +// // Use the first terminal +// CardTerminal terminal = terminals.get(0); +// +// // Connect with the card +// Card card = terminal.connect("*"); +// System.out.println("Card: " + card); +// } catch(Exception e) { +// e.printStackTrace(); +// } +// } +//} diff --git a/src/prerna/auth/PIVReader.java b/src/prerna/auth/PIVReader.java index ba7812280..9ef9bd515 100644 --- a/src/prerna/auth/PIVReader.java +++ b/src/prerna/auth/PIVReader.java @@ -1,179 +1,179 @@ -package prerna.auth; - -import java.io.BufferedReader; -import java.io.ByteArrayInputStream; -import java.io.InputStreamReader; -import java.security.KeyStore; -import java.security.Provider; -import java.security.Security; -import java.security.cert.CertificateParsingException; -import java.security.cert.X509Certificate; -import java.util.Enumeration; -import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import javax.naming.InvalidNameException; -import javax.naming.ldap.LdapName; -import javax.naming.ldap.Rdn; -import javax.smartcardio.Card; -import javax.smartcardio.CardTerminal; -import javax.smartcardio.TerminalFactory; - -import prerna.test.TestUtilityMethods; -import prerna.util.DIHelper; -import sun.security.pkcs11.SunPKCS11; - -public class PIVReader { - - public static void main(String[] args) { - TestUtilityMethods.loadDIHelper("C:\\workspace\\Semoss_Dev\\RDF_Map.prop"); - - try { - BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); - System.out.print("Enter PIN: "); - String pin = reader.readLine(); - reader.close(); - - PIVReader t = new PIVReader(); - - t.showTerminals(); - t.processCAC(pin); - } catch (Exception e) { - e.printStackTrace(); - } - } - - public void processCAC(String pin) { - if(pin == null || pin.isEmpty()) { - return; - } - - try { - /* - * Load the information to get the CAC data - */ - String config = "showInfo = true" - + "\nlibrary = " + DIHelper.getInstance().getProperty("BaseFolder") + "\\config\\CACauth\\opensc-pkcs11.dll" - + "\nname = SmartCard"; - SunPKCS11 providerMSCAPI = new SunPKCS11(new ByteArrayInputStream(config.getBytes("UTF-8"))); - Provider p = providerMSCAPI; - Security.addProvider(p); - - KeyStore keyStore = KeyStore.getInstance("PKCS11", p); - KeyStore.PasswordProtection pp = new KeyStore.PasswordProtection(pin.toCharArray()); - keyStore.load(null, pp.getPassword()); - - System.out.println("-----------------------"); - System.out.println("-----------------------"); - System.out.println("-----------------------"); - System.out.println("STARTING PROCESS"); - System.out.println("-----------------------"); - System.out.println("-----------------------"); - System.out.println("-----------------------"); - Enumeration xaliasesEnum = keyStore.aliases(); - while (xaliasesEnum.hasMoreElements()) { - Object alias = xaliasesEnum.nextElement(); - try { - X509Certificate cert = (X509Certificate) keyStore.getCertificate(alias.toString()); - - String fullName = cert.getSubjectX500Principal().getName(); - System.out.println("-----------------------"); - System.out.println("PROCESSING CERT >>>"); - System.out.println("REQUEST COMING FROM " + fullName); - LdapName ldapDN; - try { - ldapDN = new LdapName(fullName); - for(Rdn rdn: ldapDN.getRdns()) { - if(rdn.getType().equals("UID")) { - System.out.println(rdn.getValue().toString()); - System.out.println(rdn.getValue().toString()); - System.out.println(rdn.getValue().toString()); - System.out.println(rdn.getValue().toString()); - System.out.println(rdn.getValue().toString()); - System.out.println(rdn.getValue().toString()); - } - -// if(rdn.getType().equals("CN")) { -// String value = rdn.getValue().toString(); -// -// System.out.println(value); -// System.out.println(value); -// System.out.println(value); -// System.out.println(value); -// String[] split = value.split("\\."); -// if(split.length > 3) { -// // no idea if middle name is always there or not -// // just gonna validate the cac has length 10 -// String cacId = split[split.length-1]; -// if(cacId.length() >= 10) { -// // valid CAC!!! -// System.out.println("I HAVE CAC ID :::: " + cacId); -// System.out.println("I HAVE NAME :::: " + Stream.of(split).limit(split.length-2).collect(Collectors.joining(" "))); -// System.out.println("I HAVE TYPE :::: " + cert.getIssuerDN().getName()); -// System.out.println("I HAVE EXPIRATION :::: " + (int) cert.getNotAfter().getTime()); +//package prerna.auth; // -// // try to get the email -// try { -// EMAIL_LOOP : for(List altNames : cert.getSubjectAlternativeNames()) { -// for(Object alternative : altNames) { -// if(alternative instanceof String) { -// String altStr = alternative.toString(); -// // really simple email check... -// if(altStr.contains("@")) { -// System.out.println("I HAVE EMAIL :::: " + altStr); -// break EMAIL_LOOP; -// } -// } -// } -// } -// } catch (CertificateParsingException e) { -// e.printStackTrace(); -// } -// } else { -// System.out.println("IGNORE THIS VALUE ::: " + value + " , WITH CAC ID ::: " + cacId); -// continue; -// } -// } else { -// System.out.println("IGNORE THIS VALUE ::: " + value); -// continue; -// } +//import java.io.BufferedReader; +//import java.io.ByteArrayInputStream; +//import java.io.InputStreamReader; +//import java.security.KeyStore; +//import java.security.Provider; +//import java.security.Security; +//import java.security.cert.CertificateParsingException; +//import java.security.cert.X509Certificate; +//import java.util.Enumeration; +//import java.util.List; +//import java.util.stream.Collectors; +//import java.util.stream.Stream; +// +//import javax.naming.InvalidNameException; +//import javax.naming.ldap.LdapName; +//import javax.naming.ldap.Rdn; +//import javax.smartcardio.Card; +//import javax.smartcardio.CardTerminal; +//import javax.smartcardio.TerminalFactory; +// +//import prerna.test.TestUtilityMethods; +//import prerna.util.DIHelper; +//import sun.security.pkcs11.SunPKCS11; +// +//public class PIVReader { +// +// public static void main(String[] args) { +// TestUtilityMethods.loadDIHelper("C:\\workspace\\Semoss_Dev\\RDF_Map.prop"); +// +// try { +// BufferedReader reader = new BufferedReader(new InputStreamReader(System.in)); +// System.out.print("Enter PIN: "); +// String pin = reader.readLine(); +// reader.close(); +// +// PIVReader t = new PIVReader(); +// +// t.showTerminals(); +// t.processCAC(pin); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +// +// public void processCAC(String pin) { +// if(pin == null || pin.isEmpty()) { +// return; +// } +// +// try { +// /* +// * Load the information to get the CAC data +// */ +// String config = "showInfo = true" +// + "\nlibrary = " + DIHelper.getInstance().getProperty("BaseFolder") + "\\config\\CACauth\\opensc-pkcs11.dll" +// + "\nname = SmartCard"; +// SunPKCS11 providerMSCAPI = new SunPKCS11(new ByteArrayInputStream(config.getBytes("UTF-8"))); +// Provider p = providerMSCAPI; +// Security.addProvider(p); +// +// KeyStore keyStore = KeyStore.getInstance("PKCS11", p); +// KeyStore.PasswordProtection pp = new KeyStore.PasswordProtection(pin.toCharArray()); +// keyStore.load(null, pp.getPassword()); +// +// System.out.println("-----------------------"); +// System.out.println("-----------------------"); +// System.out.println("-----------------------"); +// System.out.println("STARTING PROCESS"); +// System.out.println("-----------------------"); +// System.out.println("-----------------------"); +// System.out.println("-----------------------"); +// Enumeration xaliasesEnum = keyStore.aliases(); +// while (xaliasesEnum.hasMoreElements()) { +// Object alias = xaliasesEnum.nextElement(); +// try { +// X509Certificate cert = (X509Certificate) keyStore.getCertificate(alias.toString()); +// +// String fullName = cert.getSubjectX500Principal().getName(); +// System.out.println("-----------------------"); +// System.out.println("PROCESSING CERT >>>"); +// System.out.println("REQUEST COMING FROM " + fullName); +// LdapName ldapDN; +// try { +// ldapDN = new LdapName(fullName); +// for(Rdn rdn: ldapDN.getRdns()) { +// if(rdn.getType().equals("UID")) { +// System.out.println(rdn.getValue().toString()); +// System.out.println(rdn.getValue().toString()); +// System.out.println(rdn.getValue().toString()); +// System.out.println(rdn.getValue().toString()); +// System.out.println(rdn.getValue().toString()); +// System.out.println(rdn.getValue().toString()); // } - } - System.out.println("COMPLETED PROCESSING CERT >>>"); - } catch (InvalidNameException e) { - System.out.println("ERROR WITH PARSING CAC INFORMATION!"); - e.printStackTrace(); - } - } catch (Exception e) { - e.printStackTrace(); - } - } - } catch(Exception e) { - e.printStackTrace(); - } - - System.out.println("-----------------------"); - System.out.println("-----------------------"); - System.out.println("-----------------------"); - System.out.println("FINISHED PROCESS"); - } - - public void showTerminals() { - try { - // Display the list of terminals - TerminalFactory factory = TerminalFactory.getDefault(); - List terminals = factory.terminals().list(); - System.out.println("Terminals: " + terminals); - - // Use the first terminal - CardTerminal terminal = terminals.get(0); - - // Connect with the card - Card card = terminal.connect("*"); - System.out.println("Card: " + card); - } catch(Exception e) { - e.printStackTrace(); - } - } -} +// +//// if(rdn.getType().equals("CN")) { +//// String value = rdn.getValue().toString(); +//// +//// System.out.println(value); +//// System.out.println(value); +//// System.out.println(value); +//// System.out.println(value); +//// String[] split = value.split("\\."); +//// if(split.length > 3) { +//// // no idea if middle name is always there or not +//// // just gonna validate the cac has length 10 +//// String cacId = split[split.length-1]; +//// if(cacId.length() >= 10) { +//// // valid CAC!!! +//// System.out.println("I HAVE CAC ID :::: " + cacId); +//// System.out.println("I HAVE NAME :::: " + Stream.of(split).limit(split.length-2).collect(Collectors.joining(" "))); +//// System.out.println("I HAVE TYPE :::: " + cert.getIssuerDN().getName()); +//// System.out.println("I HAVE EXPIRATION :::: " + (int) cert.getNotAfter().getTime()); +//// +//// // try to get the email +//// try { +//// EMAIL_LOOP : for(List altNames : cert.getSubjectAlternativeNames()) { +//// for(Object alternative : altNames) { +//// if(alternative instanceof String) { +//// String altStr = alternative.toString(); +//// // really simple email check... +//// if(altStr.contains("@")) { +//// System.out.println("I HAVE EMAIL :::: " + altStr); +//// break EMAIL_LOOP; +//// } +//// } +//// } +//// } +//// } catch (CertificateParsingException e) { +//// e.printStackTrace(); +//// } +//// } else { +//// System.out.println("IGNORE THIS VALUE ::: " + value + " , WITH CAC ID ::: " + cacId); +//// continue; +//// } +//// } else { +//// System.out.println("IGNORE THIS VALUE ::: " + value); +//// continue; +//// } +//// } +// } +// System.out.println("COMPLETED PROCESSING CERT >>>"); +// } catch (InvalidNameException e) { +// System.out.println("ERROR WITH PARSING CAC INFORMATION!"); +// e.printStackTrace(); +// } +// } catch (Exception e) { +// e.printStackTrace(); +// } +// } +// } catch(Exception e) { +// e.printStackTrace(); +// } +// +// System.out.println("-----------------------"); +// System.out.println("-----------------------"); +// System.out.println("-----------------------"); +// System.out.println("FINISHED PROCESS"); +// } +// +// public void showTerminals() { +// try { +// // Display the list of terminals +// TerminalFactory factory = TerminalFactory.getDefault(); +// List terminals = factory.terminals().list(); +// System.out.println("Terminals: " + terminals); +// +// // Use the first terminal +// CardTerminal terminal = terminals.get(0); +// +// // Connect with the card +// Card card = terminal.connect("*"); +// System.out.println("Card: " + card); +// } catch(Exception e) { +// e.printStackTrace(); +// } +// } +//} From f2612ec9ba64820033c6d23d53061c86da06974e Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 15 May 2020 14:40:30 +0000 Subject: [PATCH 0591/1906] UPDATE ::: Adding an errorType for insight not found to hopefully be used by the FE to re-initalize the base semoss insight they use for querying information git-svn-id: svn://107.170.10.188:8080/Monolith/dev@38740 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 0a49f33bde1cdf6076b7e72a732ef1c28f82b356 --- src/prerna/semoss/web/services/local/NameServer.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index 13eb0b5fe..4036e5a6e 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -122,6 +122,8 @@ public class NameServer { private static final Logger logger = LogManager.getLogger(NameServer.class); private static final String ERROR_MESSAGE = "errorMessage"; + private static final String ERROR_TYPE = "errorType"; + private static final String INSIGHT_NOT_FOUND = "INSIGHT_NOT_FOUND"; private static final String STACKTRACE = "StackTrace: "; // get the directory separator protected static final String DIR_SEPARATOR = java.nio.file.FileSystems.getDefault().getSeparator(); @@ -408,6 +410,7 @@ public Response runPixelSync(@Context HttpServletRequest request) { if (insight == null) { Map errorMap = new HashMap<>(); errorMap.put(ERROR_MESSAGE, "Could not find the insight id"); + errorMap.put(ERROR_TYPE, INSIGHT_NOT_FOUND); return WebUtility.getResponse(errorMap, 400); } } @@ -454,6 +457,7 @@ public Response getPixelPipelinePlan(@Context HttpServletRequest request) { if (insight == null) { Map errorMap = new HashMap<>(); errorMap.put(ERROR_MESSAGE, "Could not find the insight id"); + errorMap.put(ERROR_TYPE, INSIGHT_NOT_FOUND); return WebUtility.getResponse(errorMap, 400); } @@ -616,6 +620,7 @@ public Response runPixelAsync(@Context HttpServletRequest request) { if (insight == null) { Map errorMap = new HashMap<>(); errorMap.put(ERROR_MESSAGE, "Could not find the insight id"); + errorMap.put(ERROR_TYPE, INSIGHT_NOT_FOUND); return WebUtility.getResponse(errorMap, 400); } // make sure we have the correct session trying to get this id From 8d88ffea97987e873cf62162c2ee90d87c2509c0 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 18 May 2020 20:31:50 +0000 Subject: [PATCH 0592/1906] UPDATE ::: Patching cookies for isSecure based on the request and httpOnly git-svn-id: svn://107.170.10.188:8080/Monolith/dev@38775 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 72717cf6a6f56ca81cece99edea3e46d830bb8f2 --- .../web/services/local/AppResource.java | 47 +++++------ .../services/local/AuthorizationResource.java | 34 ++++---- .../semoss/web/services/local/NameServer.java | 10 +-- .../web/services/local/SessionResource.java | 2 + .../web/services/local/UserResource.java | 7 +- .../services/remote/EngineRemoteResource.java | 23 ++---- src/prerna/web/conf/AnonymousUserFilter.java | 13 +-- .../web/conf/NoUserInSessionFilter.java | 6 ++ .../NoUserInSessionTrustedTokenFilter.java | 2 + src/prerna/web/services/util/WebUtility.java | 80 +++++++++++++++++-- 10 files changed, 148 insertions(+), 76 deletions(-) diff --git a/src/prerna/semoss/web/services/local/AppResource.java b/src/prerna/semoss/web/services/local/AppResource.java index 962ec706e..0f42037d0 100644 --- a/src/prerna/semoss/web/services/local/AppResource.java +++ b/src/prerna/semoss/web/services/local/AppResource.java @@ -27,6 +27,7 @@ import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.ResponseBuilder; +import org.apache.commons.io.FileUtils; import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.io.filefilter.WildcardFileFilter; @@ -119,14 +120,14 @@ public Response getAppLandingPage(@Context final Request coreRequest, @Context H try { user = ResourceUtility.getUser(request); } catch (IllegalAccessException e) { - Map errorMap = new HashMap(); + Map errorMap = new HashMap<>(); errorMap.put("error", "User session is invalid"); return WebUtility.getResponse(errorMap, 401); } try { canAccessApp(user, appId); } catch (IllegalAccessException e) { - Map errorMap = new HashMap(); + Map errorMap = new HashMap<>(); errorMap.put("error", e.getMessage()); return WebUtility.getResponse(errorMap, 401); } @@ -140,7 +141,7 @@ public Response getAppLandingPage(@Context final Request coreRequest, @Context H File file = new File(fileLocation); if(file != null && file.exists()) { try { - String html = new String(Files.readAllBytes(Paths.get(file.getAbsolutePath()))); + String html = FileUtils.readFileToString(file, "UTF-8"); // want to cache this on browser if user has access CacheControl cc = new CacheControl(); @@ -156,12 +157,12 @@ public Response getAppLandingPage(@Context final Request coreRequest, @Context H return Response.status(200).entity(html).cacheControl(cc).tag(etag).lastModified(new Date(file.lastModified())).build(); } catch (IOException e) { - Map errorMap = new HashMap(); + Map errorMap = new HashMap<>(); errorMap.put("errorMessage", "Unable to load landing html file"); return WebUtility.getResponse(errorMap, 404); } } else { - Map errorMap = new HashMap(); + Map errorMap = new HashMap<>(); errorMap.put("errorMessage", "No custom landing page found"); return WebUtility.getResponse(errorMap, 404); } @@ -175,14 +176,14 @@ public Response getAppFile(@Context final Request coreRequest, @Context HttpServ try { user = ResourceUtility.getUser(request); } catch (IllegalAccessException e) { - Map errorMap = new HashMap(); + Map errorMap = new HashMap<>(); errorMap.put("error", "User session is invalid"); return WebUtility.getResponse(errorMap, 401); } try { canAccessApp(user, appId); } catch (IllegalAccessException e) { - Map errorMap = new HashMap(); + Map errorMap = new HashMap<>(); errorMap.put("error", e.getMessage()); return WebUtility.getResponse(errorMap, 401); } @@ -196,7 +197,7 @@ public Response getAppFile(@Context final Request coreRequest, @Context HttpServ File file = new File(fileLocation); if(file != null && file.exists()) { try { - String contents = new String(Files.readAllBytes(Paths.get(file.getAbsolutePath()))); + String contents = FileUtils.readFileToString(file, "UTF-8"); // want to cache this on browser if user has access CacheControl cc = new CacheControl(); @@ -212,12 +213,12 @@ public Response getAppFile(@Context final Request coreRequest, @Context HttpServ return Response.status(200).entity(contents).cacheControl(cc).tag(etag).lastModified(new Date(file.lastModified())).build(); } catch (IOException e) { - Map errorMap = new HashMap(); + Map errorMap = new HashMap<>(); errorMap.put("errorMessage", "Unable to load file"); return WebUtility.getResponse(errorMap, 404); } } else { - Map errorMap = new HashMap(); + Map errorMap = new HashMap<>(); errorMap.put("errorMessage", "No file found"); return WebUtility.getResponse(errorMap, 404); } @@ -232,14 +233,14 @@ public Response getEmbedUrl(@Context final Request coreRequest, @Context HttpSer try { user = ResourceUtility.getUser(request); } catch (IllegalAccessException e) { - Map errorMap = new HashMap(); + Map errorMap = new HashMap<>(); errorMap.put("error", "User session is invalid"); return WebUtility.getResponse(errorMap, 401); } try { canAccessApp(user, appId); } catch (IllegalAccessException e) { - Map errorMap = new HashMap(); + Map errorMap = new HashMap<>(); errorMap.put("error", e.getMessage()); return WebUtility.getResponse(errorMap, 401); } @@ -250,7 +251,7 @@ public Response getEmbedUrl(@Context final Request coreRequest, @Context HttpSer String embedLogo = getEmbedLogo(); if(AppResource.noLogo) { - Map errorMap = new HashMap(); + Map errorMap = new HashMap<>(); errorMap.put("error", "no defualt logo"); return WebUtility.getResponse(errorMap, 404); } @@ -275,12 +276,12 @@ public Response getEmbedUrl(@Context final Request coreRequest, @Context HttpSer String mimeType = Files.probeContentType(file.toPath()); return Response.status(200).entity(contents).type(mimeType).cacheControl(cc).tag(etag).lastModified(new Date(file.lastModified())).build(); } catch (IOException e) { - Map errorMap = new HashMap(); + Map errorMap = new HashMap<>(); errorMap.put("errorMessage", "Unable to load file"); return WebUtility.getResponse(errorMap, 400); } } else { - Map errorMap = new HashMap(); + Map errorMap = new HashMap<>(); errorMap.put("errorMessage", "Default logo file not found"); return WebUtility.getResponse(errorMap, 404); } @@ -322,14 +323,14 @@ public Response downloadAppImage(@Context final Request coreRequest, @Context Ht try { user = ResourceUtility.getUser(request); } catch (IllegalAccessException e) { - Map errorMap = new HashMap(); + Map errorMap = new HashMap<>(); errorMap.put("error", "User session is invalid"); return WebUtility.getResponse(errorMap, 401); } try { canAccessApp(user, appId); } catch (IllegalAccessException e) { - Map errorMap = new HashMap(); + Map errorMap = new HashMap<>(); errorMap.put("error", e.getMessage()); return WebUtility.getResponse(errorMap, 401); } @@ -354,7 +355,7 @@ public Response downloadAppImage(@Context final Request coreRequest, @Context Ht return Response.status(200).entity(exportFile).header("Content-Disposition", "attachment; filename=" + exportName) .cacheControl(cc).tag(etag).lastModified(new Date(exportFile.lastModified())).build(); } else { - Map errorMap = new HashMap(); + Map errorMap = new HashMap<>(); errorMap.put("errorMessage", "error sending image file"); return WebUtility.getResponse(errorMap, 400); } @@ -413,14 +414,14 @@ public Response downloadInsightImage(@Context final Request coreRequest, @Contex try { user = ResourceUtility.getUser(request); } catch (IllegalAccessException e) { - Map errorMap = new HashMap(); + Map errorMap = new HashMap<>(); errorMap.put("error", "User session is invalid"); return WebUtility.getResponse(errorMap, 401); } try { canAccessInsight(user, appId, id); } catch (IllegalAccessException e) { - Map errorMap = new HashMap(); + Map errorMap = new HashMap<>(); errorMap.put("error", e.getMessage()); return WebUtility.getResponse(errorMap, 401); } @@ -447,7 +448,7 @@ public Response downloadInsightImage(@Context final Request coreRequest, @Contex return Response.status(200).entity(exportFile).header("Content-Disposition", "attachment; filename=" + exportName) .cacheControl(cc).tag(etag).lastModified(new Date(exportFile.lastModified())).build(); } else { - Map errorMap = new HashMap(); + Map errorMap = new HashMap<>(); errorMap.put("errorMessage", "Error sending image file"); return WebUtility.getResponse(errorMap, 404); } @@ -521,7 +522,7 @@ private File getInsightImageFile(String appId, String id, String feUrl, String p * @return */ private File findImageFile(String baseDir) { - List extensions = new Vector(); + List extensions = new Vector<>(); extensions.add("image.png"); extensions.add("image.jpeg"); extensions.add("image.jpg"); @@ -587,7 +588,7 @@ public Response getAppWidget(@PathParam("appId") String app, @QueryParam("widget } } // return error - Map errorMap = new HashMap(); + Map errorMap = new HashMap<>(); errorMap.put("errorMessage", "error sending widget file " + widgetName + "\\" + fileName); return WebUtility.getResponse(errorMap, 400); } diff --git a/src/prerna/semoss/web/services/local/AuthorizationResource.java b/src/prerna/semoss/web/services/local/AuthorizationResource.java index 6f166ff54..a5a9c4df7 100644 --- a/src/prerna/semoss/web/services/local/AuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/AuthorizationResource.java @@ -71,7 +71,7 @@ public Response isAdminUser(@Context HttpServletRequest request) { try { user = ResourceUtility.getUser(request); } catch (IllegalAccessException e) { - Map errorMap = new HashMap(); + Map errorMap = new HashMap<>(); errorMap.put("error", "User session is invalid"); return WebUtility.getResponse(errorMap, 401); } @@ -92,7 +92,7 @@ public StreamingOutput searchForUser(@Context HttpServletRequest request, @Query @Produces("application/json") @Path("/admin/registerUser") public Response registerUser(@Context HttpServletRequest request, MultivaluedMap form) { - Hashtable errorRet = new Hashtable(); + Hashtable errorRet = new Hashtable<>(); boolean success = false; try{ User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); @@ -132,14 +132,14 @@ public Response editUser(@Context HttpServletRequest request, MultivaluedMap errorMap = new HashMap(); + Map errorMap = new HashMap<>(); errorMap.put("error", "User session is invalid"); return WebUtility.getResponse(errorMap, 401); } SecurityAdminUtils adminUtils = SecurityAdminUtils.getInstance(user); if(adminUtils == null) { - Map retMap = new Hashtable(); + Map retMap = new Hashtable<>(); retMap.put("error", "User does not have admin priviledges"); return WebUtility.getResponse(retMap, 400); } @@ -150,12 +150,12 @@ public Response editUser(@Context HttpServletRequest request, MultivaluedMap retMap = new Hashtable(); + Map retMap = new Hashtable<>(); retMap.put("error", e.getMessage()); return WebUtility.getResponse(retMap, 400); } - if(ret = false) { - Map retMap = new Hashtable(); + if(!ret) { + Map retMap = new Hashtable<>(); retMap.put("error", "Unknown error occured with updating user. Please try again."); return WebUtility.getResponse(retMap, 400); } @@ -170,14 +170,14 @@ public Response deleteUser(@Context HttpServletRequest request, MultivaluedMap errorMap = new HashMap(); + Map errorMap = new HashMap<>(); errorMap.put("error", "User session is invalid"); return WebUtility.getResponse(errorMap, 401); } SecurityAdminUtils adminUtils = SecurityAdminUtils.getInstance(user); if(adminUtils == null) { - Map retMap = new Hashtable(); + Map retMap = new Hashtable<>(); retMap.put("error", "User does not have admin priviledges"); return WebUtility.getResponse(retMap, 400); } @@ -195,14 +195,14 @@ public Response getAllUsers(@Context HttpServletRequest request) { try { user = ResourceUtility.getUser(request); } catch (IllegalAccessException e) { - Map errorMap = new HashMap(); + Map errorMap = new HashMap<>(); errorMap.put("error", "User session is invalid"); return WebUtility.getResponse(errorMap, 401); } SecurityAdminUtils adminUtils = SecurityAdminUtils.getInstance(user); if(adminUtils == null) { - Map retMap = new Hashtable(); + Map retMap = new Hashtable<>(); retMap.put("error", "User does not have admin priviledges"); return WebUtility.getResponse(retMap, 400); } @@ -219,7 +219,7 @@ public Response requestAccess(@Context HttpServletRequest request, MultivaluedMa try { user = ResourceUtility.getUser(request); } catch (IllegalAccessException e) { - Map errorMap = new HashMap(); + Map errorMap = new HashMap<>(); errorMap.put("error", "User session is invalid"); return WebUtility.getResponse(errorMap, 401); } @@ -234,12 +234,12 @@ public Response requestAccess(@Context HttpServletRequest request, MultivaluedMa addedRequests = SecurityUpdateUtils.makeRequest(user, engineId, requestedPermission); } catch(IllegalArgumentException e) { logger.error(STACKTRACE, e); - Map errorRet = new HashMap(); + Map errorRet = new HashMap<>(); errorRet.put("error", e.getMessage()); return WebUtility.getResponse(errorRet, 400); } catch (Exception e){ logger.error(STACKTRACE, e); - Map errorRet = new HashMap(); + Map errorRet = new HashMap<>(); errorRet.put("error", "An unexpected error happened. Please try again."); return WebUtility.getResponse(errorRet, 500); } @@ -255,7 +255,7 @@ public Response getMyRequests(@Context HttpServletRequest request) { try { user = ResourceUtility.getUser(request); } catch (IllegalAccessException e) { - Map errorMap = new HashMap(); + Map errorMap = new HashMap<>(); errorMap.put("error", "User session is invalid"); return WebUtility.getResponse(errorMap, 401); } @@ -265,12 +265,12 @@ public Response getMyRequests(@Context HttpServletRequest request) { userRequests = SecurityQueryUtils.getUserAccessRequests(user); } catch(IllegalArgumentException e) { logger.error(STACKTRACE, e); - Map errorRet = new HashMap(); + Map errorRet = new HashMap<>(); errorRet.put("error", e.getMessage()); return WebUtility.getResponse(errorRet, 400); } catch (Exception e){ logger.error(STACKTRACE, e); - Map errorRet = new HashMap(); + Map errorRet = new HashMap<>(); errorRet.put("error", "An unexpected error happened. Please try again."); return WebUtility.getResponse(errorRet, 500); } diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index 4036e5a6e..a35c903d3 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -518,7 +518,6 @@ private Response runPixelJob(User user, Insight insight, String expression, Stri */ private void setPythonForSession(HttpSession session, String sessionId, User user) { PyTranslator pyt = null; - PyExecutorThread jepThread = null; String port = null; boolean useFilePy = Boolean.parseBoolean(DIHelper.getInstance().getProperty("USE_PY_FILE")); @@ -529,11 +528,10 @@ private void setPythonForSession(HttpSession session, String sessionId, User use if (session.getAttribute(Constants.PYTHON) != null) { pyt = (PyTranslator) session.getAttribute(Constants.PYTHON); } - if (jepThread == null) { - jepThread = PyUtils.getInstance().getJep(); - pyt = new PyTranslator(); - pyt.setPy(jepThread); - } + + PyExecutorThread jepThread = PyUtils.getInstance().getJep(); + pyt = new PyTranslator(); + pyt.setPy(jepThread); } // check to see if the py translator needs to be set ? else if (useFilePy && session.getAttribute("USER_TUPLE") == null) { diff --git a/src/prerna/semoss/web/services/local/SessionResource.java b/src/prerna/semoss/web/services/local/SessionResource.java index 5fa0e5658..3a03bc4e9 100644 --- a/src/prerna/semoss/web/services/local/SessionResource.java +++ b/src/prerna/semoss/web/services/local/SessionResource.java @@ -27,6 +27,7 @@ import prerna.om.Insight; import prerna.om.InsightStore; import prerna.util.Constants; +import prerna.util.Utility; import prerna.util.insight.InsightUtility; import prerna.web.conf.DBLoader; import prerna.web.conf.SessionCounter; @@ -203,6 +204,7 @@ public void invalidateSession(@Context HttpServletRequest request, @Context Http redirectUrl += ":" + serverPort; } redirectUrl += contextPath + "/logout/"; + redirectUrl = Utility.cleanHttpResponse(redirectUrl); response.setHeader("redirect", redirectUrl); response.sendError(302, "Need to redirect to " + redirectUrl); } diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index b2a058740..6def3b05d 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -349,7 +349,8 @@ public Void call() throws Exception { // we need to null this out Cookie nullC = new Cookie(c.getName(), c.getValue()); nullC.setPath(c.getPath()); - nullC.setSecure(c.getSecure()); + nullC.setSecure(request.isSecure()); + nullC.setHttpOnly(true); nullC.setVersion(c.getVersion()); if (c.getDomain() != null) { nullC.setDomain(c.getDomain()); @@ -1665,6 +1666,8 @@ private void setMainPageRedirect(@Context HttpServletRequest request, @Context H response.setStatus(302); try { Cookie cookie = new Cookie(DBLoader.getSessionIdKey(), request.getSession().getId()); + cookie.setSecure(request.isSecure()); + cookie.setHttpOnly(true); // cookie.setPath("/dev"); response.addCookie(cookie); if (useCustom) { @@ -1734,6 +1737,8 @@ public StreamingOutput manCookie(@Context HttpServletRequest request, @Context H User user = (User) session.getAttribute(Constants.SESSION_USER); Cookie k = new Cookie(DBLoader.getSessionIdKey(), sessionId); + k.setSecure(request.isSecure()); + k.setHttpOnly(true); k.setPath(request.getContextPath()); response.addCookie(k); diff --git a/src/prerna/semoss/web/services/remote/EngineRemoteResource.java b/src/prerna/semoss/web/services/remote/EngineRemoteResource.java index cb83c00c5..495bf89c7 100644 --- a/src/prerna/semoss/web/services/remote/EngineRemoteResource.java +++ b/src/prerna/semoss/web/services/remote/EngineRemoteResource.java @@ -30,7 +30,6 @@ import java.io.IOException; import java.io.ObjectOutputStream; import java.io.OutputStream; -import java.io.PrintStream; import java.util.Hashtable; import javax.ws.rs.FormParam; @@ -85,7 +84,6 @@ public void setEngine(IEngine coreEngine) @Path("getFromNeighbors") @Produces("application/json") public StreamingOutput getFromNeighbors(@FormParam("nodeType") String nodeType, @FormParam("neighborHood") int neighborHood) { - // TODO Auto-generated method stub return WebUtility.getSO(coreEngine.getFromNeighbors(nodeType, neighborHood)); } @@ -93,7 +91,6 @@ public StreamingOutput getFromNeighbors(@FormParam("nodeType") String nodeType, @Path("getToNeighbors") @Produces("application/json") public StreamingOutput getToNeighbors(@FormParam("nodeType") String nodeType, @FormParam("neighborHood") int neighborHood) { - // TODO Auto-generated method stub return WebUtility.getSO(coreEngine.getToNeighbors(nodeType, neighborHood)); } @@ -109,7 +106,6 @@ public StreamingOutput getNeighbors(@FormParam("nodeType") String nodeType, @For @Path("execGraphQuery") @Produces("application/json") public Object execGraphQuery(@FormParam("query") String query) { - // TODO Auto-generated method stub // Steps I need to do // Create a wrapper object // The wrapper consists of a unique number, the actual output object @@ -139,7 +135,6 @@ public Object execGraphQuery(@FormParam("query") String query) { @Path("execSelectQuery") @Produces("application/json") public Object execSelectQuery(@FormParam("query") String query) { - // TODO Auto-generated method stub logger.info("Executing Select Query " + Utility.cleanLogString(query)); AbstractWrapper sjsw = null; try { @@ -160,7 +155,6 @@ public Object execSelectQuery(@FormParam("query") String query) { @Path("execCheaterQuery") @Produces("application/json") public Object execCheaterQuery(@FormParam("query") String query) { - // TODO Auto-generated method stub logger.info("Executing Select Query " + Utility.cleanLogString(query)); AbstractWrapper sjsw = null; try { @@ -180,7 +174,6 @@ public Object execCheaterQuery(@FormParam("query") String query) { @Path("getEntityOfType") @Produces("application/json") public StreamingOutput getEntityOfType(@FormParam("sparqlQuery") String sparqlQuery) { - // TODO Auto-generated method stub return WebUtility.getSO(coreEngine.getEntityOfType(sparqlQuery)); } @@ -188,12 +181,11 @@ public StreamingOutput getEntityOfType(@FormParam("sparqlQuery") String sparqlQu @Path("execAskQuery") @Produces("application/json") public StreamingOutput execAskQuery(@FormParam("query") String query) { - // TODO Auto-generated method stub try { return WebUtility.getSO(coreEngine.execQuery(query)); } catch (Exception e) { logger.error(STACKTRACE,e); - Hashtable ret = new Hashtable(); + Hashtable ret = new Hashtable<>(); ret.put("errorMessage", e.getMessage()); return WebUtility.getSO(ret); } @@ -213,7 +205,6 @@ public StreamingOutput execAskQuery(@FormParam("query") String query) { @Path("getInsightDefinition") @Produces("application/text") public String getInsightDefinition() { - // TODO Auto-generated method stub logger.info("ENgine is " + coreEngine); return coreEngine.getInsightDefinition(); } @@ -222,7 +213,6 @@ public String getInsightDefinition() { @Path("getOWLDefinition") @Produces("application/xml") public String getOWLDefinition() { - // TODO Auto-generated method stub return coreEngine.getOWLDefinition(); } @@ -247,9 +237,9 @@ public StreamingOutput hasNext(@FormParam("id") String id) // retValue = ((SesameJenaSelectCheater)wrapper).hasNext(); //TODO: this shouldnt' be commented out!!! -// retValue = ((IEngineWrapper) wrapper).hasNext(); - if(!retValue) // cleanup - QueryResultHash.getInstance().cleanObject(id); + // retValue = ((IEngineWrapper) wrapper).hasNext(); + // if(!retValue) // cleanup + QueryResultHash.getInstance().cleanObject(id); } return WebUtility.getSO(retValue); @@ -361,13 +351,14 @@ public void write(OutputStream outputStream) throws IOException, WebApplicationE myInt = new Integer(i); //ps.println("Sending " + i); os.writeObject(myInt); - if(i %1000 == 0) + if (i %1000 == 0) { try { Thread.sleep(200); } catch (InterruptedException e) { - // TODO Auto-generated catch block + Thread.currentThread().interrupt(); logger.error(STACKTRACE,e); } + } } }}; } diff --git a/src/prerna/web/conf/AnonymousUserFilter.java b/src/prerna/web/conf/AnonymousUserFilter.java index 158e5cbf9..9fd843a13 100644 --- a/src/prerna/web/conf/AnonymousUserFilter.java +++ b/src/prerna/web/conf/AnonymousUserFilter.java @@ -1,6 +1,7 @@ package prerna.web.conf; import java.io.IOException; +import java.io.Serializable; import java.util.UUID; import javax.servlet.Filter; @@ -18,14 +19,16 @@ import prerna.auth.utils.AbstractSecurityUtils; import prerna.util.Constants; -public class AnonymousUserFilter implements Filter { +public class AnonymousUserFilter implements Filter, Serializable { + + private static final long serialVersionUID = -4657347128078864456L; @Override public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { if(AbstractSecurityUtils.anonymousUsersEnabled()) { HttpSession session = ((HttpServletRequest)arg0).getSession(true); - User semossUser = new User(); + User semossUser = null; Object user = session.getAttribute(Constants.SESSION_USER); if(user == null) { semossUser = new User(); @@ -56,7 +59,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 c.setMaxAge(60 * 60 * 24 * 365 * 10); c.setPath(((HttpServletRequest) arg0).getContextPath()); c.setHttpOnly(true); - c.setSecure(true); + c.setSecure(((HttpServletRequest)arg0).isSecure()); ((HttpServletResponse)arg1).addCookie(c); } // add to session @@ -69,13 +72,13 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 @Override public void destroy() { - // TODO Auto-generated method stub + // destroy } @Override public void init(FilterConfig arg0) throws ServletException { - // TODO Auto-generated method stub + // initialize } diff --git a/src/prerna/web/conf/NoUserInSessionFilter.java b/src/prerna/web/conf/NoUserInSessionFilter.java index fa4a0f5d7..4d129045b 100644 --- a/src/prerna/web/conf/NoUserInSessionFilter.java +++ b/src/prerna/web/conf/NoUserInSessionFilter.java @@ -119,6 +119,8 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 String sessionId = Utility.cleanHttpResponse(req.getParameter(DBLoader.getSessionIdKey())); // create the cookie add it and sent it back Cookie k = new Cookie(DBLoader.getSessionIdKey(), sessionId); + k.setHttpOnly(true); + k.setSecure(req.isSecure()); k.setPath(contextPath); ((HttpServletResponse) arg1).addCookie(k); // in case there are other JSESSIONID @@ -138,6 +140,8 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 if (routes != null && !routes.isEmpty()) { for (String r : routes) { Cookie c = new Cookie(r, Utility.cleanHttpResponse(req.getParameter(r))); + c.setHttpOnly(true); + c.setSecure(req.isSecure()); c.setPath(contextPath); ((HttpServletResponse) arg1).addCookie(c); } @@ -146,6 +150,8 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 // add the hash cookie String hash = req.getParameter("hash"); Cookie h = new Cookie("HASH", Utility.cleanHttpResponse(hash)); + h.setHttpOnly(true); + h.setSecure(req.isSecure()); h.setPath(contextPath); ((HttpServletResponse) arg1).addCookie(h); diff --git a/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java b/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java index b1122791a..ab6c49c3a 100644 --- a/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java +++ b/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java @@ -114,6 +114,8 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 String redirectSessionId = (String) sessionMapper.get(userId); // add the session id cookie Cookie k = new Cookie(DBLoader.getSessionIdKey(), redirectSessionId); + k.setHttpOnly(true); + k.setSecure(req.isSecure()); k.setPath(contextPath); ((HttpServletResponse)arg1).addCookie(k); // replace any other session id cookies diff --git a/src/prerna/web/services/util/WebUtility.java b/src/prerna/web/services/util/WebUtility.java index 30b2503b2..c05e6a7d5 100644 --- a/src/prerna/web/services/util/WebUtility.java +++ b/src/prerna/web/services/util/WebUtility.java @@ -31,7 +31,10 @@ import java.io.OutputStream; import java.io.PrintStream; import java.io.UnsupportedEncodingException; +import java.util.Calendar; +import java.util.Date; import java.util.List; +import java.util.TimeZone; import java.util.Vector; import javax.ws.rs.WebApplicationException; @@ -40,6 +43,7 @@ import javax.ws.rs.core.Response.ResponseBuilder; import javax.ws.rs.core.StreamingOutput; +import org.apache.commons.lang.time.FastDateFormat; import org.apache.log4j.Logger; import com.google.gson.Gson; @@ -55,12 +59,15 @@ public class WebUtility { private static final String CLASS_NAME = WebUtility.class.getName(); private static final Logger LOGGER = Logger.getLogger(CLASS_NAME); + private static final FastDateFormat expiresDateFormat= FastDateFormat.getInstance("EEE, dd MMM yyyy HH:mm:ss zzz", TimeZone.getTimeZone("GMT")); + private static final List noCacheHeaders = new Vector(); static { - noCacheHeaders.add(new String[] {"Cache-Control", "no-store, no-cache, must-revalidate, max-age=0, post-check=0, pre-check=0"}); - noCacheHeaders.add(new String[] {"Pragma", "no-cache"}); + noCacheHeaders.add(new String[] {"Cache-Control", "private"}); +// noCacheHeaders.add(new String[] {"Cache-Control", "no-store, no-cache, must-revalidate, max-age=20, post-check=0, pre-check=0"}); +// noCacheHeaders.add(new String[] {"Pragma", "no-cache"}); } - + private static Gson getDefaultGson() { return GsonUtility.getDefaultGson(); } @@ -91,11 +98,11 @@ public void write(OutputStream outputStream) throws IOException, WebApplicationE public static Response getResponse(Object vec, int status, NewCookie... cookies) { return getResponse(vec, status, null, cookies); } - + public static Response getResponseNoCache(Object vec, int status, NewCookie... cookies) { return getResponse(vec, status, noCacheHeaders, cookies); } - + public static Response getResponse(Object vec, int status, List addHeaders, NewCookie... cookies) { if(vec != null) { Gson gson = getDefaultGson(); @@ -110,7 +117,14 @@ public static Response getResponse(Object vec, int status, List addHea } } if(cookies != null && cookies.length > 0) { - builder.cookie(cookies); + // due to chrome updates, we require to add cookies + // with samesite tags if they are not secure + // so will set the cookies via the header + for (NewCookie cookie : cookies) { + // add the cookie to the header + // with the SameSite Strict tag + builder.header("Set-Cookie", convertCookieToHeader(cookie)); + } } return builder.build(); } catch (UnsupportedEncodingException e) { @@ -121,9 +135,59 @@ public static Response getResponse(Object vec, int status, List addHea return null; } + + public static String convertCookieToHeader(NewCookie cookie) { + StringBuilder c = new StringBuilder(64+cookie.getValue().length()); + // add the cookie + c.append(cookie.getName()); + c.append('='); + c.append(cookie.getValue()); + // set same-site strict + c.append("; "); + c.append("SameSite"); + c.append('='); + c.append("Strict"); + // get the domain + if(cookie.getDomain() != null) { + c.append("; "); + c.append("domain"); + c.append('='); + c.append(cookie.getDomain()); + } + // the path + if(cookie.getPath() != null) { + c.append("; "); + c.append("path"); + c.append('='); + c.append(cookie.getPath()); + } + if (cookie.isSecure()) { + c.append("; secure"); + } + if (cookie.isHttpOnly()) { + c.append("; HttpOnly"); + } + if (cookie.getMaxAge()>=0) { + c.append("; "); + c.append("Expires"); + c.append('='); + c.append(getExpires(cookie.getMaxAge())); + } + + return c.toString(); + } - public static StreamingOutput getSO(byte[] output) - { + private static String getExpires(int maxAge) { + if (maxAge < 0) { + return ""; + } + Calendar expireDate = Calendar.getInstance(); + expireDate.setTime(new Date()); + expireDate.add(Calendar.SECOND,maxAge); + return expiresDateFormat.format(expireDate); + } + + public static StreamingOutput getSO(byte[] output) { try { return new StreamingOutput() { public void write(OutputStream outputStream) throws IOException, WebApplicationException { From 309b99c3fa0a7839695c959cda94101bbb578e0b Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 19 May 2020 16:12:30 +0000 Subject: [PATCH 0593/1906] UPDATE ::: Making date format not static since its not thread safe git-svn-id: svn://107.170.10.188:8080/Monolith/dev@38790 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: de380ed6c821b7a0303c15aaf601f3e31a18bd33 --- src/prerna/upload/FileUploadProgressListener.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/prerna/upload/FileUploadProgressListener.java b/src/prerna/upload/FileUploadProgressListener.java index dff1834a7..0c2f4c8b7 100644 --- a/src/prerna/upload/FileUploadProgressListener.java +++ b/src/prerna/upload/FileUploadProgressListener.java @@ -11,12 +11,12 @@ public class FileUploadProgressListener implements ProgressListener { private static final String CLASS_NAME = FileUploadProgressListener.class.getName(); - private static DecimalFormat formatter = new DecimalFormat("0.00%"); private Logger logger = null; private long megaBytes = -1; private int currentItem = -1; - + private DecimalFormat formatter = new DecimalFormat("0.00%"); + public FileUploadProgressListener(String jobId) { if(jobId != null && !jobId.isEmpty()) { this.logger = new InMemoryConsole(jobId, CLASS_NAME); From 3bb7b240f44e3bf3d42cabddf064ac8cf8a4872a Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 19 May 2020 16:26:46 +0000 Subject: [PATCH 0594/1906] UPDATE ::: Making things static since servlets/filters are initiated once git-svn-id: svn://107.170.10.188:8080/Monolith/dev@38791 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 5c683038e9d77f88a160f2e300f31ba3c12ee6b3 --- .../semoss/web/services/local/NameServer.java | 3 --- src/prerna/upload/DatabaseUploader.java | 16 ++++++------ src/prerna/upload/ImageUploader.java | 6 ++--- src/prerna/upload/Uploader.java | 25 ++++++++----------- src/prerna/web/conf/CACFilter.java | 20 +++++++-------- src/prerna/web/conf/PIVFilter.java | 20 +++++++-------- src/prerna/web/conf/WaffleFilter.java | 20 +++++++-------- 7 files changed, 51 insertions(+), 59 deletions(-) diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index a35c903d3..5d9a2b327 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -144,7 +144,6 @@ public Uploader uploadDatabase(@Context HttpServletRequest request) { upload.setFilePath(filePath); String tempFilePath = context.getInitParameter("temp-file-upload"); upload.setTempFilePath(tempFilePath); - upload.setSecurityEnabled(securityEnabled); return upload; } @@ -155,7 +154,6 @@ public Uploader uploadFile(@Context HttpServletRequest request) { Uploader upload = new FileUploader(); String tempFilePath = context.getInitParameter("temp-file-upload"); upload.setTempFilePath(tempFilePath); - upload.setSecurityEnabled(securityEnabled); return upload; } @@ -168,7 +166,6 @@ public Uploader uploadImage(@Context HttpServletRequest request) { upload.setFilePath(filePath); String tempFilePath = context.getInitParameter("temp-file-upload"); upload.setTempFilePath(tempFilePath); - upload.setSecurityEnabled(securityEnabled); return upload; } diff --git a/src/prerna/upload/DatabaseUploader.java b/src/prerna/upload/DatabaseUploader.java index 079704458..eb46297c6 100644 --- a/src/prerna/upload/DatabaseUploader.java +++ b/src/prerna/upload/DatabaseUploader.java @@ -8,7 +8,6 @@ import java.io.PrintWriter; import java.text.SimpleDateFormat; import java.util.ArrayList; -import java.util.Arrays; import java.util.Calendar; import java.util.Date; import java.util.HashMap; @@ -37,6 +36,7 @@ import prerna.algorithm.api.SemossDataType; import prerna.auth.AuthProvider; import prerna.auth.User; +import prerna.auth.utils.AbstractSecurityUtils; import prerna.auth.utils.SecurityUpdateUtils; import prerna.engine.impl.SmssUtilities; import prerna.nameserver.AddToMasterDB; @@ -84,7 +84,7 @@ public class DatabaseUploader extends Uploader { // we will control the adding of the engine into local master and solr // such that we dont send a success before those processes are complete - boolean autoLoad = false; + static boolean autoLoad = false; ///////////////////////////////////////////// SET DEFAULT OPTIONS /////////////////////////////////////////////// @@ -633,7 +633,7 @@ public Response uploadCSVFile(MultivaluedMap form, @Context Http // add engine owner for permissions // the - if(this.securityEnabled) { + if(AbstractSecurityUtils.securityEnabled()) { User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); if(user == null) { Map errorHash = new HashMap<>(); @@ -1010,7 +1010,7 @@ public Response uploadExcelPOIFormat(@Context HttpServletRequest request) options.setFileLocation(files); // add engine owner for permissions - if(this.securityEnabled) { + if(AbstractSecurityUtils.securityEnabled()) { User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); if(user == null) { Map errorHash = new HashMap<>(); @@ -1370,7 +1370,7 @@ public Response processExcelFile(@Context HttpServletRequest request) ////////////////////// end logic to process metamodel for excel flat table rdf ////////////////////// // add engine owner for permissions - if(this.securityEnabled) { + if(AbstractSecurityUtils.securityEnabled()) { User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); if(user == null) { Map errorHash = new HashMap<>(); @@ -1496,7 +1496,7 @@ public Response uploadNLPFile(@Context HttpServletRequest request) { options.setFileLocation(uploadFiles); // add engine owner for permissions - if(this.securityEnabled) { + if(AbstractSecurityUtils.securityEnabled()) { User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); if(user == null) { Map errorHash = new HashMap<>(); @@ -1600,7 +1600,7 @@ public Response uploadNLPFile(@Context HttpServletRequest request) { // GATracker.getInstance().trackCsvUpload(files, tableName, headerDataTypes); // } // // add engine owner for permissions -// if(this.securityEnabled) { +// if(AbstractSecurityUtils.securityEnabled()) { // Object user = request.getSession().getAttribute(Constants.SESSION_USER); // if(user != null && !((User) user).getId().equals(Constants.ANONYMOUS_USER_ID)) { // addEngineOwner(options.getDbName(), ((User) user).getId()); @@ -1695,7 +1695,7 @@ public Response uploadNLPFile(@Context HttpServletRequest request) { // } // // // add engine owner for permissions -// if(this.securityEnabled) { +// if(AbstractSecurityUtils.securityEnabled()) { // Object user = request.getSession().getAttribute(Constants.SESSION_USER); // if(user != null && !((User) user).getId().equals(Constants.ANONYMOUS_USER_ID)) { // addEngineOwner(options.getDbName(), ((User) user).getId()); diff --git a/src/prerna/upload/ImageUploader.java b/src/prerna/upload/ImageUploader.java index f72db80bb..463de6c06 100644 --- a/src/prerna/upload/ImageUploader.java +++ b/src/prerna/upload/ImageUploader.java @@ -4,7 +4,6 @@ import java.io.FileFilter; import java.io.FilenameFilter; import java.io.IOException; -import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -24,6 +23,7 @@ import org.apache.log4j.Logger; import prerna.auth.User; +import prerna.auth.utils.AbstractSecurityUtils; import prerna.auth.utils.SecurityAppUtils; import prerna.auth.utils.SecurityInsightUtils; import prerna.auth.utils.SecurityQueryUtils; @@ -71,7 +71,7 @@ public Response uploadAppImage(@Context HttpServletRequest request) { return WebUtility.getResponse(returnMap, 400); } - if (this.securityEnabled) { + if (AbstractSecurityUtils.securityEnabled()) { HttpSession session = request.getSession(false); if (session != null) { User user = ((User) session.getAttribute(Constants.SESSION_USER)); @@ -198,7 +198,7 @@ public Response uploadInsightImage(@Context HttpServletRequest request) { return WebUtility.getResponse(returnMap, 400); } - if (this.securityEnabled) { + if (AbstractSecurityUtils.securityEnabled()) { HttpSession session = request.getSession(false); if (session != null) { User user = ((User) session.getAttribute(Constants.SESSION_USER)); diff --git a/src/prerna/upload/Uploader.java b/src/prerna/upload/Uploader.java index b56435d34..944d15c9b 100644 --- a/src/prerna/upload/Uploader.java +++ b/src/prerna/upload/Uploader.java @@ -67,15 +67,14 @@ public abstract class Uploader extends HttpServlet { public static final String CSV_HELPER_MESSAGE = "HTML_RESPONSE"; private static final String STACKTRACE = "StackTrace: "; - protected int maxFileSize = 10_000_000 * 1024; - protected int maxMemSize = 8 * 1024; - protected String filePath; - protected String tempFilePath = ""; - protected boolean securityEnabled; + protected static int maxFileSize = 10_000_000 * 1024; + protected static int maxMemSize = 8 * 1024; + protected static String filePath; + protected static String tempFilePath = ""; // we will control the adding of the engine into local master and solr // such that we dont send a success before those processes are complete - boolean autoLoad = false; + static boolean autoLoad = false; public void setFilePath(String filePath) { // first, normalize path @@ -83,11 +82,11 @@ public void setFilePath(String filePath) { // then set path if(normalizedfilePath.endsWith(DIR_SEPARATOR)) { - this.filePath = normalizedfilePath; + Uploader.filePath = normalizedfilePath; } else { - this.filePath = normalizedfilePath + DIR_SEPARATOR; + Uploader.filePath = normalizedfilePath + DIR_SEPARATOR; } - File f = new File(this.filePath); + File f = new File(Uploader.filePath); if(!f.exists() && !f.isDirectory()) { Boolean success = f.mkdirs(); if(!success) { @@ -101,7 +100,7 @@ public void setTempFilePath(String tempFilePath){ String normalizedTempFilePath = Utility.normalizePath(tempFilePath); // then set path - this.tempFilePath = normalizedTempFilePath; + Uploader.tempFilePath = normalizedTempFilePath; File tFile = new File(normalizedTempFilePath); if(!tFile.exists() && !tFile.isDirectory()) { Boolean success = tFile.mkdirs(); @@ -111,10 +110,6 @@ public void setTempFilePath(String tempFilePath){ } } - public void setSecurityEnabled(boolean securityEnabled) { - this.securityEnabled = securityEnabled; - } - public void writeFile(FileItem fi, File file){ try { fi.write(file); @@ -199,7 +194,7 @@ protected Hashtable getInputData(List fileItems) fileName = fileName.replace(";", ""); Date date = new Date(); String modifiedDate = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_SSSS").format(date); - value = this.filePath + fileName.substring(fileName.lastIndexOf(DIR_SEPARATOR) + 1, fileName.lastIndexOf(".")).trim().replace(" ", "_") + "_____UNIQUE" + modifiedDate + fileName.substring(fileName.lastIndexOf(".")); + value = Uploader.filePath + fileName.substring(fileName.lastIndexOf(DIR_SEPARATOR) + 1, fileName.lastIndexOf(".")).trim().replace(" ", "_") + "_____UNIQUE" + modifiedDate + fileName.substring(fileName.lastIndexOf(".")); file = new File(value); writeFile(fi, file); diff --git a/src/prerna/web/conf/CACFilter.java b/src/prerna/web/conf/CACFilter.java index c8db1070b..485ae6aad 100644 --- a/src/prerna/web/conf/CACFilter.java +++ b/src/prerna/web/conf/CACFilter.java @@ -55,10 +55,10 @@ public class CACFilter implements Filter { // realization of init params private static Boolean autoAdd = null; - private CACTrackingUtil tracker = null; - private UserFileLogUtil userLogger = null; + private static CACTrackingUtil tracker = null; + private static UserFileLogUtil userLogger = null; - private FilterConfig filterConfig; + private static FilterConfig filterConfig; // TODO >>>timb: WORKSPACE - call logic to pull workspace here, or make into a reactor @Override @@ -222,12 +222,12 @@ public void destroy() { @Override public void init(FilterConfig arg0) throws ServletException { - this.filterConfig = arg0; + CACFilter.filterConfig = arg0; } private void setInitParams(ServletRequest arg0) { if(CACFilter.autoAdd == null) { - String autoAddStr = this.filterConfig.getInitParameter(AUTO_ADD); + String autoAddStr = CACFilter.filterConfig.getInitParameter(AUTO_ADD); if(autoAddStr != null) { CACFilter.autoAdd = Boolean.parseBoolean(autoAddStr); } else { @@ -236,13 +236,13 @@ private void setInitParams(ServletRequest arg0) { } boolean logUsers = false; - String logUserInfoStr = this.filterConfig.getInitParameter(LOG_USER_INFO); + String logUserInfoStr = CACFilter.filterConfig.getInitParameter(LOG_USER_INFO); if(logUserInfoStr != null) { logUsers = Boolean.parseBoolean(logUserInfoStr); } if(logUsers) { - String logInfoPath = this.filterConfig.getInitParameter(LOG_USER_INFO_PATH); - String logInfoSep = this.filterConfig.getInitParameter(LOG_USER_INFO_SEP); + String logInfoPath = CACFilter.filterConfig.getInitParameter(LOG_USER_INFO_PATH); + String logInfoSep = CACFilter.filterConfig.getInitParameter(LOG_USER_INFO_SEP); if(logInfoPath == null) { logger.info("SYSTEM HAS REGISTERED TO PERFORM A USER FILE LOG BUT NOT FILE PATH HAS BEEN ENTERED!!!"); logger.info("SYSTEM HAS REGISTERED TO PERFORM A USER FILE LOG BUT NOT FILE PATH HAS BEEN ENTERED!!!"); @@ -260,7 +260,7 @@ private void setInitParams(ServletRequest arg0) { } boolean countUsers = false; - String countUsersStr = this.filterConfig.getInitParameter(COUNT_USER_ENTRY); + String countUsersStr = CACFilter.filterConfig.getInitParameter(COUNT_USER_ENTRY); if(countUsersStr != null) { countUsers = Boolean.parseBoolean(countUsersStr); } else { @@ -268,7 +268,7 @@ private void setInitParams(ServletRequest arg0) { } if(countUsers) { - String countDatabaseId = this.filterConfig.getInitParameter(COUNT_USER_ENTRY_DATABASE); + String countDatabaseId = CACFilter.filterConfig.getInitParameter(COUNT_USER_ENTRY_DATABASE); if(countDatabaseId == null) { logger.info("SYSTEM HAS REGISTERED TO PERFORM A COUNT BUT NO DATABASE ID HAS BEEN ENTERED!!!"); logger.info("SYSTEM HAS REGISTERED TO PERFORM A COUNT BUT NO DATABASE ID HAS BEEN ENTERED!!!"); diff --git a/src/prerna/web/conf/PIVFilter.java b/src/prerna/web/conf/PIVFilter.java index 29c5f98ea..2488cbc54 100644 --- a/src/prerna/web/conf/PIVFilter.java +++ b/src/prerna/web/conf/PIVFilter.java @@ -45,10 +45,10 @@ public class PIVFilter implements Filter { // realization of init params private static Boolean autoAdd = null; - private CACTrackingUtil tracker = null; - private UserFileLogUtil userLogger = null; + private static CACTrackingUtil tracker = null; + private static UserFileLogUtil userLogger = null; - private FilterConfig filterConfig; + private static FilterConfig filterConfig; // TODO >>>timb: WORKSPACE - call logic to pull workspace here, or make into a reactor @Override @@ -160,12 +160,12 @@ public void destroy() { @Override public void init(FilterConfig arg0) throws ServletException { - this.filterConfig = arg0; + PIVFilter.filterConfig = arg0; } private void setInitParams(ServletRequest arg0) { if(PIVFilter.autoAdd == null) { - String autoAddStr = this.filterConfig.getInitParameter(AUTO_ADD); + String autoAddStr = PIVFilter.filterConfig.getInitParameter(AUTO_ADD); if(autoAddStr != null) { PIVFilter.autoAdd = Boolean.parseBoolean(autoAddStr); } else { @@ -174,13 +174,13 @@ private void setInitParams(ServletRequest arg0) { } boolean logUsers = false; - String logUserInfoStr = this.filterConfig.getInitParameter(LOG_USER_INFO); + String logUserInfoStr = PIVFilter.filterConfig.getInitParameter(LOG_USER_INFO); if(logUserInfoStr != null) { logUsers = Boolean.parseBoolean(logUserInfoStr); } if(logUsers) { - String logInfoPath = this.filterConfig.getInitParameter(LOG_USER_INFO_PATH); - String logInfoSep = this.filterConfig.getInitParameter(LOG_USER_INFO_SEP); + String logInfoPath = PIVFilter.filterConfig.getInitParameter(LOG_USER_INFO_PATH); + String logInfoSep = PIVFilter.filterConfig.getInitParameter(LOG_USER_INFO_SEP); if(logInfoPath == null) { logger.info("SYSTEM HAS REGISTERED TO PERFORM A USER FILE LOG BUT NOT FILE PATH HAS BEEN ENTERED!!!"); logger.info("SYSTEM HAS REGISTERED TO PERFORM A USER FILE LOG BUT NOT FILE PATH HAS BEEN ENTERED!!!"); @@ -198,7 +198,7 @@ private void setInitParams(ServletRequest arg0) { } boolean countUsers = false; - String countUsersStr = this.filterConfig.getInitParameter(COUNT_USER_ENTRY); + String countUsersStr = PIVFilter.filterConfig.getInitParameter(COUNT_USER_ENTRY); if(countUsersStr != null) { countUsers = Boolean.parseBoolean(countUsersStr); } else { @@ -206,7 +206,7 @@ private void setInitParams(ServletRequest arg0) { } if(countUsers) { - String countDatabaseId = this.filterConfig.getInitParameter(COUNT_USER_ENTRY_DATABASE); + String countDatabaseId = PIVFilter.filterConfig.getInitParameter(COUNT_USER_ENTRY_DATABASE); if(countDatabaseId == null) { logger.info("SYSTEM HAS REGISTERED TO PERFORM A COUNT BUT NO DATABASE ID HAS BEEN ENTERED!!!"); logger.info("SYSTEM HAS REGISTERED TO PERFORM A COUNT BUT NO DATABASE ID HAS BEEN ENTERED!!!"); diff --git a/src/prerna/web/conf/WaffleFilter.java b/src/prerna/web/conf/WaffleFilter.java index ff07c687a..06d0cb21e 100644 --- a/src/prerna/web/conf/WaffleFilter.java +++ b/src/prerna/web/conf/WaffleFilter.java @@ -40,10 +40,10 @@ public class WaffleFilter implements Filter { // realization of init params private static Boolean autoAdd = null; - private CACTrackingUtil tracker = null; - private UserFileLogUtil userLogger = null; + private static CACTrackingUtil tracker = null; + private static UserFileLogUtil userLogger = null; - private FilterConfig filterConfig; + private static FilterConfig filterConfig; @Override public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { @@ -94,12 +94,12 @@ public void destroy() { @Override public void init(FilterConfig arg0) throws ServletException { - this.filterConfig = arg0; + WaffleFilter.filterConfig = arg0; } private void setInitParams(ServletRequest arg0) { if(WaffleFilter.autoAdd == null) { - String autoAddStr = this.filterConfig.getInitParameter(AUTO_ADD); + String autoAddStr = WaffleFilter.filterConfig.getInitParameter(AUTO_ADD); if(autoAddStr != null) { WaffleFilter.autoAdd = Boolean.parseBoolean(autoAddStr); } else { @@ -108,13 +108,13 @@ private void setInitParams(ServletRequest arg0) { } boolean logUsers = false; - String logUserInfoStr = this.filterConfig.getInitParameter(LOG_USER_INFO); + String logUserInfoStr = WaffleFilter.filterConfig.getInitParameter(LOG_USER_INFO); if(logUserInfoStr != null) { logUsers = Boolean.parseBoolean(logUserInfoStr); } if(logUsers) { - String logInfoPath = this.filterConfig.getInitParameter(LOG_USER_INFO_PATH); - String logInfoSep = this.filterConfig.getInitParameter(LOG_USER_INFO_SEP); + String logInfoPath = WaffleFilter.filterConfig.getInitParameter(LOG_USER_INFO_PATH); + String logInfoSep = WaffleFilter.filterConfig.getInitParameter(LOG_USER_INFO_SEP); if(logInfoPath == null) { LOGGER.info("SYSTEM HAS REGISTERED TO PERFORM A USER FILE LOG BUT NOT FILE PATH HAS BEEN ENTERED!!!"); LOGGER.info("SYSTEM HAS REGISTERED TO PERFORM A USER FILE LOG BUT NOT FILE PATH HAS BEEN ENTERED!!!"); @@ -132,7 +132,7 @@ private void setInitParams(ServletRequest arg0) { } boolean countUsers = false; - String countUsersStr = this.filterConfig.getInitParameter(COUNT_USER_ENTRY); + String countUsersStr = WaffleFilter.filterConfig.getInitParameter(COUNT_USER_ENTRY); if(countUsersStr != null) { countUsers = Boolean.parseBoolean(countUsersStr); } else { @@ -140,7 +140,7 @@ private void setInitParams(ServletRequest arg0) { } if(countUsers) { - String countDatabaseId = this.filterConfig.getInitParameter(COUNT_USER_ENTRY_DATABASE); + String countDatabaseId = WaffleFilter.filterConfig.getInitParameter(COUNT_USER_ENTRY_DATABASE); if(countDatabaseId == null) { LOGGER.info("SYSTEM HAS REGISTERED TO PERFORM A COUNT BUT NO DATABASE ID HAS BEEN ENTERED!!!"); LOGGER.info("SYSTEM HAS REGISTERED TO PERFORM A COUNT BUT NO DATABASE ID HAS BEEN ENTERED!!!"); From f0cb300d938aeef960008748112477593a9c5ae3 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 19 May 2020 23:47:28 +0000 Subject: [PATCH 0595/1906] UPDATE ::: Moving to latest version of quartz scheduler git-svn-id: svn://107.170.10.188:8080/Monolith/dev@38807 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: d328fa8200a0eafe9c0bcf85b923b804b8ba689a --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 72842a053..d0282333f 100644 --- a/pom.xml +++ b/pom.xml @@ -2468,12 +2468,12 @@ org.quartz-scheduler quartz - 2.2.1 + 2.3.2 org.quartz-scheduler quartz-jobs - 2.2.1 + 2.3.2 From de466e869b85a24d035a70714ea6eeec55233953 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 22 May 2020 23:20:04 +0000 Subject: [PATCH 0596/1906] UPDATE ::: Moving from GET to POST. TODO ::: Need to update the BE to be a POST and parse the body git-svn-id: svn://107.170.10.188:8080/Monolith/dev@38863 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 1dd35914026e65cafbd6d651123497a9d34825c6 --- WebContent/share/index.html | 96 ++++++++++++++++++++----------------- 1 file changed, 51 insertions(+), 45 deletions(-) diff --git a/WebContent/share/index.html b/WebContent/share/index.html index 684e51f5c..3b1a8ba24 100644 --- a/WebContent/share/index.html +++ b/WebContent/share/index.html @@ -179,57 +179,63 @@ From 9a3e9e24135fb8e7fc6beecc734e4f760fe57e3f Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 26 May 2020 21:45:33 +0000 Subject: [PATCH 0597/1906] UPDATE ::: Converted the tableau web data connector logic to work as a POST instead of a GET git-svn-id: svn://107.170.10.188:8080/Monolith/dev@38882 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: d05c967aac9417aba50915daa74ccb9468c3df53 --- src/prerna/semoss/web/services/local/RunInsight.java | 4 ++-- .../semoss/web/services/local/UserResource.java | 11 +++++------ 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/prerna/semoss/web/services/local/RunInsight.java b/src/prerna/semoss/web/services/local/RunInsight.java index eb19ce082..1e3d6a5db 100644 --- a/src/prerna/semoss/web/services/local/RunInsight.java +++ b/src/prerna/semoss/web/services/local/RunInsight.java @@ -4,7 +4,7 @@ import java.util.Map; import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.GET; +import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.Context; @@ -26,7 +26,7 @@ public void dropInsight(boolean drop) { this.drop = drop; } - @GET + @POST @Path("/getTableData") @Produces("application/json") public Response getInsightData(@Context HttpServletRequest request) { diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index 6def3b05d..537979802 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -58,7 +58,6 @@ import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; import javax.ws.rs.core.Context; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.NewCookie; @@ -88,7 +87,6 @@ import prerna.auth.utils.SecurityAdminUtils; import prerna.auth.utils.SecurityUpdateUtils; import prerna.ds.py.FilePyTranslator; -import prerna.ds.py.PyExecutorThread; import prerna.ds.py.PyTranslator; import prerna.ds.py.PyUtils; import prerna.ds.py.TCPPyTranslator; @@ -1708,13 +1706,14 @@ private void setAccessTokenDetails(AccessToken token, Map ret) { * Sharing session */ - @GET + @POST @Produces("application/json") @Path("/cookie") - public StreamingOutput manCookie(@Context HttpServletRequest request, @Context HttpServletResponse response, - @QueryParam("i") String insightId, @QueryParam("s") String secret) { - // https://nuwanbando.com/2010/05/07/sharing-https-http-sessions-in-tomcat/ + public StreamingOutput manCookie(@Context HttpServletRequest request, @Context HttpServletResponse response) { + String insightId = request.getParameter("i"); + String secret = request.getParameter("s"); + // https://nuwanbando.com/2010/05/07/sharing-https-http-sessions-in-tomcat/ /* * When the user clicks on connect to tableau.. I need to give the user a link * to that insight primarily From cefed2a21511e55ecb281a08d808009f68981531 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 2 Jun 2020 13:10:28 +0000 Subject: [PATCH 0598/1906] UPDATE ::: Logging when a user logouts from a provider UPDATE ::: Renaming the logger on the insight git-svn-id: svn://107.170.10.188:8080/Monolith/dev@38962 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 995ab834ae047bdf54574e09d6efb3143c7cca0e --- .../web/services/local/UserResource.java | 234 ++++++++---------- 1 file changed, 107 insertions(+), 127 deletions(-) diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index 537979802..9099b91e3 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -225,45 +225,13 @@ public Response logout(@PathParam("provider") String provider, @Context HttpServ HttpSession session = request.getSession(); User thisUser = (User) session.getAttribute(Constants.SESSION_USER); - - // Stop R - if (thisUser != null) { - IRUserConnection rserve = thisUser.getRcon(); - if (rserve != null) { - ExecutorService executor = Executors.newSingleThreadExecutor(); - try { - executor.submit(new Callable() { - @Override - public Void call() throws Exception { - try { - rserve.stopR(); - } catch (Exception e) { - logger.warn("Unable to stop R."); - } - return null; - } - }); - } finally { - executor.shutdown(); - } - } - } - - // stop python too - if (PyUtils.pyEnabled()) { - PyTranslator pyt = thisUser.getPyTranslator(false); - - if (pyt instanceof prerna.ds.py.PyTranslator) - PyUtils.getInstance().killPyThread(pyt.getPy()); - if (pyt instanceof FilePyTranslator && thisUser != null) - PyUtils.getInstance().killTempTupleSpace(thisUser); - if (pyt instanceof TCPPyTranslator) { - NettyClient nc = thisUser.getPyServe(); - String dir = thisUser.pyTupleSpace; - nc.stopPyServe(dir); - } + // log the logout + if(thisUser != null) { + logger.info(User.getSingleLogginName(thisUser) + " is logging out of provider " + provider + " from session " + request.getSession().getId()); + } else { + logger.info("Unknown user is logging out of provider " + provider + " from session " + request.getSession().getId()); } - + if (provider.equalsIgnoreCase("ALL")) { // remove the user from session call it a day request.getSession().removeAttribute(Constants.SESSION_USER); @@ -294,76 +262,116 @@ public Void call() throws Exception { } } - // if there are no users and there is security - // redirect the user - // and invalidate the session - if (noUser && AbstractSecurityUtils.securityEnabled()) { - logger.info("User is no longer logged in"); - logger.info("Removing user object from session"); - session.removeAttribute(Constants.SESSION_USER); - // well, you have logged out and we always require a login - // so i will redirect you - response.setStatus(302); - - String customUrl = DBLoader.getCustomLogoutUrl(); - if (customUrl != null && !customUrl.isEmpty()) { - response.setHeader("redirect", customUrl); - response.sendError(302, "Need to redirect to " + customUrl); - } else { - String redirectUrl = request.getHeader("referer"); - if (DBLoader.useLogoutPage()) { - String scheme = request.getScheme(); - if (!scheme.trim().equalsIgnoreCase("https") && - !scheme.trim().equalsIgnoreCase("http")) { - throw new IllegalArgumentException("scheme is invalid, please input proper scheme"); - } - String serverName = request.getServerName(); // hostname.com - int serverPort = request.getServerPort(); // 8080 - String contextPath = request.getContextPath(); // /Monolith - - redirectUrl = ""; - redirectUrl += scheme + "://" + serverName; - if (serverPort != 80 && serverPort != 443) { - redirectUrl += ":" + serverPort; + if(noUser) { + // stop R + if (thisUser != null) { + IRUserConnection rserve = thisUser.getRcon(); + if (rserve != null) { + ExecutorService executor = Executors.newSingleThreadExecutor(); + try { + executor.submit(new Callable() { + @Override + public Void call() throws Exception { + try { + rserve.stopR(); + } catch (Exception e) { + logger.warn("Unable to stop R."); + } + return null; + } + }); + } finally { + executor.shutdown(); } - redirectUrl += contextPath + "/logout/"; - response.setHeader("redirect", redirectUrl); - response.sendError(302, "Need to redirect to " + redirectUrl); - } else { - redirectUrl = redirectUrl + "#!/login"; - String encodedRedirectUrl = Encode.forHtml(redirectUrl); - response.setHeader("redirect", encodedRedirectUrl); - response.sendError(302, "Need to redirect to " + encodedRedirectUrl); } } - // remove the cookie from the browser - // for the session id - logger.info("Removing session token"); - Cookie[] cookies = request.getCookies(); - if (cookies != null) { - for (Cookie c : cookies) { - if (DBLoader.getSessionIdKey().equals(c.getName())) { - // we need to null this out - Cookie nullC = new Cookie(c.getName(), c.getValue()); - nullC.setPath(c.getPath()); - nullC.setSecure(request.isSecure()); - nullC.setHttpOnly(true); - nullC.setVersion(c.getVersion()); - if (c.getDomain() != null) { - nullC.setDomain(c.getDomain()); + // stop python too + if (PyUtils.pyEnabled()) { + PyTranslator pyt = thisUser.getPyTranslator(false); + + if (pyt instanceof prerna.ds.py.PyTranslator) + PyUtils.getInstance().killPyThread(pyt.getPy()); + if (pyt instanceof FilePyTranslator && thisUser != null) + PyUtils.getInstance().killTempTupleSpace(thisUser); + if (pyt instanceof TCPPyTranslator) { + NettyClient nc = thisUser.getPyServe(); + String dir = thisUser.pyTupleSpace; + nc.stopPyServe(dir); + } + } + + // if there are no users and there is security + // redirect the user + // and invalidate the session + if (AbstractSecurityUtils.securityEnabled()) { + logger.info("User is no longer logged in"); + logger.info("Removing user object from session"); + session.removeAttribute(Constants.SESSION_USER); + // well, you have logged out and we always require a login + // so i will redirect you + response.setStatus(302); + + String customUrl = DBLoader.getCustomLogoutUrl(); + if (customUrl != null && !customUrl.isEmpty()) { + response.setHeader("redirect", customUrl); + response.sendError(302, "Need to redirect to " + customUrl); + } else { + String redirectUrl = request.getHeader("referer"); + if (DBLoader.useLogoutPage()) { + String scheme = request.getScheme(); + if (!scheme.trim().equalsIgnoreCase("https") && + !scheme.trim().equalsIgnoreCase("http")) { + throw new IllegalArgumentException("scheme is invalid, please input proper scheme"); + } + String serverName = request.getServerName(); // hostname.com + int serverPort = request.getServerPort(); // 8080 + String contextPath = request.getContextPath(); // /Monolith + + redirectUrl = ""; + redirectUrl += scheme + "://" + serverName; + if (serverPort != 80 && serverPort != 443) { + redirectUrl += ":" + serverPort; } - nullC.setMaxAge(0); - response.addCookie(nullC); + redirectUrl += contextPath + "/logout/"; + response.setHeader("redirect", redirectUrl); + response.sendError(302, "Need to redirect to " + redirectUrl); + } else { + redirectUrl = redirectUrl + "#!/login"; + String encodedRedirectUrl = Encode.forHtml(redirectUrl); + response.setHeader("redirect", encodedRedirectUrl); + response.sendError(302, "Need to redirect to " + encodedRedirectUrl); } } - } - // invalidate the session - session.invalidate(); - return null; - } + // remove the cookie from the browser + // for the session id + logger.info("Removing session token"); + Cookie[] cookies = request.getCookies(); + if (cookies != null) { + for (Cookie c : cookies) { + if (DBLoader.getSessionIdKey().equals(c.getName())) { + // we need to null this out + Cookie nullC = new Cookie(c.getName(), c.getValue()); + nullC.setPath(c.getPath()); + nullC.setSecure(request.isSecure()); + nullC.setHttpOnly(true); + nullC.setVersion(c.getVersion()); + if (c.getDomain() != null) { + nullC.setDomain(c.getDomain()); + } + nullC.setMaxAge(0); + response.addCookie(nullC); + } + } + } + // invalidate the session + session.invalidate(); + return null; + } + } + Map ret = new Hashtable<>(); ret.put("success", removed); return WebUtility.getResponse(ret, 200); @@ -1460,34 +1468,6 @@ public Response loginNative(@Context HttpServletRequest request, @Context HttpSe return WebUtility.getResponse(ret, 200); } - /** - * Logs user out when authenticated in a native way. - */ - @GET - @Produces("application/json") - @Path("/logout") - public Response logoutNative(@Context HttpServletRequest request) throws IOException { - Hashtable ret = new Hashtable<>(); - try { - if (request.getSession(false) != null) { - HttpSession session = request.getSession(false); - User print = (User) session.getAttribute(Constants.SESSION_USER); - print.dropAccessToken(AuthProvider.NATIVE.name().toUpperCase()); - request.getSession().setAttribute(Constants.SESSION_USER, print); - } else { - ret.put("error", "User is not connected."); - return WebUtility.getResponse(ret, 401); - } - // Only disconnect a connected user. - } catch (Exception ex) { - logger.error(STACKTRACE, ex); - ret.put("error", "Unexpected error."); - return WebUtility.getResponse(ret, 500); - } - ret.put("success", "true"); - return WebUtility.getResponse(ret, 200); - } - /** * Create an user according to the information provided (user name, password, * email) From ef96c1ffe97d8bf7d6b8c0fd44253f616e8eb90c Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 2 Jun 2020 15:39:05 +0000 Subject: [PATCH 0599/1906] UPDATE ::: Pushing updated h2 jar git-svn-id: svn://107.170.10.188:8080/Monolith/dev@38964 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: fb0a1466020c2e6e6747d05befae6a3eb6a22dc7 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d0282333f..5254f21f5 100644 --- a/pom.xml +++ b/pom.xml @@ -2491,7 +2491,7 @@ com.h2database h2 - 1.4.195 + 1.4.200 org.postgresql From 38b50cae86086281252a1089b49639ed1904181e Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 2 Jun 2020 18:12:45 +0000 Subject: [PATCH 0600/1906] BUGFIX ::: Moving back to version of h2 that will not break everything.... git-svn-id: svn://107.170.10.188:8080/Monolith/dev@38966 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 8356d25d9de7f1964273640c0d5a6a59dc3806c3 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 5254f21f5..152bf8ff2 100644 --- a/pom.xml +++ b/pom.xml @@ -2491,7 +2491,7 @@ com.h2database h2 - 1.4.200 + 1.4.199 org.postgresql From 34b5943b86d775f1436189f7f15e0771a973cd5e Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 2 Jun 2020 20:23:44 +0000 Subject: [PATCH 0601/1906] UPDATE ::: More useful logs for stigs on user login/logout UPDATE ::: Adding amazon in auth provider list for upcoming aws saml git-svn-id: svn://107.170.10.188:8080/Monolith/dev@38967 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: aa190f9d1286f594db579005fa3829c00d48aed2 --- .../semoss/web/services/local/ResourceUtility.java | 12 ++++++++++++ .../semoss/web/services/local/UserResource.java | 13 +++++++------ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/prerna/semoss/web/services/local/ResourceUtility.java b/src/prerna/semoss/web/services/local/ResourceUtility.java index ae69d1906..3cb9e9e0d 100644 --- a/src/prerna/semoss/web/services/local/ResourceUtility.java +++ b/src/prerna/semoss/web/services/local/ResourceUtility.java @@ -33,4 +33,16 @@ public static User getUser(@Context HttpServletRequest request) throws IllegalAc return user; } + public static String getClientIp(@Context HttpServletRequest request) { + String remoteAddr = ""; + if (request != null) { + remoteAddr = request.getHeader("X-FORWARDED-FOR"); + if (remoteAddr == null || "".equals(remoteAddr)) { + remoteAddr = request.getRemoteAddr(); + } + } + + return remoteAddr; + } + } diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index 9099b91e3..cdfec29fd 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -227,9 +227,9 @@ public Response logout(@PathParam("provider") String provider, @Context HttpServ User thisUser = (User) session.getAttribute(Constants.SESSION_USER); // log the logout if(thisUser != null) { - logger.info(User.getSingleLogginName(thisUser) + " is logging out of provider " + provider + " from session " + request.getSession().getId()); + logger.info("IP " + ResourceUtility.getClientIp(request) + " : " + User.getSingleLogginName(thisUser) + " is logging out of provider " + provider + " from session " + request.getSession().getId()); } else { - logger.info("Unknown user is logging out of provider " + provider + " from session " + request.getSession().getId()); + logger.info("IP " + ResourceUtility.getClientIp(request) + " : Unknown user is logging out of provider " + provider + " from session " + request.getSession().getId()); } if (provider.equalsIgnoreCase("ALL")) { @@ -305,7 +305,7 @@ public Void call() throws Exception { // redirect the user // and invalidate the session if (AbstractSecurityUtils.securityEnabled()) { - logger.info("User is no longer logged in"); + logger.info("IP " + ResourceUtility.getClientIp(request) + " : User is logged out from all providers in from session " + request.getSession().getId()); logger.info("Removing user object from session"); session.removeAttribute(Constants.SESSION_USER); // well, you have logged out and we always require a login @@ -387,10 +387,7 @@ private void addAccessToken(AccessToken token, HttpServletRequest request) { User semossUser = null; HttpSession session = request.getSession(); Object user = session.getAttribute(Constants.SESSION_USER); - - // all of this is now in the user - if (user != null) { semossUser = (User) user; } else { @@ -399,6 +396,10 @@ private void addAccessToken(AccessToken token, HttpServletRequest request) { semossUser.setAccessToken(token); semossUser.setAnonymous(false); request.getSession().setAttribute(Constants.SESSION_USER, semossUser); + + // log user sign-in + logger.info("IP " + ResourceUtility.getClientIp(request) + " : " + User.getSingleLogginName(semossUser) + " is logging in with provider " + token.getProvider() + " from session " + request.getSession().getId()); + // add new users into the database SecurityUpdateUtils.addOAuthUser(token); } From b080ba219529d85331c1ebcda375eea194a401b9 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 2 Jun 2020 20:34:44 +0000 Subject: [PATCH 0602/1906] UPDATE ::: More useful logs for stigs on user login/logout git-svn-id: svn://107.170.10.188:8080/Monolith/dev@38969 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 233a5f4bedd361f3c8be9ae9b198c11dc08c2093 --- src/prerna/web/conf/AnonymousUserFilter.java | 23 +++++++---- src/prerna/web/conf/CACFilter.java | 9 +++-- src/prerna/web/conf/PIVFilter.java | 9 +++-- src/prerna/web/conf/WaffleFilter.java | 40 +++++++++++--------- 4 files changed, 47 insertions(+), 34 deletions(-) diff --git a/src/prerna/web/conf/AnonymousUserFilter.java b/src/prerna/web/conf/AnonymousUserFilter.java index 9fd843a13..2e53b4ad2 100644 --- a/src/prerna/web/conf/AnonymousUserFilter.java +++ b/src/prerna/web/conf/AnonymousUserFilter.java @@ -15,12 +15,17 @@ import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; +import org.apache.log4j.LogManager; +import org.apache.log4j.Logger; + import prerna.auth.User; import prerna.auth.utils.AbstractSecurityUtils; +import prerna.semoss.web.services.local.ResourceUtility; import prerna.util.Constants; public class AnonymousUserFilter implements Filter, Serializable { + private static final Logger logger = LogManager.getLogger(AnonymousUserFilter.class); private static final long serialVersionUID = -4657347128078864456L; @Override @@ -28,11 +33,10 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 if(AbstractSecurityUtils.anonymousUsersEnabled()) { HttpSession session = ((HttpServletRequest)arg0).getSession(true); - User semossUser = null; - Object user = session.getAttribute(Constants.SESSION_USER); + User user = (User) session.getAttribute(Constants.SESSION_USER); if(user == null) { - semossUser = new User(); - semossUser.setAnonymous(true); + user = new User(); + user.setAnonymous(true); String cookieToFind = DBLoader.getSessionIdKey() + "_unk"; Cookie[] cookies = ((HttpServletRequest) arg0).getCookies(); @@ -41,7 +45,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 for(Cookie c : cookies) { if(c.getName().equals(cookieToFind)) { String uId = c.getValue(); - semossUser.setAnonymousId(uId); + user.setAnonymousId(uId); // found the cookie // no need to continue loop break; @@ -49,10 +53,10 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 } } - if(semossUser.getAnonymousId() == null) { + if(user.getAnonymousId() == null) { // set a new id + add a cookie String uId = "UNK_" + UUID.randomUUID().toString(); - semossUser.setAnonymousId(uId); + user.setAnonymousId(uId); Cookie c = new Cookie(cookieToFind, uId); // max age of 10years... @@ -63,7 +67,10 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 ((HttpServletResponse)arg1).addCookie(c); } // add to session - session.setAttribute(Constants.SESSION_USER, semossUser); + session.setAttribute(Constants.SESSION_USER, user); + + // log the user login + logger.info("IP " + ResourceUtility.getClientIp((HttpServletRequest)arg0) + " : Anonymous user with id " + User.getSingleLogginName(user) + " logged in from session " + session.getId()); } } diff --git a/src/prerna/web/conf/CACFilter.java b/src/prerna/web/conf/CACFilter.java index 485ae6aad..0dcf7c427 100644 --- a/src/prerna/web/conf/CACFilter.java +++ b/src/prerna/web/conf/CACFilter.java @@ -35,6 +35,7 @@ import prerna.engine.impl.rdbms.RDBMSNativeEngine; import prerna.forms.FormBuilder; import prerna.rdf.engine.wrappers.WrapperManager; +import prerna.semoss.web.services.local.ResourceUtility; import prerna.util.Constants; import prerna.util.Utility; import prerna.web.conf.util.CACTrackingUtil; @@ -202,11 +203,11 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 // are we logging their information? if(userLogger != null && !token.getName().equals("TOPAZ")) { // grab the ip address - String ipAddress1 = ((HttpServletRequest)arg0).getHeader("X-FORWARDED-FOR"); - String ipAddress2 = ((HttpServletRequest)arg0).getRemoteAddr(); - - userLogger.addToQueue(new String[] {email, name, LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")), ipAddress1, ipAddress2}); + userLogger.addToQueue(new String[] {email, name, LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")), ResourceUtility.getClientIp((HttpServletRequest)arg0)}); } + + // log the user login + logger.info("IP " + ResourceUtility.getClientIp((HttpServletRequest)arg0) + " : " + User.getSingleLogginName(user) + " is logging in with provider " + token.getProvider() + " from session " + session.getId()); } } } diff --git a/src/prerna/web/conf/PIVFilter.java b/src/prerna/web/conf/PIVFilter.java index 2488cbc54..e3170bfc2 100644 --- a/src/prerna/web/conf/PIVFilter.java +++ b/src/prerna/web/conf/PIVFilter.java @@ -25,6 +25,7 @@ import prerna.auth.AuthProvider; import prerna.auth.User; import prerna.auth.utils.SecurityUpdateUtils; +import prerna.semoss.web.services.local.ResourceUtility; import prerna.util.Constants; import prerna.util.Utility; import prerna.web.conf.util.CACTrackingUtil; @@ -140,11 +141,11 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 // are we logging their information? if(userLogger != null) { // grab the ip address - String ipAddress1 = ((HttpServletRequest)arg0).getHeader("X-FORWARDED-FOR"); - String ipAddress2 = ((HttpServletRequest)arg0).getRemoteAddr(); - - userLogger.addToQueue(new String[] {email, name, LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")), ipAddress1, ipAddress2}); + userLogger.addToQueue(new String[] {email, name, LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")), ResourceUtility.getClientIp((HttpServletRequest)arg0)}); } + + // log the user login + logger.info("IP " + ResourceUtility.getClientIp((HttpServletRequest)arg0) + " : " + User.getSingleLogginName(user) + " is logging in with provider " + token.getProvider() + " from session " + session.getId()); } } } diff --git a/src/prerna/web/conf/WaffleFilter.java b/src/prerna/web/conf/WaffleFilter.java index 06d0cb21e..78ae0f14c 100644 --- a/src/prerna/web/conf/WaffleFilter.java +++ b/src/prerna/web/conf/WaffleFilter.java @@ -22,13 +22,14 @@ import prerna.auth.AuthProvider; import prerna.auth.User; import prerna.auth.utils.SecurityUpdateUtils; +import prerna.semoss.web.services.local.ResourceUtility; import prerna.util.Constants; import prerna.web.conf.util.CACTrackingUtil; import prerna.web.conf.util.UserFileLogUtil; public class WaffleFilter implements Filter { - private static final Logger LOGGER = LogManager.getLogger(WaffleFilter.class.getName()); + private static final Logger logger = LogManager.getLogger(WaffleFilter.class.getName()); // filter init params private static final String AUTO_ADD = "autoAdd"; @@ -63,7 +64,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 token.setProvider(AuthProvider.WINDOWS_USER); token.setId(id); token.setName(name); - LOGGER.info("Valid request coming from user " + token.getName()); + logger.info("Valid request coming from user " + token.getName()); // add the user if they do not exist if(WaffleFilter.autoAdd) { SecurityUpdateUtils.addOAuthUser(token); @@ -81,6 +82,9 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 user.setAccessToken(token); session.setAttribute(Constants.SESSION_USER, user); + + // log the user login + logger.info("IP " + ResourceUtility.getClientIp((HttpServletRequest)arg0) + " : " + User.getSingleLogginName(user) + " is logging in with provider " + token.getProvider() + " from session " + session.getId()); } arg2.doFilter(arg0, arg1); @@ -116,18 +120,18 @@ private void setInitParams(ServletRequest arg0) { String logInfoPath = WaffleFilter.filterConfig.getInitParameter(LOG_USER_INFO_PATH); String logInfoSep = WaffleFilter.filterConfig.getInitParameter(LOG_USER_INFO_SEP); if(logInfoPath == null) { - LOGGER.info("SYSTEM HAS REGISTERED TO PERFORM A USER FILE LOG BUT NOT FILE PATH HAS BEEN ENTERED!!!"); - LOGGER.info("SYSTEM HAS REGISTERED TO PERFORM A USER FILE LOG BUT NOT FILE PATH HAS BEEN ENTERED!!!"); - LOGGER.info("SYSTEM HAS REGISTERED TO PERFORM A USER FILE LOG BUT NOT FILE PATH HAS BEEN ENTERED!!!"); - LOGGER.info("SYSTEM HAS REGISTERED TO PERFORM A USER FILE LOG BUT NOT FILE PATH HAS BEEN ENTERED!!!"); + logger.info("SYSTEM HAS REGISTERED TO PERFORM A USER FILE LOG BUT NOT FILE PATH HAS BEEN ENTERED!!!"); + logger.info("SYSTEM HAS REGISTERED TO PERFORM A USER FILE LOG BUT NOT FILE PATH HAS BEEN ENTERED!!!"); + logger.info("SYSTEM HAS REGISTERED TO PERFORM A USER FILE LOG BUT NOT FILE PATH HAS BEEN ENTERED!!!"); + logger.info("SYSTEM HAS REGISTERED TO PERFORM A USER FILE LOG BUT NOT FILE PATH HAS BEEN ENTERED!!!"); } try { userLogger = UserFileLogUtil.getInstance(logInfoPath, logInfoSep); } catch(Exception e) { - LOGGER.info(e.getMessage()); - LOGGER.info(e.getMessage()); - LOGGER.info(e.getMessage()); - LOGGER.info(e.getMessage()); + logger.info(e.getMessage()); + logger.info(e.getMessage()); + logger.info(e.getMessage()); + logger.info(e.getMessage()); } } @@ -142,18 +146,18 @@ private void setInitParams(ServletRequest arg0) { if(countUsers) { String countDatabaseId = WaffleFilter.filterConfig.getInitParameter(COUNT_USER_ENTRY_DATABASE); if(countDatabaseId == null) { - LOGGER.info("SYSTEM HAS REGISTERED TO PERFORM A COUNT BUT NO DATABASE ID HAS BEEN ENTERED!!!"); - LOGGER.info("SYSTEM HAS REGISTERED TO PERFORM A COUNT BUT NO DATABASE ID HAS BEEN ENTERED!!!"); - LOGGER.info("SYSTEM HAS REGISTERED TO PERFORM A COUNT BUT NO DATABASE ID HAS BEEN ENTERED!!!"); - LOGGER.info("SYSTEM HAS REGISTERED TO PERFORM A COUNT BUT NO DATABASE ID HAS BEEN ENTERED!!!"); + logger.info("SYSTEM HAS REGISTERED TO PERFORM A COUNT BUT NO DATABASE ID HAS BEEN ENTERED!!!"); + logger.info("SYSTEM HAS REGISTERED TO PERFORM A COUNT BUT NO DATABASE ID HAS BEEN ENTERED!!!"); + logger.info("SYSTEM HAS REGISTERED TO PERFORM A COUNT BUT NO DATABASE ID HAS BEEN ENTERED!!!"); + logger.info("SYSTEM HAS REGISTERED TO PERFORM A COUNT BUT NO DATABASE ID HAS BEEN ENTERED!!!"); } try { tracker = CACTrackingUtil.getInstance(countDatabaseId); } catch(Exception e) { - LOGGER.info(e.getMessage()); - LOGGER.info(e.getMessage()); - LOGGER.info(e.getMessage()); - LOGGER.info(e.getMessage()); + logger.info(e.getMessage()); + logger.info(e.getMessage()); + logger.info(e.getMessage()); + logger.info(e.getMessage()); } } } From c17f5cd2bb079fb38ba642b1ec1bae7cba79a6c0 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 2 Jun 2020 22:15:19 +0000 Subject: [PATCH 0603/1906] UPDATE ::: Standardizing some of the login/logout/form logs to be the same format git-svn-id: svn://107.170.10.188:8080/Monolith/dev@38974 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 33deb1c126bd4dd61d4de8a97445631a322b25f6 --- src/prerna/semoss/web/form/FormResource.java | 21 ++++++++++++++++++- .../web/services/local/ResourceUtility.java | 12 +++++++++++ .../web/services/local/UserResource.java | 13 +++++++----- src/prerna/web/conf/CACFilter.java | 2 +- src/prerna/web/conf/PIVFilter.java | 2 +- src/prerna/web/conf/WaffleFilter.java | 2 +- 6 files changed, 43 insertions(+), 9 deletions(-) diff --git a/src/prerna/semoss/web/form/FormResource.java b/src/prerna/semoss/web/form/FormResource.java index 60cdc19fa..5ab677bd8 100644 --- a/src/prerna/semoss/web/form/FormResource.java +++ b/src/prerna/semoss/web/form/FormResource.java @@ -28,6 +28,7 @@ import prerna.forms.FormFactory; import prerna.nameserver.utility.MasterDatabaseUtility; import prerna.rdf.engine.wrappers.WrapperManager; +import prerna.semoss.web.services.local.ResourceUtility; import prerna.util.Constants; import prerna.util.Utility; import prerna.web.services.util.WebUtility; @@ -55,11 +56,12 @@ public Response modifyUserAccess(@Context HttpServletRequest request, Multivalue try { throwErrorIfNotAdmin(cacId); } catch (IllegalAccessException e) { + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), cacId, "is trying to modify user access while not being an admin")); Map err = new HashMap(); err.put("errorMessage", e.getMessage()); return WebUtility.getResponse(err, 400); } - + String addOrRemove = form.getFirst("addOrRemove"); String userid = form.getFirst("userid"); String instancename = Utility.cleanString(form.getFirst("instanceName"), true); @@ -73,15 +75,24 @@ public Response modifyUserAccess(@Context HttpServletRequest request, Multivalue RdbmsQueryBuilder.escapeForSQLStatement(userid) + "' AND INSTANCE_NAME = '" + RdbmsQueryBuilder.escapeForSQLStatement(instancename) + "';"; + + // log the operation + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), cacId, "is removing user " + userid + " from having access to " + instancename)); } else { // remove all of user query = "DELETE FROM FORMS_USER_ACCESS WHERE USER_ID = '" + RdbmsQueryBuilder.escapeForSQLStatement(userid) + "';"; + + // log the operation + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), cacId, "is removing all access for user " + userid)); } } else if (addOrRemove.equals("Add")) { query = "INSERT INTO FORMS_USER_ACCESS (USER_ID, INSTANCE_NAME, IS_SYS_ADMIN) VALUES ('" + RdbmsQueryBuilder.escapeForSQLStatement(userid) + "','" + RdbmsQueryBuilder.escapeForSQLStatement(instancename) + "','" + RdbmsQueryBuilder.escapeForSQLStatement(owner) + "');"; + + // log the operation + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), cacId, "is adding user " + userid + " to have access to " + instancename)); } else { return WebUtility.getResponse("Error: need to specify Add or Remove", 400); } @@ -116,6 +127,7 @@ public Response renameInstance(@Context HttpServletRequest request, MultivaluedM try { throwErrorIfNotAdmin(cacId); } catch (IllegalAccessException e) { + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), cacId, "is trying to rename an instance while not being an admin")); Map err = new HashMap(); err.put("errorMessage", e.getMessage()); return WebUtility.getResponse(err, 400); @@ -129,6 +141,9 @@ public Response renameInstance(@Context HttpServletRequest request, MultivaluedM deleteInstanceBoolean = Boolean.parseBoolean(form.getFirst("deleteInstanceBoolean")); } + // log the operation + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), cacId, "is renaming " + origUri + " to " + newUri)); + IEngine coreEngine = Utility.getEngine(MasterDatabaseUtility.testEngineIdIfAlias(dbName)); AbstractFormBuilder formbuilder = FormFactory.getFormBuilder(coreEngine); formbuilder.modifyInstanceValue(origUri, newUri, deleteInstanceBoolean); @@ -154,6 +169,7 @@ public Response certifyInstance(@Context HttpServletRequest request, Multivalued try { throwErrorIfNotSysAdmin(cacId, instanceName); + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), cacId, "is trying to certify " + instanceName + " when he is not the system admin for the system")); } catch (IllegalAccessException e) { Map err = new HashMap(); err.put("errorMessage", e.getMessage()); @@ -164,6 +180,9 @@ public Response certifyInstance(@Context HttpServletRequest request, Multivalued AbstractFormBuilder formbuilder = FormFactory.getFormBuilder(coreEngine); formbuilder.setUser(cacId); formbuilder.certifyInstance(instanceType, instanceName); + + // log the operation + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), cacId, "has certified " + instanceName)); return WebUtility.getResponse("success", 200); } diff --git a/src/prerna/semoss/web/services/local/ResourceUtility.java b/src/prerna/semoss/web/services/local/ResourceUtility.java index 3cb9e9e0d..390d398bd 100644 --- a/src/prerna/semoss/web/services/local/ResourceUtility.java +++ b/src/prerna/semoss/web/services/local/ResourceUtility.java @@ -44,5 +44,17 @@ public static String getClientIp(@Context HttpServletRequest request) { return remoteAddr; } + + /** + * Standardized format for the message + * @param request + * @param session + * @param userId + * @param message + * @return + */ + public static String getLogMessage(HttpServletRequest request, HttpSession session, String userId, String message) { + return "IP = " + ResourceUtility.getClientIp(request) + " : Session = " + session.getId() + " : ID = " + userId + " " + message; + } } diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index cdfec29fd..ccdd60cc6 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -227,9 +227,10 @@ public Response logout(@PathParam("provider") String provider, @Context HttpServ User thisUser = (User) session.getAttribute(Constants.SESSION_USER); // log the logout if(thisUser != null) { - logger.info("IP " + ResourceUtility.getClientIp(request) + " : " + User.getSingleLogginName(thisUser) + " is logging out of provider " + provider + " from session " + request.getSession().getId()); + // log the user login + logger.info(ResourceUtility.getLogMessage(request, session, User.getSingleLogginName(thisUser), "is logging out of provider " + provider)); } else { - logger.info("IP " + ResourceUtility.getClientIp(request) + " : Unknown user is logging out of provider " + provider + " from session " + request.getSession().getId()); + logger.info(ResourceUtility.getLogMessage(request, session, "Unknown user", "is logging out of provider " + provider)); } if (provider.equalsIgnoreCase("ALL")) { @@ -305,7 +306,7 @@ public Void call() throws Exception { // redirect the user // and invalidate the session if (AbstractSecurityUtils.securityEnabled()) { - logger.info("IP " + ResourceUtility.getClientIp(request) + " : User is logged out from all providers in from session " + request.getSession().getId()); + logger.info(ResourceUtility.getLogMessage(request, session, User.getSingleLogginName(thisUser), "has logged out from all providers in the session")); logger.info("Removing user object from session"); session.removeAttribute(Constants.SESSION_USER); // well, you have logged out and we always require a login @@ -397,8 +398,8 @@ private void addAccessToken(AccessToken token, HttpServletRequest request) { semossUser.setAnonymous(false); request.getSession().setAttribute(Constants.SESSION_USER, semossUser); - // log user sign-in - logger.info("IP " + ResourceUtility.getClientIp(request) + " : " + User.getSingleLogginName(semossUser) + " is logging in with provider " + token.getProvider() + " from session " + request.getSession().getId()); + // log the user login + logger.info(ResourceUtility.getLogMessage(request, session, User.getSingleLogginName(semossUser), "is logging in with provider " + token.getProvider())); // add new users into the database SecurityUpdateUtils.addOAuthUser(token); @@ -1453,6 +1454,8 @@ public Response loginNative(@Context HttpServletRequest request, @Context HttpSe authToken.setEmail(email); addAccessToken(authToken, request); + // log the log in + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), id, " is logging out of provider " + AuthProvider.NATIVE)); if (!disableRedirect) { setMainPageRedirect(request, response, redirect); } diff --git a/src/prerna/web/conf/CACFilter.java b/src/prerna/web/conf/CACFilter.java index 0dcf7c427..9a9638a59 100644 --- a/src/prerna/web/conf/CACFilter.java +++ b/src/prerna/web/conf/CACFilter.java @@ -207,7 +207,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 } // log the user login - logger.info("IP " + ResourceUtility.getClientIp((HttpServletRequest)arg0) + " : " + User.getSingleLogginName(user) + " is logging in with provider " + token.getProvider() + " from session " + session.getId()); + logger.info(ResourceUtility.getLogMessage((HttpServletRequest)arg0, session, User.getSingleLogginName(user), "is logging in with provider " + token.getProvider())); } } } diff --git a/src/prerna/web/conf/PIVFilter.java b/src/prerna/web/conf/PIVFilter.java index e3170bfc2..5560e0d67 100644 --- a/src/prerna/web/conf/PIVFilter.java +++ b/src/prerna/web/conf/PIVFilter.java @@ -145,7 +145,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 } // log the user login - logger.info("IP " + ResourceUtility.getClientIp((HttpServletRequest)arg0) + " : " + User.getSingleLogginName(user) + " is logging in with provider " + token.getProvider() + " from session " + session.getId()); + logger.info(ResourceUtility.getLogMessage((HttpServletRequest)arg0, session, User.getSingleLogginName(user), "is logging in with provider " + token.getProvider())); } } } diff --git a/src/prerna/web/conf/WaffleFilter.java b/src/prerna/web/conf/WaffleFilter.java index 78ae0f14c..ca9bfadb5 100644 --- a/src/prerna/web/conf/WaffleFilter.java +++ b/src/prerna/web/conf/WaffleFilter.java @@ -84,7 +84,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 session.setAttribute(Constants.SESSION_USER, user); // log the user login - logger.info("IP " + ResourceUtility.getClientIp((HttpServletRequest)arg0) + " : " + User.getSingleLogginName(user) + " is logging in with provider " + token.getProvider() + " from session " + session.getId()); + logger.info(ResourceUtility.getLogMessage((HttpServletRequest)arg0, session, User.getSingleLogginName(user), "is logging in with provider " + token.getProvider())); } arg2.doFilter(arg0, arg1); From a40c17fae699844cb5515cca4ed5cbf41255d480 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 2 Jun 2020 22:46:42 +0000 Subject: [PATCH 0604/1906] UPDATE ::: Adding logging when admin is going through and updating user permissions git-svn-id: svn://107.170.10.188:8080/Monolith/dev@38975 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 7acb5bed1c86b1242e74d00dc925124594b2df59 --- src/prerna/semoss/web/form/FormResource.java | 10 +- .../local/auth/AbstractAdminResource.java | 6 +- .../auth/AdminAppAuthorizationResource.java | 85 ++++++++++---- .../AdminInsightAuthorizationResource.java | 107 +++++++++++++----- 4 files changed, 145 insertions(+), 63 deletions(-) diff --git a/src/prerna/semoss/web/form/FormResource.java b/src/prerna/semoss/web/form/FormResource.java index 5ab677bd8..9d40031b8 100644 --- a/src/prerna/semoss/web/form/FormResource.java +++ b/src/prerna/semoss/web/form/FormResource.java @@ -56,7 +56,7 @@ public Response modifyUserAccess(@Context HttpServletRequest request, Multivalue try { throwErrorIfNotAdmin(cacId); } catch (IllegalAccessException e) { - logger.info(ResourceUtility.getLogMessage(request, request.getSession(), cacId, "is trying to modify user access while not being an admin")); + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), cacId, "is trying to modify user access while not being an admin")); Map err = new HashMap(); err.put("errorMessage", e.getMessage()); return WebUtility.getResponse(err, 400); @@ -127,7 +127,7 @@ public Response renameInstance(@Context HttpServletRequest request, MultivaluedM try { throwErrorIfNotAdmin(cacId); } catch (IllegalAccessException e) { - logger.info(ResourceUtility.getLogMessage(request, request.getSession(), cacId, "is trying to rename an instance while not being an admin")); + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), cacId, "is trying to rename an instance while not being an admin")); Map err = new HashMap(); err.put("errorMessage", e.getMessage()); return WebUtility.getResponse(err, 400); @@ -169,8 +169,8 @@ public Response certifyInstance(@Context HttpServletRequest request, Multivalued try { throwErrorIfNotSysAdmin(cacId, instanceName); - logger.info(ResourceUtility.getLogMessage(request, request.getSession(), cacId, "is trying to certify " + instanceName + " when he is not the system admin for the system")); } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), cacId, "is trying to certify " + instanceName + " when he is not the system admin for the system")); Map err = new HashMap(); err.put("errorMessage", e.getMessage()); return WebUtility.getResponse(err, 400); @@ -269,7 +269,7 @@ private void throwErrorIfNotAdmin(String cacId) throws IllegalAccessException { } } catch (Exception e) { logger.error("Stacktrace: " , e); - } finally { + } finally { if(wrapper != null) { wrapper.cleanUp(); } @@ -296,7 +296,7 @@ private void throwErrorIfNotSysAdmin(String cacId, String system) throws Illegal } } catch (Exception e) { logger.error("Stacktrace: " , e); - } finally { + } finally { if(wrapper != null) { wrapper.cleanUp(); } diff --git a/src/prerna/semoss/web/services/local/auth/AbstractAdminResource.java b/src/prerna/semoss/web/services/local/auth/AbstractAdminResource.java index 599a2a78c..a34afbc52 100644 --- a/src/prerna/semoss/web/services/local/auth/AbstractAdminResource.java +++ b/src/prerna/semoss/web/services/local/auth/AbstractAdminResource.java @@ -5,12 +5,10 @@ import prerna.auth.User; import prerna.auth.utils.SecurityAdminUtils; -import prerna.semoss.web.services.local.ResourceUtility; public class AbstractAdminResource { - - SecurityAdminUtils performAdminCheck(@Context HttpServletRequest request) throws IllegalAccessException { - User user = ResourceUtility.getUser(request); + + SecurityAdminUtils performAdminCheck(@Context HttpServletRequest request, User user) throws IllegalAccessException { SecurityAdminUtils adminUtils = SecurityAdminUtils.getInstance(user); if(adminUtils == null) { throw new IllegalArgumentException("User is not an admin"); diff --git a/src/prerna/semoss/web/services/local/auth/AdminAppAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/AdminAppAuthorizationResource.java index c25179611..8487d7d97 100644 --- a/src/prerna/semoss/web/services/local/auth/AdminAppAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/AdminAppAuthorizationResource.java @@ -16,6 +16,7 @@ import org.apache.log4j.Logger; +import prerna.auth.User; import prerna.auth.utils.SecurityAdminUtils; import prerna.semoss.web.services.local.ResourceUtility; import prerna.web.services.util.WebUtility; @@ -38,9 +39,12 @@ public class AdminAppAuthorizationResource extends AbstractAdminResource { @Path("getApps") public Response getUserApps(@Context HttpServletRequest request) { SecurityAdminUtils adminUtils = null; + User user = null; try { - adminUtils = performAdminCheck(request); + user = ResourceUtility.getUser(request); + adminUtils = performAdminCheck(request, user); } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to get all apps when not an admin")); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 401); @@ -53,12 +57,14 @@ public Response getUserApps(@Context HttpServletRequest request) { @Path("/getAllUserApps") @Produces("application/json") public Response getAllUserDbs(@Context HttpServletRequest request, MultivaluedMap form) { - String userId = form.getFirst("userId"); SecurityAdminUtils adminUtils = null; - + User user = null; + String userId = form.getFirst("userId"); try { - adminUtils = performAdminCheck(request); + user = ResourceUtility.getUser(request); + adminUtils = performAdminCheck(request, user); } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to pull the apps that user " + userId + " has access to when not an admin")); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 401); @@ -78,9 +84,12 @@ public Response getAllUserDbs(@Context HttpServletRequest request, MultivaluedMa @Path("getAppUsers") public Response getAppUsers(@Context HttpServletRequest request, @QueryParam("appId") String appId) { SecurityAdminUtils adminUtils = null; + User user = null; try { - adminUtils = performAdminCheck(request); + user = ResourceUtility.getUser(request); + adminUtils = performAdminCheck(request, user); } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to pull all the users who use app " + appId + " when not an admin")); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 401); @@ -100,18 +109,22 @@ public Response getAppUsers(@Context HttpServletRequest request, @QueryParam("ap @Path("addAppUserPermission") public Response addAppUserPermission(@Context HttpServletRequest request, MultivaluedMap form) { SecurityAdminUtils adminUtils = null; + User user = null; + + String newUserId = form.getFirst("id"); + String appId = form.getFirst("appId"); + String permission = form.getFirst("permission"); + try { - adminUtils = performAdminCheck(request); + user = ResourceUtility.getUser(request); + adminUtils = performAdminCheck(request, user); } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to add user " + newUserId + " to app " + appId + " when not an admin")); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 401); } - String newUserId = form.getFirst("id"); - String appId = form.getFirst("appId"); - String permission = form.getFirst("permission"); - try { adminUtils.addAppUser(newUserId, appId, permission); } catch (Exception e) { @@ -119,6 +132,9 @@ public Response addAppUserPermission(@Context HttpServletRequest request, Multiv errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 400); } + + // log the operation + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has added user " + newUserId + " to app " + appId + " with permission " + permission)); Map ret = new HashMap(); ret.put("success", true); @@ -136,18 +152,22 @@ public Response addAppUserPermission(@Context HttpServletRequest request, Multiv @Path("editAppUserPermission") public Response editAppUserPermission(@Context HttpServletRequest request, MultivaluedMap form) { SecurityAdminUtils adminUtils = null; + User user = null; + + String existingUserId = form.getFirst("id"); + String appId = form.getFirst("appId"); + String newPermission = form.getFirst("permission"); + try { - adminUtils = performAdminCheck(request); + user = ResourceUtility.getUser(request); + adminUtils = performAdminCheck(request, user); } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to edit user " + existingUserId + " permissions for app " + appId + " when not an admin")); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 401); } - String existingUserId = form.getFirst("id"); - String appId = form.getFirst("appId"); - String newPermission = form.getFirst("permission"); - try { adminUtils.editAppUserPermission(existingUserId, appId, newPermission); } catch (Exception e) { @@ -156,6 +176,9 @@ public Response editAppUserPermission(@Context HttpServletRequest request, Multi return WebUtility.getResponse(errorMap, 400); } + // log the operation + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has edited user " + existingUserId + " permission to app " + appId + " with level " + newPermission)); + Map ret = new HashMap(); ret.put("success", true); return WebUtility.getResponse(ret, 200); @@ -172,17 +195,21 @@ public Response editAppUserPermission(@Context HttpServletRequest request, Multi @Path("removeAppUserPermission") public Response removeAppUserPermission(@Context HttpServletRequest request, MultivaluedMap form) { SecurityAdminUtils adminUtils = null; + User user = null; + + String existingUserId = form.getFirst("id"); + String appId = form.getFirst("appId"); + try { - adminUtils = performAdminCheck(request); + user = ResourceUtility.getUser(request); + adminUtils = performAdminCheck(request, user); } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to remove user " + existingUserId + " from having access to app " + appId + " when not an admin")); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 401); } - String existingUserId = form.getFirst("id"); - String appId = form.getFirst("appId"); - try { adminUtils.removeAppUser(existingUserId, appId); } catch (Exception e) { @@ -191,6 +218,9 @@ public Response removeAppUserPermission(@Context HttpServletRequest request, Mul return WebUtility.getResponse(errorMap, 400); } + // log the operation + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has removed user " + existingUserId + " from having access to app " + appId)); + Map ret = new HashMap(); ret.put("success", true); return WebUtility.getResponse(ret, 200); @@ -201,24 +231,33 @@ public Response removeAppUserPermission(@Context HttpServletRequest request, Mul @Path("setAppGlobal") public Response setAppGlobal(@Context HttpServletRequest request, MultivaluedMap form) { SecurityAdminUtils adminUtils = null; + User user = null; + + String appId = form.getFirst("appId"); + boolean isPublic = Boolean.parseBoolean(form.getFirst("public")); + String logPublic = isPublic ? " public " : " private"; + try { - adminUtils = performAdminCheck(request); + user = ResourceUtility.getUser(request); + adminUtils = performAdminCheck(request, user); } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to set the app " + appId + logPublic + " when not an admin")); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 401); } - String engineId = form.getFirst("appId"); - boolean isPublic = Boolean.parseBoolean(form.getFirst("public")); try { - adminUtils.setAppGlobal(engineId, isPublic); + adminUtils.setAppGlobal(appId, isPublic); } catch (Exception e){ logger.error("Stacktrace: ",e); Map errorRet = new HashMap(); errorRet.put("error", "An unexpected error happened. Please try again."); return WebUtility.getResponse(errorRet, 500); } + + // log the operation + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has set the app " + appId + logPublic)); Map ret = new HashMap(); ret.put("success", true); diff --git a/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java index 5197aa75d..f0bbe56da 100644 --- a/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java @@ -14,8 +14,11 @@ import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; +import org.apache.log4j.Logger; + import com.google.gson.Gson; +import prerna.auth.User; import prerna.auth.utils.SecurityAdminUtils; import prerna.cluster.util.ClusterUtil; import prerna.semoss.web.services.local.ResourceUtility; @@ -24,6 +27,8 @@ @Path("/auth/admin/insight") public class AdminInsightAuthorizationResource extends AbstractAdminResource { + private static final Logger logger = Logger.getLogger(AdminInsightAuthorizationResource.class); + /** * Get the user insight permissions for a given insight * @param request @@ -35,9 +40,12 @@ public class AdminInsightAuthorizationResource extends AbstractAdminResource { @Path("getAppInsights") public Response getAppInsights(@Context HttpServletRequest request, @QueryParam("appId") String appId) { SecurityAdminUtils adminUtils = null; + User user = null; try { - adminUtils = performAdminCheck(request); + user = ResourceUtility.getUser(request); + adminUtils = performAdminCheck(request, user); } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to see all the insight for app " + appId + " when not an admin")); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 401); @@ -58,21 +66,24 @@ public Response getAppInsights(@Context HttpServletRequest request, @QueryParam( @Path("deleteAppInsights") public Response deleteAppInsights(@Context HttpServletRequest request, MultivaluedMap form) { SecurityAdminUtils adminUtils = null; + User user = null; + + String appId = form.getFirst("appId"); + Gson gson = new Gson(); + List insightIds = gson.fromJson(form.getFirst("insightId"), List.class); + try { - adminUtils = performAdminCheck(request); + user = ResourceUtility.getUser(request); + adminUtils = performAdminCheck(request, user); } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to delete insight from app " + appId + " when not an admin")); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 401); } - String appId = form.getFirst("appId"); - Gson gson = new Gson(); - List insightIds = gson.fromJson(form.getFirst("insightId"), List.class); - try { adminUtils.deleteAppInsights(appId, insightIds); - // since modifying insight list // need to push to cloud storage ClusterUtil.reactorPushApp(appId); @@ -98,9 +109,12 @@ public Response deleteAppInsights(@Context HttpServletRequest request, Multivalu @Path("getInsightUsers") public Response getInsightUsers(@Context HttpServletRequest request, @QueryParam("appId") String appId, @QueryParam("insightId") String insightId) { SecurityAdminUtils adminUtils = null; + User user = null; try { - adminUtils = performAdminCheck(request); + user = ResourceUtility.getUser(request); + adminUtils = performAdminCheck(request, user); } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to get all users who have access to insight " + insightId + " in app " + appId + " when not an admin")); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 401); @@ -130,19 +144,23 @@ public Response getInsightUsers(@Context HttpServletRequest request, @QueryParam @Path("addInsightUserPermission") public Response addInsightUserPermission(@Context HttpServletRequest request, MultivaluedMap form) { SecurityAdminUtils adminUtils = null; + User user = null; + + String newUserId = form.getFirst("id"); + String appId = form.getFirst("appId"); + String insightId = form.getFirst("insightId"); + String permission = form.getFirst("permission"); + try { - adminUtils = performAdminCheck(request); + user = ResourceUtility.getUser(request); + adminUtils = performAdminCheck(request, user); } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to add user " + newUserId + " to insight " + insightId + " in app " + appId + " when not an admin")); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 401); } - String newUserId = form.getFirst("id"); - String appId = form.getFirst("appId"); - String insightId = form.getFirst("insightId"); - String permission = form.getFirst("permission"); - try { adminUtils.addInsightUser(newUserId, appId, insightId, permission); } catch (Exception e) { @@ -151,6 +169,9 @@ public Response addInsightUserPermission(@Context HttpServletRequest request, Mu return WebUtility.getResponse(errorMap, 400); } + // log the operation + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has added user " + newUserId + " to insight " + insightId + " in app " + appId + " with permission " + permission)); + Map ret = new HashMap(); ret.put("success", true); return WebUtility.getResponse(ret, 200); @@ -167,19 +188,23 @@ public Response addInsightUserPermission(@Context HttpServletRequest request, Mu @Path("editInsightUserPermission") public Response editInsightUserPermission(@Context HttpServletRequest request, MultivaluedMap form) { SecurityAdminUtils adminUtils = null; + User user = null; + + String existingUserId = form.getFirst("id"); + String appId = form.getFirst("appId"); + String insightId = form.getFirst("insightId"); + String newPermission = form.getFirst("permission"); + try { - adminUtils = performAdminCheck(request); + user = ResourceUtility.getUser(request); + adminUtils = performAdminCheck(request, user); } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to edit user " + existingUserId + " permissions for insight " + insightId + " in app " + appId + " when not an admin")); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 401); } - String existingUserId = form.getFirst("id"); - String appId = form.getFirst("appId"); - String insightId = form.getFirst("insightId"); - String newPermission = form.getFirst("permission"); - try { adminUtils.editInsightUserPermission(existingUserId, appId, insightId, newPermission); } catch (Exception e) { @@ -188,6 +213,9 @@ public Response editInsightUserPermission(@Context HttpServletRequest request, M return WebUtility.getResponse(errorMap, 400); } + // log the operation + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has edited user " + existingUserId + " permission to insight " + insightId + " in app " + appId + " with level " + newPermission)); + Map ret = new HashMap(); ret.put("success", true); return WebUtility.getResponse(ret, 200); @@ -204,18 +232,22 @@ public Response editInsightUserPermission(@Context HttpServletRequest request, M @Path("removeInsightUserPermission") public Response removeInsightUserPermission(@Context HttpServletRequest request, MultivaluedMap form) { SecurityAdminUtils adminUtils = null; + User user = null; + + String existingUserId = form.getFirst("id"); + String appId = form.getFirst("appId"); + String insightId = form.getFirst("insightId"); + try { - adminUtils = performAdminCheck(request); + user = ResourceUtility.getUser(request); + adminUtils = performAdminCheck(request, user); } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to remove user " + existingUserId + " from having access to insight " + insightId + " in app " + appId + " when not an admin")); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 401); } - String existingUserId = form.getFirst("id"); - String appId = form.getFirst("appId"); - String insightId = form.getFirst("insightId"); - try { adminUtils.removeInsightUser(existingUserId, appId, insightId); } catch (Exception e) { @@ -224,6 +256,9 @@ public Response removeInsightUserPermission(@Context HttpServletRequest request, return WebUtility.getResponse(errorMap, 400); } + // log the operation + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has removed user " + existingUserId + " from having access to insight " + insightId + " in app " + appId)); + Map ret = new HashMap(); ret.put("success", true); return WebUtility.getResponse(ret, 200); @@ -240,18 +275,23 @@ public Response removeInsightUserPermission(@Context HttpServletRequest request, @Path("setInsightGlobal") public Response setInsightGlobal(@Context HttpServletRequest request, MultivaluedMap form) { SecurityAdminUtils adminUtils = null; + User user = null; + + String appId = form.getFirst("appId"); + String insightId = form.getFirst("insightId"); + boolean isPublic = Boolean.parseBoolean(form.getFirst("isPublic")); + String logPublic = isPublic ? " public " : " private"; + try { - adminUtils = performAdminCheck(request); + user = ResourceUtility.getUser(request); + adminUtils = performAdminCheck(request, user); } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to set the insight " + insightId + " in app " + appId + logPublic + " when not an admin")); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 401); } - String appId = form.getFirst("appId"); - String insightId = form.getFirst("insightId"); - boolean isPublic = Boolean.parseBoolean(form.getFirst("isPublic")); - try { adminUtils.setInsightGlobalWithinApp(appId, insightId, isPublic); } catch (Exception e) { @@ -260,6 +300,9 @@ public Response setInsightGlobal(@Context HttpServletRequest request, Multivalue return WebUtility.getResponse(errorMap, 400); } + // log the operation + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has set the insight " + insightId + " in app " + appId + logPublic)); + Map ret = new HashMap(); ret.put("success", true); return WebUtility.getResponse(ret, 200); @@ -276,8 +319,10 @@ public Response setInsightGlobal(@Context HttpServletRequest request, Multivalue @Path("setUserPublisher") public Response setUserPublisher(@Context HttpServletRequest request, MultivaluedMap form) { SecurityAdminUtils adminUtils = null; + User user = null; try { - adminUtils = performAdminCheck(request); + user = ResourceUtility.getUser(request); + adminUtils = performAdminCheck(request, user); } catch (IllegalAccessException e) { Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); From b2597a63bed0a656f99883085f3ecfe179aaa9a8 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 2 Jun 2020 23:48:28 +0000 Subject: [PATCH 0605/1906] UPDATE ::: Throwing additional exceptions and logging user permissions in log file git-svn-id: svn://107.170.10.188:8080/Monolith/dev@38976 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: e007d216df33a3b5a6da39ed89386c95a84b3fe1 --- .../web/services/local/ResourceUtility.java | 3 ++ .../local/auth/AppAuthorizationResource.java | 47 ++++++++++++++++--- 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/src/prerna/semoss/web/services/local/ResourceUtility.java b/src/prerna/semoss/web/services/local/ResourceUtility.java index 390d398bd..51f9a06cb 100644 --- a/src/prerna/semoss/web/services/local/ResourceUtility.java +++ b/src/prerna/semoss/web/services/local/ResourceUtility.java @@ -54,6 +54,9 @@ public static String getClientIp(@Context HttpServletRequest request) { * @return */ public static String getLogMessage(HttpServletRequest request, HttpSession session, String userId, String message) { + if(userId.isEmpty()) { + return "IP = " + ResourceUtility.getClientIp(request) + " : Session = " + session.getId() + " : ID = INVALID " + message; + } return "IP = " + ResourceUtility.getClientIp(request) + " : Session = " + session.getId() + " : ID = " + userId + " " + message; } diff --git a/src/prerna/semoss/web/services/local/auth/AppAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/AppAuthorizationResource.java index 565fb9505..bc77c781f 100644 --- a/src/prerna/semoss/web/services/local/auth/AppAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/AppAuthorizationResource.java @@ -47,6 +47,7 @@ public Response getUserApps(@Context HttpServletRequest request) { try { user = ResourceUtility.getUser(request); } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "invalid user session trying to access authorization resources")); Map errorMap = new HashMap(); errorMap.put("error", "User session is invalid"); return WebUtility.getResponse(errorMap, 401); @@ -76,6 +77,7 @@ public Response getUserAppPermission(@Context HttpServletRequest request, @Query String permission = SecurityAppUtils.getActualUserAppPermission(user, appId); if(permission == null) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to pull permission details for app " + appId + " without having access")); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, "User does not have access to this app"); return WebUtility.getResponse(errorMap, 401); @@ -109,6 +111,7 @@ public Response getAppUsers(@Context HttpServletRequest request, @QueryParam("ap try { ret = SecurityAppUtils.getAppUsers(user, appId); } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to pull users for app " + appId + " without having access")); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 401); @@ -143,11 +146,15 @@ public Response addAppUserPermission(@Context HttpServletRequest request, Multiv try { SecurityAppUtils.addAppUser(user, newUserId, appId, permission); } catch (Exception e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to pull users for app " + appId + " without having access")); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 400); } + // log the operation + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has added user " + newUserId + " to app " + appId + " with permission " + permission)); + Map ret = new HashMap(); ret.put("success", true); return WebUtility.getResponse(ret, 200); @@ -178,12 +185,20 @@ public Response editAppUserPermission(@Context HttpServletRequest request, Multi try { SecurityAppUtils.editAppUserPermission(user, existingUserId, appId, newPermission); + } catch(IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to edit user " + existingUserId + " permissions for app " + appId + " without having proper access")); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 400); } catch (Exception e) { Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 400); } + // log the operation + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has edited user " + existingUserId + " permission to app " + appId + " with level " + newPermission)); + Map ret = new HashMap(); ret.put("success", true); return WebUtility.getResponse(ret, 200); @@ -213,12 +228,20 @@ public Response removeAppUserPermission(@Context HttpServletRequest request, Mul try { SecurityAppUtils.removeAppUser(user, existingUserId, appId); + } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to remove user " + existingUserId + " from having access to app " + appId + " without having proper access")); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 400); } catch (Exception e) { Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 400); } + // log the operation + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has removed user " + existingUserId + " from having access to app " + appId)); + Map ret = new HashMap(); ret.put("success", true); return WebUtility.getResponse(ret, 200); @@ -250,11 +273,14 @@ public Response setAppGlobal(@Context HttpServletRequest request, MultivaluedMap return WebUtility.getResponse(errorMap, 401); } - String engineId = form.getFirst("appId"); + String appId = form.getFirst("appId"); boolean isPublic = Boolean.parseBoolean(form.getFirst("public")); + String logPublic = isPublic ? " public " : " private"; + try { - SecurityAppUtils.setAppGlobal(user, engineId, isPublic); - } catch(IllegalArgumentException e) { + SecurityAppUtils.setAppGlobal(user, appId, isPublic); + } catch(IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to set the app " + appId + logPublic + " without having proper access")); logger.error(STACKTRACE, e); Map errorRet = new HashMap(); errorRet.put("error", e.getMessage()); @@ -266,6 +292,9 @@ public Response setAppGlobal(@Context HttpServletRequest request, MultivaluedMap return WebUtility.getResponse(errorRet, 500); } + // log the operation + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has set the app " + appId + logPublic)); + Map ret = new HashMap(); ret.put("success", true); return WebUtility.getResponse(ret, 200); @@ -291,10 +320,13 @@ public Response setAppVisibility(@Context HttpServletRequest request, Multivalue } String appId = form.getFirst("appId"); - boolean isPublic = Boolean.parseBoolean(form.getFirst("visibility")); + boolean visible = Boolean.parseBoolean(form.getFirst("visibility")); + String logVisible = visible ? " visible " : " not visible"; + try { - SecurityUpdateUtils.setDbVisibility(user, appId, isPublic); - } catch(IllegalArgumentException e) { + SecurityUpdateUtils.setDbVisibility(user, appId, visible); + } catch(IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to set the app " + appId + logVisible + " without having proper access")); logger.error(STACKTRACE, e); Map errorRet = new HashMap(); errorRet.put("error", e.getMessage()); @@ -306,6 +338,9 @@ public Response setAppVisibility(@Context HttpServletRequest request, Multivalue return WebUtility.getResponse(errorRet, 500); } + // log the operation + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has set the app " + appId + logVisible)); + return WebUtility.getResponse(true, 200); } } From f73bb044e73473226335fa3084c864511d97c757 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 3 Jun 2020 00:01:12 +0000 Subject: [PATCH 0606/1906] UPDATE ::: Throwing additional exceptions and logging user permissions in log file git-svn-id: svn://107.170.10.188:8080/Monolith/dev@38977 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 754e56bed948b497ec086f0002e50431bc615e5a --- .../local/auth/AppAuthorizationResource.java | 13 +++-- .../auth/InsightAuthorizationResource.java | 47 ++++++++++++++++++- 2 files changed, 56 insertions(+), 4 deletions(-) diff --git a/src/prerna/semoss/web/services/local/auth/AppAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/AppAuthorizationResource.java index bc77c781f..588865754 100644 --- a/src/prerna/semoss/web/services/local/auth/AppAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/AppAuthorizationResource.java @@ -70,6 +70,7 @@ public Response getUserAppPermission(@Context HttpServletRequest request, @Query try { user = ResourceUtility.getUser(request); } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "invalid user session trying to access authorization resources")); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, "User session is invalid"); return WebUtility.getResponse(errorMap, 401); @@ -77,7 +78,7 @@ public Response getUserAppPermission(@Context HttpServletRequest request, @Query String permission = SecurityAppUtils.getActualUserAppPermission(user, appId); if(permission == null) { - logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to pull permission details for app " + appId + " without having access")); + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to pull permission details for app " + appId + " without having proper access")); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, "User does not have access to this app"); return WebUtility.getResponse(errorMap, 401); @@ -102,6 +103,7 @@ public Response getAppUsers(@Context HttpServletRequest request, @QueryParam("ap try { user = ResourceUtility.getUser(request); } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "invalid user session trying to access authorization resources")); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, "User session is invalid"); return WebUtility.getResponse(errorMap, 401); @@ -111,7 +113,7 @@ public Response getAppUsers(@Context HttpServletRequest request, @QueryParam("ap try { ret = SecurityAppUtils.getAppUsers(user, appId); } catch (IllegalAccessException e) { - logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to pull users for app " + appId + " without having access")); + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to pull users for app " + appId + " without having proper access")); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 401); @@ -134,6 +136,7 @@ public Response addAppUserPermission(@Context HttpServletRequest request, Multiv try { user = ResourceUtility.getUser(request); } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "invalid user session trying to access authorization resources")); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, "User session is invalid"); return WebUtility.getResponse(errorMap, 401); @@ -146,7 +149,7 @@ public Response addAppUserPermission(@Context HttpServletRequest request, Multiv try { SecurityAppUtils.addAppUser(user, newUserId, appId, permission); } catch (Exception e) { - logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to pull users for app " + appId + " without having access")); + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to pull users for app " + appId + " without having proper access")); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 400); @@ -174,6 +177,7 @@ public Response editAppUserPermission(@Context HttpServletRequest request, Multi try { user = ResourceUtility.getUser(request); } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "invalid user session trying to access authorization resources")); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, "User session is invalid"); return WebUtility.getResponse(errorMap, 401); @@ -218,6 +222,7 @@ public Response removeAppUserPermission(@Context HttpServletRequest request, Mul try { user = ResourceUtility.getUser(request); } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "invalid user session trying to access authorization resources")); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, "User session is invalid"); return WebUtility.getResponse(errorMap, 401); @@ -268,6 +273,7 @@ public Response setAppGlobal(@Context HttpServletRequest request, MultivaluedMap try { user = ResourceUtility.getUser(request); } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "invalid user session trying to access authorization resources")); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, "User session is invalid"); return WebUtility.getResponse(errorMap, 401); @@ -314,6 +320,7 @@ public Response setAppVisibility(@Context HttpServletRequest request, Multivalue try { user = ResourceUtility.getUser(request); } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "invalid user session trying to access authorization resources")); Map errorMap = new HashMap(); errorMap.put("error", "User session is invalid"); return WebUtility.getResponse(errorMap, 401); diff --git a/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java index 2c9b14f84..06f8e0904 100644 --- a/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java @@ -14,6 +14,8 @@ import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; +import org.apache.log4j.Logger; + import prerna.auth.AccessPermission; import prerna.auth.User; import prerna.auth.utils.SecurityAppUtils; @@ -24,6 +26,8 @@ @Path("/auth/insight") public class InsightAuthorizationResource { + private static final Logger logger = Logger.getLogger(InsightAuthorizationResource.class); + /** * Get the user insight permissions for a given insight * @param request @@ -38,6 +42,7 @@ public Response getUserInsightPermission(@Context HttpServletRequest request, @Q try { user = ResourceUtility.getUser(request); } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "invalid user session trying to access authorization resources")); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, "User session is invalid"); return WebUtility.getResponse(errorMap, 401); @@ -45,6 +50,7 @@ public Response getUserInsightPermission(@Context HttpServletRequest request, @Q String permission = SecurityInsightUtils.getActualUserInsightPermission(user, appId, insightId); if(permission == null) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to pull permission details for insight " + insightId + " in app " + appId + " without having proper access")); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, "User does not have access to this insight"); return WebUtility.getResponse(errorMap, 401); @@ -70,6 +76,7 @@ public Response getInsightUsers(@Context HttpServletRequest request, @QueryParam try { user = ResourceUtility.getUser(request); } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "invalid user session trying to access authorization resources")); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, "User session is invalid"); return WebUtility.getResponse(errorMap, 401); @@ -79,6 +86,7 @@ public Response getInsightUsers(@Context HttpServletRequest request, @QueryParam try { ret = SecurityInsightUtils.getInsightUsers(user, appId, insightId); } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to pull permission details for insight " + insightId + " in app " + appId + " without having proper access")); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 401); @@ -102,6 +110,7 @@ public Response addInsightUserPermission(@Context HttpServletRequest request, Mu try { user = ResourceUtility.getUser(request); } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "invalid user session trying to access authorization resources")); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, "User session is invalid"); return WebUtility.getResponse(errorMap, 401); @@ -116,6 +125,11 @@ public Response addInsightUserPermission(@Context HttpServletRequest request, Mu if(SecurityAppUtils.getUserAppPermission(newUserId, appId) == null) { try { SecurityAppUtils.addAppUser(user, newUserId, appId, AccessPermission.READ_ONLY.getPermission()); + } catch(IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to add user " + newUserId + " to insight " + insightId + " in app " + appId + " without having proper access")); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 400); } catch(Exception e) { Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); @@ -131,6 +145,9 @@ public Response addInsightUserPermission(@Context HttpServletRequest request, Mu return WebUtility.getResponse(errorMap, 400); } + // log the operation + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has added user " + newUserId + " to insight " + insightId + " in app " + appId + " with permission " + permission)); + Map ret = new HashMap(); ret.put("success", true); return WebUtility.getResponse(ret, 200); @@ -150,6 +167,7 @@ public Response editInsightUserPermission(@Context HttpServletRequest request, M try { user = ResourceUtility.getUser(request); } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "invalid user session trying to access authorization resources")); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, "User session is invalid"); return WebUtility.getResponse(errorMap, 401); @@ -162,12 +180,20 @@ public Response editInsightUserPermission(@Context HttpServletRequest request, M try { SecurityInsightUtils.editInsightUserPermission(user, existingUserId, appId, insightId, newPermission); + } catch(IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to edit user " + existingUserId + " permissions for insight " + insightId + " in app " + appId + " without having proper access")); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 400); } catch (Exception e) { Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 400); } + // log the operation + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has edited user " + existingUserId + " permission to insight " + insightId + " in app " + appId + " with level " + newPermission)); + Map ret = new HashMap(); ret.put("success", true); return WebUtility.getResponse(ret, 200); @@ -187,6 +213,7 @@ public Response removeInsightUserPermission(@Context HttpServletRequest request, try { user = ResourceUtility.getUser(request); } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "invalid user session trying to access authorization resources")); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, "User session is invalid"); return WebUtility.getResponse(errorMap, 401); @@ -198,12 +225,20 @@ public Response removeInsightUserPermission(@Context HttpServletRequest request, try { SecurityInsightUtils.removeInsightUser(user, existingUserId, appId, insightId); + } catch(IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to remove user " + existingUserId + " from having access to insight " + insightId + " in app " + appId + " without having proper access")); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 400); } catch (Exception e) { Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 400); } + // log the operation + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has removed user " + existingUserId + " from having access to insight " + insightId + " in app " + appId)); + Map ret = new HashMap(); ret.put("success", true); return WebUtility.getResponse(ret, 200); @@ -223,6 +258,7 @@ public Response setInsightGlobal(@Context HttpServletRequest request, Multivalue try { user = ResourceUtility.getUser(request); } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "invalid user session trying to access authorization resources")); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, "User session is invalid"); return WebUtility.getResponse(errorMap, 401); @@ -231,15 +267,24 @@ public Response setInsightGlobal(@Context HttpServletRequest request, Multivalue String appId = form.getFirst("appId"); String insightId = form.getFirst("insightId"); boolean isPublic = Boolean.parseBoolean(form.getFirst("isPublic")); - + String logPublic = isPublic ? " public " : " private"; + try { SecurityInsightUtils.setInsightGlobalWithinApp(user, appId, insightId, isPublic); + } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to set the insight " + insightId + " in app " + appId + logPublic + " without having proper access")); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 401); } catch (Exception e) { Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 400); } + // log the operation + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has set the insight " + insightId + " in app " + appId + logPublic)); + Map ret = new HashMap(); ret.put("success", true); return WebUtility.getResponse(ret, 200); From 6f44e7ecd7de419859f96030f38f237742b1faed Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 3 Jun 2020 00:25:22 +0000 Subject: [PATCH 0607/1906] UPDATE ::: Additional log cleanup for fortify / consistency git-svn-id: svn://107.170.10.188:8080/Monolith/dev@38978 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: a71926348fb3f3bcb8e0f527aab37b7faefdc16f --- .../semoss/web/services/local/NameServer.java | 34 +++++++++---------- .../auth/AdminAppAuthorizationResource.java | 11 ++++++ .../AdminInsightAuthorizationResource.java | 16 +++++++++ .../local/auth/AppAuthorizationResource.java | 13 +++++++ .../auth/InsightAuthorizationResource.java | 16 +++++++++ 5 files changed, 72 insertions(+), 18 deletions(-) diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index 5d9a2b327..ac4147422 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -121,10 +121,8 @@ public class NameServer { private static final Logger logger = LogManager.getLogger(NameServer.class); - private static final String ERROR_MESSAGE = "errorMessage"; private static final String ERROR_TYPE = "errorType"; private static final String INSIGHT_NOT_FOUND = "INSIGHT_NOT_FOUND"; - private static final String STACKTRACE = "StackTrace: "; // get the directory separator protected static final String DIR_SEPARATOR = java.nio.file.FileSystems.getDefault().getSeparator(); @@ -202,7 +200,7 @@ public Object getInsightDataFrame(@PathParam("insightID") String insightID, existingInsight = InsightStore.getInstance().get(insightID); if (existingInsight == null) { Map errorHash = new HashMap<>(); - errorHash.put(ERROR_MESSAGE, "Existing insight based on passed insightID is not found"); + errorHash.put(Constants.ERROR_MESSAGE, "Existing insight based on passed insightID is not found"); // return Response.status(400).entity(WebUtility.getSO(errorHash)).build(); return WebUtility.getResponse(errorHash, 400); } @@ -288,7 +286,7 @@ public Response downloadFile(@QueryParam("insightId") String insightId, @QueryPa Insight insight = InsightStore.getInstance().get(insightId); if (insight == null) { Map errorMap = new HashMap<>(); - errorMap.put(ERROR_MESSAGE, "Could not find the insight id"); + errorMap.put(Constants.ERROR_MESSAGE, "Could not find the insight id"); return WebUtility.getResponse(errorMap, 400); } @@ -296,7 +294,7 @@ public Response downloadFile(@QueryParam("insightId") String insightId, @QueryPa File exportFile = new File(filePath); if (!exportFile.exists()) { Map errorMap = new HashMap<>(); - errorMap.put(ERROR_MESSAGE, "Could not find the file for given file id"); + errorMap.put(Constants.ERROR_MESSAGE, "Could not find the file for given file id"); return WebUtility.getResponse(errorMap, 400); } @@ -406,7 +404,7 @@ public Response runPixelSync(@Context HttpServletRequest request) { insight = InsightStore.getInstance().get(insightId); if (insight == null) { Map errorMap = new HashMap<>(); - errorMap.put(ERROR_MESSAGE, "Could not find the insight id"); + errorMap.put(Constants.ERROR_MESSAGE, "Could not find the insight id"); errorMap.put(ERROR_TYPE, INSIGHT_NOT_FOUND); return WebUtility.getResponse(errorMap, 400); } @@ -453,7 +451,7 @@ public Response getPixelPipelinePlan(@Context HttpServletRequest request) { Insight insight = InsightStore.getInstance().get(insightId); if (insight == null) { Map errorMap = new HashMap<>(); - errorMap.put(ERROR_MESSAGE, "Could not find the insight id"); + errorMap.put(Constants.ERROR_MESSAGE, "Could not find the insight id"); errorMap.put(ERROR_TYPE, INSIGHT_NOT_FOUND); return WebUtility.getResponse(errorMap, 400); } @@ -569,9 +567,9 @@ private Response getInsightPipeline(Insight insight, String expression) { .entity(GsonUtility.getDefaultGson().toJson(PixelUtility.generatePipeline(insight, expression))) .build(); } catch (Exception e) { - logger.error(STACKTRACE, e); + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap<>(); - errorMap.put(ERROR_MESSAGE, e.getMessage()); + errorMap.put(Constants.ERROR_MESSAGE, e.getMessage()); return WebUtility.getResponse(errorMap, 400); } } @@ -614,7 +612,7 @@ public Response runPixelAsync(@Context HttpServletRequest request) { insight = InsightStore.getInstance().get(insightId); if (insight == null) { Map errorMap = new HashMap<>(); - errorMap.put(ERROR_MESSAGE, "Could not find the insight id"); + errorMap.put(Constants.ERROR_MESSAGE, "Could not find the insight id"); errorMap.put(ERROR_TYPE, INSIGHT_NOT_FOUND); return WebUtility.getResponse(errorMap, 400); } @@ -849,7 +847,7 @@ public StreamingOutput getMediaWikiTagsForSearchTerm(@QueryParam("searchTerm") S } } } catch (ClientProtocolException e) { - logger.error(STACKTRACE, e); + logger.error(Constants.STACKTRACE, e); } finally { if (httpClient != null) { httpClient.close(); @@ -859,7 +857,7 @@ public StreamingOutput getMediaWikiTagsForSearchTerm(@QueryParam("searchTerm") S } } } catch (IOException e) { - logger.error(STACKTRACE, e); + logger.error(Constants.STACKTRACE, e); } } @@ -883,7 +881,7 @@ public Object getLocalDatabase(@Context HttpServletRequest request, @PathParam(" engineId = SecurityQueryUtils.testUserEngineIdForAlias(user, engineId); if (!SecurityAppUtils.userCanViewEngine(user, engineId)) { Map errorMap = new HashMap<>(); - errorMap.put(ERROR_MESSAGE, + errorMap.put(Constants.ERROR_MESSAGE, "Database " + engineId + " does not exist or user does not have access to database"); return WebUtility.getResponse(errorMap, 400); } @@ -891,7 +889,7 @@ public Object getLocalDatabase(@Context HttpServletRequest request, @PathParam(" engineId = MasterDatabaseUtility.testEngineIdIfAlias(engineId); if (!MasterDatabaseUtility.getAllEngineIds().contains(engineId)) { Map errorMap = new HashMap<>(); - errorMap.put(ERROR_MESSAGE, "Database " + engineId + " does not exist"); + errorMap.put(Constants.ERROR_MESSAGE, "Database " + engineId + " does not exist"); return WebUtility.getResponse(errorMap, 400); } } @@ -1060,7 +1058,7 @@ public void write(OutputStream outputStream) throws IOException, WebApplicationE out.println(""); out.println(""); } catch (Exception e) { - logger.error(STACKTRACE, e); + logger.error(Constants.STACKTRACE, e); } } }; @@ -1160,9 +1158,9 @@ public StreamingOutput getSearchInsightsResults(MultivaluedMap f appIds = filterMap.get("app_id"); tags = filterMap.get("tags"); } catch (Exception e) { - logger.error(STACKTRACE, e); + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap<>(); - errorMap.put(ERROR_MESSAGE, "Invalid filter map"); + errorMap.put(Constants.ERROR_MESSAGE, "Invalid filter map"); return WebUtility.getSO(errorMap); } } @@ -1201,7 +1199,7 @@ private String createInsightTupleSpace(String baseFolder, String insightId) { try { FileUtils.writeStringToFile(cmdFile, command); } catch (IOException ioe) { - logger.error(STACKTRACE, ioe); + logger.error(Constants.STACKTRACE, ioe); } } return normalizedInsightSpecificFolder; diff --git a/src/prerna/semoss/web/services/local/auth/AdminAppAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/AdminAppAuthorizationResource.java index 8487d7d97..43d849064 100644 --- a/src/prerna/semoss/web/services/local/auth/AdminAppAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/AdminAppAuthorizationResource.java @@ -19,6 +19,7 @@ import prerna.auth.User; import prerna.auth.utils.SecurityAdminUtils; import prerna.semoss.web.services.local.ResourceUtility; +import prerna.util.Constants; import prerna.web.services.util.WebUtility; @Path("/auth/admin/app") @@ -45,6 +46,7 @@ public Response getUserApps(@Context HttpServletRequest request) { adminUtils = performAdminCheck(request, user); } catch (IllegalAccessException e) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to get all apps when not an admin")); + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 401); @@ -65,6 +67,7 @@ public Response getAllUserDbs(@Context HttpServletRequest request, MultivaluedMa adminUtils = performAdminCheck(request, user); } catch (IllegalAccessException e) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to pull the apps that user " + userId + " has access to when not an admin")); + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 401); @@ -90,6 +93,7 @@ public Response getAppUsers(@Context HttpServletRequest request, @QueryParam("ap adminUtils = performAdminCheck(request, user); } catch (IllegalAccessException e) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to pull all the users who use app " + appId + " when not an admin")); + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 401); @@ -120,6 +124,7 @@ public Response addAppUserPermission(@Context HttpServletRequest request, Multiv adminUtils = performAdminCheck(request, user); } catch (IllegalAccessException e) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to add user " + newUserId + " to app " + appId + " when not an admin")); + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 401); @@ -128,6 +133,7 @@ public Response addAppUserPermission(@Context HttpServletRequest request, Multiv try { adminUtils.addAppUser(newUserId, appId, permission); } catch (Exception e) { + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 400); @@ -162,6 +168,7 @@ public Response editAppUserPermission(@Context HttpServletRequest request, Multi user = ResourceUtility.getUser(request); adminUtils = performAdminCheck(request, user); } catch (IllegalAccessException e) { + logger.error(Constants.STACKTRACE, e); logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to edit user " + existingUserId + " permissions for app " + appId + " when not an admin")); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); @@ -171,6 +178,7 @@ public Response editAppUserPermission(@Context HttpServletRequest request, Multi try { adminUtils.editAppUserPermission(existingUserId, appId, newPermission); } catch (Exception e) { + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 400); @@ -205,6 +213,7 @@ public Response removeAppUserPermission(@Context HttpServletRequest request, Mul adminUtils = performAdminCheck(request, user); } catch (IllegalAccessException e) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to remove user " + existingUserId + " from having access to app " + appId + " when not an admin")); + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 401); @@ -213,6 +222,7 @@ public Response removeAppUserPermission(@Context HttpServletRequest request, Mul try { adminUtils.removeAppUser(existingUserId, appId); } catch (Exception e) { + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 400); @@ -242,6 +252,7 @@ public Response setAppGlobal(@Context HttpServletRequest request, MultivaluedMap adminUtils = performAdminCheck(request, user); } catch (IllegalAccessException e) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to set the app " + appId + logPublic + " when not an admin")); + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 401); diff --git a/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java index f0bbe56da..4ec760894 100644 --- a/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java @@ -22,6 +22,7 @@ import prerna.auth.utils.SecurityAdminUtils; import prerna.cluster.util.ClusterUtil; import prerna.semoss.web.services.local.ResourceUtility; +import prerna.util.Constants; import prerna.web.services.util.WebUtility; @Path("/auth/admin/insight") @@ -46,6 +47,7 @@ public Response getAppInsights(@Context HttpServletRequest request, @QueryParam( adminUtils = performAdminCheck(request, user); } catch (IllegalAccessException e) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to see all the insight for app " + appId + " when not an admin")); + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 401); @@ -77,6 +79,7 @@ public Response deleteAppInsights(@Context HttpServletRequest request, Multivalu adminUtils = performAdminCheck(request, user); } catch (IllegalAccessException e) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to delete insight from app " + appId + " when not an admin")); + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 401); @@ -88,6 +91,7 @@ public Response deleteAppInsights(@Context HttpServletRequest request, Multivalu // need to push to cloud storage ClusterUtil.reactorPushApp(appId); } catch (Exception e) { + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 401); @@ -115,6 +119,7 @@ public Response getInsightUsers(@Context HttpServletRequest request, @QueryParam adminUtils = performAdminCheck(request, user); } catch (IllegalAccessException e) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to get all users who have access to insight " + insightId + " in app " + appId + " when not an admin")); + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 401); @@ -124,6 +129,7 @@ public Response getInsightUsers(@Context HttpServletRequest request, @QueryParam try { ret = adminUtils.getInsightUsers(appId, insightId); } catch (IllegalAccessException e) { + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 401); @@ -156,6 +162,7 @@ public Response addInsightUserPermission(@Context HttpServletRequest request, Mu adminUtils = performAdminCheck(request, user); } catch (IllegalAccessException e) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to add user " + newUserId + " to insight " + insightId + " in app " + appId + " when not an admin")); + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 401); @@ -164,6 +171,7 @@ public Response addInsightUserPermission(@Context HttpServletRequest request, Mu try { adminUtils.addInsightUser(newUserId, appId, insightId, permission); } catch (Exception e) { + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 400); @@ -200,6 +208,7 @@ public Response editInsightUserPermission(@Context HttpServletRequest request, M adminUtils = performAdminCheck(request, user); } catch (IllegalAccessException e) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to edit user " + existingUserId + " permissions for insight " + insightId + " in app " + appId + " when not an admin")); + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 401); @@ -208,6 +217,7 @@ public Response editInsightUserPermission(@Context HttpServletRequest request, M try { adminUtils.editInsightUserPermission(existingUserId, appId, insightId, newPermission); } catch (Exception e) { + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 400); @@ -243,6 +253,7 @@ public Response removeInsightUserPermission(@Context HttpServletRequest request, adminUtils = performAdminCheck(request, user); } catch (IllegalAccessException e) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to remove user " + existingUserId + " from having access to insight " + insightId + " in app " + appId + " when not an admin")); + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 401); @@ -251,6 +262,7 @@ public Response removeInsightUserPermission(@Context HttpServletRequest request, try { adminUtils.removeInsightUser(existingUserId, appId, insightId); } catch (Exception e) { + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 400); @@ -287,6 +299,7 @@ public Response setInsightGlobal(@Context HttpServletRequest request, Multivalue adminUtils = performAdminCheck(request, user); } catch (IllegalAccessException e) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to set the insight " + insightId + " in app " + appId + logPublic + " when not an admin")); + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 401); @@ -295,6 +308,7 @@ public Response setInsightGlobal(@Context HttpServletRequest request, Multivalue try { adminUtils.setInsightGlobalWithinApp(appId, insightId, isPublic); } catch (Exception e) { + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 400); @@ -324,6 +338,7 @@ public Response setUserPublisher(@Context HttpServletRequest request, Multivalue user = ResourceUtility.getUser(request); adminUtils = performAdminCheck(request, user); } catch (IllegalAccessException e) { + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 401); @@ -335,6 +350,7 @@ public Response setUserPublisher(@Context HttpServletRequest request, Multivalue try { adminUtils.setUserPublisher(userId, isPublisher); } catch (Exception e) { + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 400); diff --git a/src/prerna/semoss/web/services/local/auth/AppAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/AppAuthorizationResource.java index 588865754..2607329c1 100644 --- a/src/prerna/semoss/web/services/local/auth/AppAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/AppAuthorizationResource.java @@ -48,6 +48,7 @@ public Response getUserApps(@Context HttpServletRequest request) { user = ResourceUtility.getUser(request); } catch (IllegalAccessException e) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "invalid user session trying to access authorization resources")); + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put("error", "User session is invalid"); return WebUtility.getResponse(errorMap, 401); @@ -71,6 +72,7 @@ public Response getUserAppPermission(@Context HttpServletRequest request, @Query user = ResourceUtility.getUser(request); } catch (IllegalAccessException e) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "invalid user session trying to access authorization resources")); + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, "User session is invalid"); return WebUtility.getResponse(errorMap, 401); @@ -104,6 +106,7 @@ public Response getAppUsers(@Context HttpServletRequest request, @QueryParam("ap user = ResourceUtility.getUser(request); } catch (IllegalAccessException e) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "invalid user session trying to access authorization resources")); + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, "User session is invalid"); return WebUtility.getResponse(errorMap, 401); @@ -114,6 +117,7 @@ public Response getAppUsers(@Context HttpServletRequest request, @QueryParam("ap ret = SecurityAppUtils.getAppUsers(user, appId); } catch (IllegalAccessException e) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to pull users for app " + appId + " without having proper access")); + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 401); @@ -137,6 +141,7 @@ public Response addAppUserPermission(@Context HttpServletRequest request, Multiv user = ResourceUtility.getUser(request); } catch (IllegalAccessException e) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "invalid user session trying to access authorization resources")); + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, "User session is invalid"); return WebUtility.getResponse(errorMap, 401); @@ -150,6 +155,7 @@ public Response addAppUserPermission(@Context HttpServletRequest request, Multiv SecurityAppUtils.addAppUser(user, newUserId, appId, permission); } catch (Exception e) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to pull users for app " + appId + " without having proper access")); + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 400); @@ -178,6 +184,7 @@ public Response editAppUserPermission(@Context HttpServletRequest request, Multi user = ResourceUtility.getUser(request); } catch (IllegalAccessException e) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "invalid user session trying to access authorization resources")); + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, "User session is invalid"); return WebUtility.getResponse(errorMap, 401); @@ -191,10 +198,12 @@ public Response editAppUserPermission(@Context HttpServletRequest request, Multi SecurityAppUtils.editAppUserPermission(user, existingUserId, appId, newPermission); } catch(IllegalAccessException e) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to edit user " + existingUserId + " permissions for app " + appId + " without having proper access")); + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 400); } catch (Exception e) { + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 400); @@ -235,10 +244,12 @@ public Response removeAppUserPermission(@Context HttpServletRequest request, Mul SecurityAppUtils.removeAppUser(user, existingUserId, appId); } catch (IllegalAccessException e) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to remove user " + existingUserId + " from having access to app " + appId + " without having proper access")); + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 400); } catch (Exception e) { + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 400); @@ -274,6 +285,7 @@ public Response setAppGlobal(@Context HttpServletRequest request, MultivaluedMap user = ResourceUtility.getUser(request); } catch (IllegalAccessException e) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "invalid user session trying to access authorization resources")); + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, "User session is invalid"); return WebUtility.getResponse(errorMap, 401); @@ -321,6 +333,7 @@ public Response setAppVisibility(@Context HttpServletRequest request, Multivalue user = ResourceUtility.getUser(request); } catch (IllegalAccessException e) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "invalid user session trying to access authorization resources")); + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put("error", "User session is invalid"); return WebUtility.getResponse(errorMap, 401); diff --git a/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java index 06f8e0904..20c160234 100644 --- a/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java @@ -21,6 +21,7 @@ import prerna.auth.utils.SecurityAppUtils; import prerna.auth.utils.SecurityInsightUtils; import prerna.semoss.web.services.local.ResourceUtility; +import prerna.util.Constants; import prerna.web.services.util.WebUtility; @Path("/auth/insight") @@ -43,6 +44,7 @@ public Response getUserInsightPermission(@Context HttpServletRequest request, @Q user = ResourceUtility.getUser(request); } catch (IllegalAccessException e) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "invalid user session trying to access authorization resources")); + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, "User session is invalid"); return WebUtility.getResponse(errorMap, 401); @@ -77,6 +79,7 @@ public Response getInsightUsers(@Context HttpServletRequest request, @QueryParam user = ResourceUtility.getUser(request); } catch (IllegalAccessException e) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "invalid user session trying to access authorization resources")); + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, "User session is invalid"); return WebUtility.getResponse(errorMap, 401); @@ -87,6 +90,7 @@ public Response getInsightUsers(@Context HttpServletRequest request, @QueryParam ret = SecurityInsightUtils.getInsightUsers(user, appId, insightId); } catch (IllegalAccessException e) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to pull permission details for insight " + insightId + " in app " + appId + " without having proper access")); + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 401); @@ -127,10 +131,12 @@ public Response addInsightUserPermission(@Context HttpServletRequest request, Mu SecurityAppUtils.addAppUser(user, newUserId, appId, AccessPermission.READ_ONLY.getPermission()); } catch(IllegalAccessException e) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to add user " + newUserId + " to insight " + insightId + " in app " + appId + " without having proper access")); + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 400); } catch(Exception e) { + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 400); @@ -140,6 +146,7 @@ public Response addInsightUserPermission(@Context HttpServletRequest request, Mu try { SecurityInsightUtils.addInsightUser(user, newUserId, appId, insightId, permission); } catch (Exception e) { + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 400); @@ -168,6 +175,7 @@ public Response editInsightUserPermission(@Context HttpServletRequest request, M user = ResourceUtility.getUser(request); } catch (IllegalAccessException e) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "invalid user session trying to access authorization resources")); + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, "User session is invalid"); return WebUtility.getResponse(errorMap, 401); @@ -182,10 +190,12 @@ public Response editInsightUserPermission(@Context HttpServletRequest request, M SecurityInsightUtils.editInsightUserPermission(user, existingUserId, appId, insightId, newPermission); } catch(IllegalAccessException e) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to edit user " + existingUserId + " permissions for insight " + insightId + " in app " + appId + " without having proper access")); + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 400); } catch (Exception e) { + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 400); @@ -214,6 +224,7 @@ public Response removeInsightUserPermission(@Context HttpServletRequest request, user = ResourceUtility.getUser(request); } catch (IllegalAccessException e) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "invalid user session trying to access authorization resources")); + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, "User session is invalid"); return WebUtility.getResponse(errorMap, 401); @@ -227,10 +238,12 @@ public Response removeInsightUserPermission(@Context HttpServletRequest request, SecurityInsightUtils.removeInsightUser(user, existingUserId, appId, insightId); } catch(IllegalAccessException e) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to remove user " + existingUserId + " from having access to insight " + insightId + " in app " + appId + " without having proper access")); + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 400); } catch (Exception e) { + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 400); @@ -259,6 +272,7 @@ public Response setInsightGlobal(@Context HttpServletRequest request, Multivalue user = ResourceUtility.getUser(request); } catch (IllegalAccessException e) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "invalid user session trying to access authorization resources")); + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, "User session is invalid"); return WebUtility.getResponse(errorMap, 401); @@ -273,10 +287,12 @@ public Response setInsightGlobal(@Context HttpServletRequest request, Multivalue SecurityInsightUtils.setInsightGlobalWithinApp(user, appId, insightId, isPublic); } catch (IllegalAccessException e) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to set the insight " + insightId + " in app " + appId + logPublic + " without having proper access")); + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 401); } catch (Exception e) { + logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 400); From 4d757d5a09cd90109679f5edd6c109dfb0bc189d Mon Sep 17 00:00:00 2001 From: kunalppatel9 Date: Thu, 4 Jun 2020 13:55:21 +0000 Subject: [PATCH 0608/1906] BUGFIX ::: Adding a clean log string to logging of IPs git-svn-id: svn://107.170.10.188:8080/Monolith/dev@38992 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: c491d06ff26da240f51d37fdee994eee5a458694 --- src/prerna/semoss/web/services/local/ResourceUtility.java | 5 +++-- src/prerna/web/conf/AnonymousUserFilter.java | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/prerna/semoss/web/services/local/ResourceUtility.java b/src/prerna/semoss/web/services/local/ResourceUtility.java index 51f9a06cb..2933fd8f7 100644 --- a/src/prerna/semoss/web/services/local/ResourceUtility.java +++ b/src/prerna/semoss/web/services/local/ResourceUtility.java @@ -8,6 +8,7 @@ import prerna.auth.User; import prerna.util.Constants; +import prerna.util.Utility; public class ResourceUtility { @@ -55,9 +56,9 @@ public static String getClientIp(@Context HttpServletRequest request) { */ public static String getLogMessage(HttpServletRequest request, HttpSession session, String userId, String message) { if(userId.isEmpty()) { - return "IP = " + ResourceUtility.getClientIp(request) + " : Session = " + session.getId() + " : ID = INVALID " + message; + return "IP = " + Utility.cleanLogString(ResourceUtility.getClientIp(request)) + " : Session = " + session.getId() + " : ID = INVALID " + message; } - return "IP = " + ResourceUtility.getClientIp(request) + " : Session = " + session.getId() + " : ID = " + userId + " " + message; + return "IP = " + Utility.cleanLogString(ResourceUtility.getClientIp(request)) + " : Session = " + session.getId() + " : ID = " + userId + " " + message; } } diff --git a/src/prerna/web/conf/AnonymousUserFilter.java b/src/prerna/web/conf/AnonymousUserFilter.java index 2e53b4ad2..3bcbd3275 100644 --- a/src/prerna/web/conf/AnonymousUserFilter.java +++ b/src/prerna/web/conf/AnonymousUserFilter.java @@ -22,6 +22,7 @@ import prerna.auth.utils.AbstractSecurityUtils; import prerna.semoss.web.services.local.ResourceUtility; import prerna.util.Constants; +import prerna.util.Utility; public class AnonymousUserFilter implements Filter, Serializable { @@ -70,7 +71,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 session.setAttribute(Constants.SESSION_USER, user); // log the user login - logger.info("IP " + ResourceUtility.getClientIp((HttpServletRequest)arg0) + " : Anonymous user with id " + User.getSingleLogginName(user) + " logged in from session " + session.getId()); + logger.info("IP " + Utility.cleanLogString(ResourceUtility.getClientIp((HttpServletRequest)arg0)) + " : Anonymous user with id " + User.getSingleLogginName(user) + " logged in from session " + session.getId()); } } From d419fe51bbf8c6f67fad219fd3991940e321b468 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 4 Jun 2020 16:09:04 +0000 Subject: [PATCH 0609/1906] UPDATE ::: Moving log to same utility message + determining if first time login or not git-svn-id: svn://107.170.10.188:8080/Monolith/dev@38993 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 1e26e0427b170671ce6b0061c7fe2deb2021f2de --- src/prerna/web/conf/AnonymousUserFilter.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/prerna/web/conf/AnonymousUserFilter.java b/src/prerna/web/conf/AnonymousUserFilter.java index 3bcbd3275..413bc3f51 100644 --- a/src/prerna/web/conf/AnonymousUserFilter.java +++ b/src/prerna/web/conf/AnonymousUserFilter.java @@ -22,7 +22,6 @@ import prerna.auth.utils.AbstractSecurityUtils; import prerna.semoss.web.services.local.ResourceUtility; import prerna.util.Constants; -import prerna.util.Utility; public class AnonymousUserFilter implements Filter, Serializable { @@ -54,7 +53,8 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 } } - if(user.getAnonymousId() == null) { + boolean foundPrevoiusCookie = user.getAnonymousId() != null; + if(!foundPrevoiusCookie) { // set a new id + add a cookie String uId = "UNK_" + UUID.randomUUID().toString(); user.setAnonymousId(uId); @@ -71,7 +71,11 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 session.setAttribute(Constants.SESSION_USER, user); // log the user login - logger.info("IP " + Utility.cleanLogString(ResourceUtility.getClientIp((HttpServletRequest)arg0)) + " : Anonymous user with id " + User.getSingleLogginName(user) + " logged in from session " + session.getId()); + if(foundPrevoiusCookie) { + logger.info(ResourceUtility.getLogMessage((HttpServletRequest)arg0, session, User.getSingleLogginName(user), "is logging in anonymously")); + } else { + logger.info(ResourceUtility.getLogMessage((HttpServletRequest)arg0, session, User.getSingleLogginName(user), "is logging in anonymously for first time")); + } } } From f436fb7f31c30dd0f9651e12abcffb151cadf42b Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 11 Jun 2020 19:05:27 +0000 Subject: [PATCH 0610/1906] BUGFIX ::: Allowing native user information to be null w/o preventing login git-svn-id: svn://107.170.10.188:8080/Monolith/dev@39096 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 01453a2a72d47863a88b4ca7b27ece49dd26937e --- src/prerna/semoss/web/services/local/NameServer.java | 6 ------ .../semoss/web/services/local/UserResource.java | 11 +++++++---- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index ac4147422..fa338b76d 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -135,8 +135,6 @@ public class NameServer { // uploader functionality @Path("/uploadDatabase") public Uploader uploadDatabase(@Context HttpServletRequest request) { - boolean securityEnabled = AbstractSecurityUtils.securityEnabled(); - Uploader upload = new DatabaseUploader(); String filePath = context.getInitParameter("file-upload"); upload.setFilePath(filePath); @@ -147,8 +145,6 @@ public Uploader uploadDatabase(@Context HttpServletRequest request) { @Path("/uploadFile") public Uploader uploadFile(@Context HttpServletRequest request) { - boolean securityEnabled = AbstractSecurityUtils.securityEnabled(); - Uploader upload = new FileUploader(); String tempFilePath = context.getInitParameter("temp-file-upload"); upload.setTempFilePath(tempFilePath); @@ -157,8 +153,6 @@ public Uploader uploadFile(@Context HttpServletRequest request) { @Path("/uploadImage") public Uploader uploadImage(@Context HttpServletRequest request) { - boolean securityEnabled = AbstractSecurityUtils.securityEnabled(); - Uploader upload = new ImageUploader(); String filePath = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER) + DIR_SEPARATOR + "db"; upload.setFilePath(filePath); diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index ccdd60cc6..456e88c4f 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -1428,16 +1428,19 @@ private String getTwitterRedirect(HttpServletRequest request) throws Unsupported @Produces("application/json") @Path("login") public Response loginNative(@Context HttpServletRequest request, @Context HttpServletResponse response) { - Hashtable ret = new Hashtable<>(); + Map ret = new HashMap<>(); try { String username = request.getParameter("username"); String password = request.getParameter("password"); String redirect = Utility.cleanHttpResponse(request.getParameter("redirect")); Boolean disableRedirect = Boolean.parseBoolean(request.getParameter("enableRedirect") + ""); - boolean emptyCredentials = (username == null || password == null || username.isEmpty() - || password.isEmpty()); - boolean canLogin = !emptyCredentials && NativeUserSecurityUtils.logIn(username, password); + if(username == null || password == null || username.isEmpty() || password.isEmpty()) { + ret.put("error", "The user name or password are empty"); + return WebUtility.getResponse(ret, 401); + } + + boolean canLogin = NativeUserSecurityUtils.logIn(username, password); if (canLogin) { ret.put("success", "true"); ret.put("username", username); From bf4e5e13b9dad78b71b76033d3054362ea79f6b6 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 17 Jun 2020 19:36:28 +0000 Subject: [PATCH 0611/1906] UPDATE ::: Adding scheduler as RDBMS instead of using the file watcher TODO ::: Will incorporate script to load in previous files in watcher directory to database git-svn-id: svn://107.170.10.188:8080/Monolith/dev@39167 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: e72ba0165c1571c9f154b9cd09fe354c0f12b101 --- src/prerna/web/conf/DBLoader.java | 36 ++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/src/prerna/web/conf/DBLoader.java b/src/prerna/web/conf/DBLoader.java index 497509858..d13c5380c 100644 --- a/src/prerna/web/conf/DBLoader.java +++ b/src/prerna/web/conf/DBLoader.java @@ -27,6 +27,7 @@ *******************************************************************************/ package prerna.web.conf; +import java.sql.SQLException; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -40,18 +41,19 @@ import org.apache.log4j.LogManager; import org.apache.log4j.Logger; import org.apache.log4j.PropertyConfigurator; -import org.quartz.SchedulerException; import com.ibm.icu.util.StringTokenizer; import prerna.engine.api.IEngine; import prerna.engine.impl.r.RserveUtil; +import prerna.engine.impl.rdbms.RDBMSNativeEngine; import prerna.forms.AbstractFormBuilder; import prerna.nameserver.utility.MasterDatabaseUtility; import prerna.om.Insight; import prerna.om.InsightStore; -import prerna.rpa.quartz.SchedulerUtil; import prerna.sablecc2.reactor.frame.r.util.RJavaTranslatorFactory; +import prerna.sablecc2.reactor.scheduler.SchedulerFactorySingleton; +import prerna.sablecc2.reactor.scheduler.SchedulerH2DatabaseUtility; import prerna.util.AbstractFileWatcher; import prerna.util.ChromeDriverUtility; import prerna.util.Constants; @@ -131,7 +133,7 @@ public void contextInitialized(ServletContextEvent arg0) { ChromeDriverUtility.setSessionCookie(cookieConfig.getName()); } } - + logger.info("Initializing application context..." + Utility.cleanLogString(contextPath)); // Set default file separator system variable @@ -189,11 +191,25 @@ public void contextInitialized(ServletContextEvent arg0) { { IEngine localmaster = (IEngine) DIHelper.getInstance().getLocalProp(Constants.LOCAL_MASTER_DB_NAME); IEngine security = (IEngine) DIHelper.getInstance().getLocalProp(Constants.SECURITY_DB); - if (localmaster == null || security == null || !localmaster.isConnected() || !security.isConnected()) { + // TODO: will make scheduler a requirement + IEngine scheduler = (IEngine) DIHelper.getInstance().getLocalProp(Constants.SCHEDULER_DB); +// if (localmaster == null || security == null || scheduler == null || !localmaster.isConnected() || !security.isConnected() || !scheduler.isConnected()) { + if (localmaster == null || security == null || !localmaster.isConnected() || !security.isConnected() ) { + // you have messed up!!! StartUpSuccessFilter.setStartUpSuccess(false); } } + + // Load and run triggerOnLoad jobs + RDBMSNativeEngine schedulerDb = (RDBMSNativeEngine) Utility.getEngine(Constants.SCHEDULER_DB); + if(schedulerDb != null) { + try { + SchedulerH2DatabaseUtility.executeAllTriggerOnLoads(schedulerDb.getConnection()); + } catch (SQLException e) { + logger.error(STACKTRACE, e); + } + } } public void loadEngines() { @@ -205,8 +221,7 @@ public void loadEngines() { String watcherClass = DIHelper.getInstance().getProperty(watcher); String folder = DIHelper.getInstance().getProperty(watcher + "_DIR"); String ext = DIHelper.getInstance().getProperty(watcher + "_EXT"); - AbstractFileWatcher watcherInstance = (AbstractFileWatcher) Class.forName(watcherClass) - .getConstructor(null).newInstance(null); + AbstractFileWatcher watcherInstance = (AbstractFileWatcher) Class.forName(watcherClass).getConstructor(null).newInstance(null); watcherInstance.setMonitor(monitor); watcherInstance.setFolderToWatch(folder); watcherInstance.setExtension(ext); @@ -276,13 +291,8 @@ public void contextDestroyed(ServletContextEvent arg0) { logger.info("Couldn't find database " + Constants.LOCAL_MASTER_DB_NAME); } - // close scheduler - try { - logger.info("Closing scheduler"); - SchedulerUtil.shutdownScheduler(true); - } catch (SchedulerException e) { - logger.error(STACKTRACE, e); - } + logger.info("Closing scheduler"); + SchedulerFactorySingleton.getInstance().shutdownScheduler(true); // close r try { From 05ee69b3f599fb73bda27ccd88ff3a080df59d00 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 17 Jun 2020 21:36:32 +0000 Subject: [PATCH 0612/1906] UPDATE ::: Adding logic to move legacy json files git-svn-id: svn://107.170.10.188:8080/Monolith/dev@39170 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 58177673d5e42bb34faf89eb741ded5b1f47e14c --- src/prerna/web/conf/DBLoader.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/prerna/web/conf/DBLoader.java b/src/prerna/web/conf/DBLoader.java index d13c5380c..4fab8875c 100644 --- a/src/prerna/web/conf/DBLoader.java +++ b/src/prerna/web/conf/DBLoader.java @@ -54,6 +54,7 @@ import prerna.sablecc2.reactor.frame.r.util.RJavaTranslatorFactory; import prerna.sablecc2.reactor.scheduler.SchedulerFactorySingleton; import prerna.sablecc2.reactor.scheduler.SchedulerH2DatabaseUtility; +import prerna.sablecc2.reactor.scheduler.legacy.JsonConversionToQuartzJob; import prerna.util.AbstractFileWatcher; import prerna.util.ChromeDriverUtility; import prerna.util.Constants; @@ -206,6 +207,8 @@ public void contextInitialized(ServletContextEvent arg0) { if(schedulerDb != null) { try { SchedulerH2DatabaseUtility.executeAllTriggerOnLoads(schedulerDb.getConnection()); + // also add legacy json files + JsonConversionToQuartzJob.runUpdateFromLegacyFormat(); } catch (SQLException e) { logger.error(STACKTRACE, e); } From 15751ec3b7126e321ddaf49ffe05e912f05a89dc Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 24 Jun 2020 19:12:47 +0000 Subject: [PATCH 0613/1906] UPDATE ::: Adding more for export to excel git-svn-id: svn://107.170.10.188:8080/Monolith/dev@39239 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: cc06d44a6a83e19a99d731bd75d81fc69189540f --- pom.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pom.xml b/pom.xml index 152bf8ff2..d601a80fb 100644 --- a/pom.xml +++ b/pom.xml @@ -1576,6 +1576,11 @@ + + org.apache.poi + ooxml-schemas + 1.4 + + + org.apache.poi + poi-scratchpad + 4.1.1 + - NoUserInSessionFilter @@ -256,6 +254,22 @@ --> + + + MainApplication @@ -345,15 +359,17 @@ prerna.web.conf.SessionCounter - 120 monolith + \ No newline at end of file From 3feadf1f839d4b56e4d9f7c1cc6b5cfb18b74eff Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 31 Jul 2020 14:32:32 +0000 Subject: [PATCH 0628/1906] UPDATE ::: sync between security and app insight database on which insights are public/hidden git-svn-id: svn://107.170.10.188:8080/Monolith/dev@39600 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 69b3b36939f33e2d9df458b36f9289c0cbd35a75 --- .../auth/AdminInsightAuthorizationResource.java | 12 ++++++++++++ .../local/auth/InsightAuthorizationResource.java | 13 +++++++++++++ 2 files changed, 25 insertions(+) diff --git a/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java index ff729a025..77a1acbf5 100644 --- a/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java @@ -21,8 +21,11 @@ import prerna.auth.User; import prerna.auth.utils.SecurityAdminUtils; import prerna.cluster.util.ClusterUtil; +import prerna.engine.api.IEngine; +import prerna.engine.impl.InsightAdministrator; import prerna.semoss.web.services.local.ResourceUtility; import prerna.util.Constants; +import prerna.util.Utility; import prerna.web.services.util.WebUtility; @Path("/auth/admin/insight") @@ -307,6 +310,15 @@ public Response setInsightGlobal(@Context HttpServletRequest request, Multivalue try { adminUtils.setInsightGlobalWithinApp(appId, insightId, isPublic); + + // also update in the app itself + // so it is properly synchronized with the security db + ClusterUtil.reactorPullInsightsDB(appId); + IEngine app = Utility.getEngine(appId); + InsightAdministrator admin = new InsightAdministrator(app.getInsightDatabase()); + admin.updateInsightGlobal(insightId, !isPublic); + ClusterUtil.reactorPushInsightDB(appId); + } catch (Exception e) { logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); diff --git a/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java index 20c160234..b28b057d8 100644 --- a/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java @@ -20,8 +20,12 @@ import prerna.auth.User; import prerna.auth.utils.SecurityAppUtils; import prerna.auth.utils.SecurityInsightUtils; +import prerna.cluster.util.ClusterUtil; +import prerna.engine.api.IEngine; +import prerna.engine.impl.InsightAdministrator; import prerna.semoss.web.services.local.ResourceUtility; import prerna.util.Constants; +import prerna.util.Utility; import prerna.web.services.util.WebUtility; @Path("/auth/insight") @@ -285,6 +289,15 @@ public Response setInsightGlobal(@Context HttpServletRequest request, Multivalue try { SecurityInsightUtils.setInsightGlobalWithinApp(user, appId, insightId, isPublic); + + // also update in the app itself + // so it is properly synchronized with the security db + ClusterUtil.reactorPullInsightsDB(appId); + IEngine app = Utility.getEngine(appId); + InsightAdministrator admin = new InsightAdministrator(app.getInsightDatabase()); + admin.updateInsightGlobal(insightId, !isPublic); + ClusterUtil.reactorPushInsightDB(appId); + } catch (IllegalAccessException e) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to set the insight " + insightId + " in app " + appId + logPublic + " without having proper access")); logger.error(Constants.STACKTRACE, e); From 1b2a6102d0d61008b5e378f6d3c6516508708b18 Mon Sep 17 00:00:00 2001 From: pkapaleeswaran Date: Mon, 3 Aug 2020 17:58:05 +0000 Subject: [PATCH 0629/1906] Shutdown python singleton if no user in the contextDestroyed git-svn-id: svn://107.170.10.188:8080/Monolith/dev@39613 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 47e255371d68f681dcae5c7a4a46085e73120ba9 --- src/prerna/web/conf/DBLoader.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/prerna/web/conf/DBLoader.java b/src/prerna/web/conf/DBLoader.java index 4fab8875c..0f2bb8260 100644 --- a/src/prerna/web/conf/DBLoader.java +++ b/src/prerna/web/conf/DBLoader.java @@ -51,6 +51,7 @@ import prerna.nameserver.utility.MasterDatabaseUtility; import prerna.om.Insight; import prerna.om.InsightStore; +import prerna.sablecc2.reactor.frame.r.util.PyTranslatorFactory; import prerna.sablecc2.reactor.frame.r.util.RJavaTranslatorFactory; import prerna.sablecc2.reactor.scheduler.SchedulerFactorySingleton; import prerna.sablecc2.reactor.scheduler.SchedulerH2DatabaseUtility; @@ -300,6 +301,7 @@ public void contextDestroyed(ServletContextEvent arg0) { // close r try { RJavaTranslatorFactory.stopRConnection(); + PyTranslatorFactory.stopPy(); } catch (Exception e) { logger.error(STACKTRACE, e); } From bdc60c992fe89b292b14adbed3727566691d3ff8 Mon Sep 17 00:00:00 2001 From: pkapaleeswaran Date: Mon, 10 Aug 2020 20:35:13 +0000 Subject: [PATCH 0630/1906] Enable FileSpace Access First Filter checks for session Second checks to see if they have access to that folder NoUserInSessionFileFilter prerna.web.conf.FilespaceAccessFilter NoUserInSessionFilter /public_home/* NoUserInSessionFileFilter /public_home/* git-svn-id: svn://107.170.10.188:8080/Monolith/dev@39692 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 23482881309abb7cbb3ac9f5c30e98b9294edb0a --- .../web/conf/FilespaceAccessFilter.java | 70 +++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 src/prerna/web/conf/FilespaceAccessFilter.java diff --git a/src/prerna/web/conf/FilespaceAccessFilter.java b/src/prerna/web/conf/FilespaceAccessFilter.java new file mode 100644 index 000000000..324f83666 --- /dev/null +++ b/src/prerna/web/conf/FilespaceAccessFilter.java @@ -0,0 +1,70 @@ +package prerna.web.conf; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import prerna.auth.User; +import prerna.util.Constants; + +public class FilespaceAccessFilter implements Filter { + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + // TODO Auto-generated method stub + + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { + // TODO Auto-generated method stub + try + { + // get the space it is trying to access + // get the user from the session + // see if this user can access this space + // allow / redirect + HttpServletRequest hsr = (HttpServletRequest)request; + String url = hsr.getRequestURI(); + // this is typically of the pattern + // http://blah blah/Monolith/public_home/app__app_id/something + String publicHome = "/" + Constants.PUBLIC_HOME + "/"; + int publicHomeIndex = url.indexOf(publicHome); + if(publicHomeIndex >= 0) + { + String appHome = url.substring(publicHomeIndex + publicHome.length()); + int appRootIndex = appHome.indexOf("/"); + if(appRootIndex >= 0) + { + String appRoot = appHome.substring(0, appRootIndex); + String [] appRootElements = appRoot.split("__"); + User user = (User)hsr.getSession().getAttribute(Constants.SESSION_USER); + if(user.checkAppAccess(appRootElements[0], appRootElements[1])) + chain.doFilter(request, response); + else + { + ((HttpServletResponse)response).sendError(HttpServletResponse.SC_FORBIDDEN, " You are not allowed to access that resource ");; + } + } + } + }catch(Exception ex) + { + + } + } + + @Override + public void destroy() { + // TODO Auto-generated method stub + + } + +} From 81c921728160fb9dde50e9271ad96d7a1da47c4e Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 18 Aug 2020 15:22:48 +0000 Subject: [PATCH 0631/1906] UPDATE ::: Updating scheduler key to run via the end point instead of within the same thread git-svn-id: svn://107.170.10.188:8080/Monolith/dev@39753 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: b8ce9a842f02565115506044ff11c6c9f162067f --- .../semoss/web/app/MonolithApplication.java | 2 + .../semoss/web/services/local/NameServer.java | 6 +- .../web/services/local/SchedulerResource.java | 51 ++++++++++++ src/prerna/web/conf/DBLoader.java | 11 +-- src/prerna/web/conf/SchedulerFilter.java | 79 +++++++++++++++++++ 5 files changed, 139 insertions(+), 10 deletions(-) create mode 100644 src/prerna/semoss/web/services/local/SchedulerResource.java create mode 100644 src/prerna/web/conf/SchedulerFilter.java diff --git a/src/prerna/semoss/web/app/MonolithApplication.java b/src/prerna/semoss/web/app/MonolithApplication.java index b8641873d..29e95ebd2 100644 --- a/src/prerna/semoss/web/app/MonolithApplication.java +++ b/src/prerna/semoss/web/app/MonolithApplication.java @@ -39,6 +39,7 @@ import prerna.semoss.web.services.local.AuthorizationResource; import prerna.semoss.web.services.local.ExecuteInsightResource; import prerna.semoss.web.services.local.NameServer; +import prerna.semoss.web.services.local.SchedulerResource; import prerna.semoss.web.services.local.SessionResource; import prerna.semoss.web.services.local.ShareInsightResource; import prerna.semoss.web.services.local.ThemeResource; @@ -71,6 +72,7 @@ public MonolithApplication() { // insight execution singletons.add(new ExecuteInsightResource()); singletons.add(new ShareInsightResource()); + singletons.add(new SchedulerResource()); // other singletons.add(new ThemeResource()); singletons.add(new ServerConfigurationResource()); diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index 4a2b2b6cb..ed1c7e5a3 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -723,8 +723,10 @@ public void killJob(@QueryParam("jobId") String jobId, @Context HttpServletReque public String getServerURL(HttpServletRequest request) { if(NameServer.baseURL == null) { //http://localhost:8080/appui/ - StringBuffer baseURL = new StringBuffer(request.getHeader("referer")).append("#!/"); - NameServer.baseURL = baseURL.toString(); + if(request.getHeader("referer") != null) { + StringBuffer baseURL = new StringBuffer(request.getHeader("referer")).append("#!/"); + NameServer.baseURL = baseURL.toString(); + } } return baseURL; } diff --git a/src/prerna/semoss/web/services/local/SchedulerResource.java b/src/prerna/semoss/web/services/local/SchedulerResource.java new file mode 100644 index 000000000..16e12265a --- /dev/null +++ b/src/prerna/semoss/web/services/local/SchedulerResource.java @@ -0,0 +1,51 @@ +package prerna.semoss.web.services.local; + +import java.util.HashMap; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.Response; + +import prerna.rpa.config.JobConfigKeys; +import prerna.web.requests.OverrideParametersServletRequest; + +@Path("/schedule") +public class SchedulerResource { + + @POST + @Path("/executePixel") + @Produces("application/json") + public Response executePixel(@Context HttpServletRequest request) { + // we will flush the user object inside + // and make sure the + String pixel = request.getParameter(JobConfigKeys.PIXEL); + return runPixel(request, pixel); + } + + /** + * Utility method to execute the pixel on the insight + * @param request + * @param pixel + * @return + */ + private Response runPixel(@Context HttpServletRequest request, String pixel) { + if(pixel.endsWith(";")) { + pixel = pixel + "DropInsight();"; + } else { + pixel = pixel + ";DropInsight();"; + } + + NameServer ns = new NameServer(); + OverrideParametersServletRequest requestWrapper = new OverrideParametersServletRequest(request); + Map paramMap = new HashMap(); + paramMap.put("expression", pixel); + requestWrapper.setParameters(paramMap); + return ns.runPixelSync(requestWrapper); + } + + +} diff --git a/src/prerna/web/conf/DBLoader.java b/src/prerna/web/conf/DBLoader.java index 0f2bb8260..f3d6f14b2 100644 --- a/src/prerna/web/conf/DBLoader.java +++ b/src/prerna/web/conf/DBLoader.java @@ -27,7 +27,6 @@ *******************************************************************************/ package prerna.web.conf; -import java.sql.SQLException; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -206,13 +205,9 @@ public void contextInitialized(ServletContextEvent arg0) { // Load and run triggerOnLoad jobs RDBMSNativeEngine schedulerDb = (RDBMSNativeEngine) Utility.getEngine(Constants.SCHEDULER_DB); if(schedulerDb != null) { - try { - SchedulerH2DatabaseUtility.executeAllTriggerOnLoads(schedulerDb.getConnection()); - // also add legacy json files - JsonConversionToQuartzJob.runUpdateFromLegacyFormat(); - } catch (SQLException e) { - logger.error(STACKTRACE, e); - } + SchedulerH2DatabaseUtility.executeAllTriggerOnLoads(); + // also add legacy json files + JsonConversionToQuartzJob.runUpdateFromLegacyFormat(); } } diff --git a/src/prerna/web/conf/SchedulerFilter.java b/src/prerna/web/conf/SchedulerFilter.java new file mode 100644 index 000000000..786dc1016 --- /dev/null +++ b/src/prerna/web/conf/SchedulerFilter.java @@ -0,0 +1,79 @@ +package prerna.web.conf; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpSession; + +import org.apache.log4j.LogManager; +import org.apache.log4j.Logger; + +import prerna.auth.AccessToken; +import prerna.auth.AuthProvider; +import prerna.auth.User; +import prerna.rpa.config.JobConfigKeys; +import prerna.sablecc2.reactor.scheduler.SchedulerH2DatabaseUtility; +import prerna.util.Constants; + +public class SchedulerFilter implements Filter { + + private static final Logger logger = LogManager.getLogger(SchedulerFilter.class); + + @Override + public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { + HttpServletRequest request = (HttpServletRequest) arg0; + + String execId = request.getParameter(JobConfigKeys.EXEC_ID); + String jobName = request.getParameter(JobConfigKeys.JOB_NAME); + String jobGroup = request.getParameter(JobConfigKeys.JOB_GROUP); + + // make sure the request is valid + String[] jobInfo = SchedulerH2DatabaseUtility.executionIdExists(execId); + if(jobInfo == null) { + // error + logger.info("Could not find the scheduler execution id"); + return; + } + if(!jobInfo[0].equals(jobName) || !jobInfo[1].equals(jobGroup)) { + // error + logger.info("Found scheduler execution id but could not match to details"); + return; + } + + HttpSession session = request.getSession(true); + String userAccess = request.getParameter(JobConfigKeys.USER_ACCESS); + // Add user info to the insight + User user = new User(); + String[] accessPairs = userAccess.split(","); + for (String accessPair : accessPairs) { + String[] providerAndId = accessPair.split(":"); + + // Get the auth provider + AuthProvider provider = AuthProvider.valueOf(providerAndId[0]); + + // Get the id + String id = providerAndId[1]; + + // Create the access token + AccessToken token = new AccessToken(); + token.setProvider(provider); + token.setId(id); + + user.setAccessToken(token); + } + session.setAttribute(Constants.SESSION_USER, user); + + // clean up the table + SchedulerH2DatabaseUtility.removeExecutionId(execId); + + // continue + arg2.doFilter(arg0, arg1); + } + + +} From 8edd31eb9e961d5965339602e1a2d6590becc2b7 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 18 Aug 2020 15:23:30 +0000 Subject: [PATCH 0632/1906] UPDATE ::: Adding the scheduler filter for security git-svn-id: svn://107.170.10.188:8080/Monolith/dev@39754 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: aebe298dc663d68a5302669039fbb6d209a2bd52 --- WebContent/WEB-INF/web.xml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index 3d38e60f4..ed56679a7 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -47,6 +47,16 @@ /api/* + + + SchedulerFilter + prerna.web.conf.SchedulerFilter + + + SchedulerFilter + /api/schedule/* + + + + io.prestosql + presto-jdbc + 340 + - + + com.univocity univocity-parsers From 13a7a3a4a796d67cba529cfd51014af4a89d9846 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 3 Sep 2020 03:29:48 +0000 Subject: [PATCH 0642/1906] UPDATE ::: Removing jclouds package and its dependencies git-svn-id: svn://107.170.10.188:8080/Monolith/dev@39966 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: e78c762f737a9470d5cf9e00996f34db1fec40d1 --- pom.xml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 50ace75ac..7302b79c8 100644 --- a/pom.xml +++ b/pom.xml @@ -2373,7 +2373,8 @@ 1.4.0 - + + + io.minio minio From b662abe31eb9f41b18d1ca7ffceb29788b4110db Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 3 Sep 2020 04:24:53 +0000 Subject: [PATCH 0643/1906] UPDATE ::: pom.xml cleanup and version updates git-svn-id: svn://107.170.10.188:8080/Monolith/dev@39967 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 7fd4ac972725fa717dfaf94a903fd913e2b45459 --- pom.xml | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/pom.xml b/pom.xml index 7302b79c8..13df9cab0 100644 --- a/pom.xml +++ b/pom.xml @@ -489,7 +489,7 @@ commons-fileupload commons-fileupload - 1.3 + 1.3.3 * @@ -2079,18 +2079,6 @@ - - aurelionribon.ui css-engine-swing-api @@ -2963,7 +2951,7 @@ org.apache.zookeeper zookeeper - 3.4.9 + 3.4.10 * From a6a62c8860c5d4d1ffe5a83663937f0da4f0432f Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 3 Sep 2020 04:41:19 +0000 Subject: [PATCH 0644/1906] UPDATE ::: pom.xml cleanup and version updates git-svn-id: svn://107.170.10.188:8080/Monolith/dev@39968 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 7dfbe2b54c1d8cd53663c12f65c582cd5682dde9 --- pom.xml | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/pom.xml b/pom.xml index 13df9cab0..8a9bf7479 100644 --- a/pom.xml +++ b/pom.xml @@ -2529,19 +2529,29 @@ neo4j-tinkerpop-api-impl 0.9-3.4.0 - - org.bouncycastle - bcpkix-jdk15on - - - io.netty - netty - - - io.netty - netty-all - - + + org.bouncycastle + bcpkix-jdk15on + + + io.netty + netty + + + io.netty + netty-all + + + org.apache.shiro + * + + + + + + org.apache.shiro + shiro-core + 1.6.0 From 2a1c2830d7126722293a84799e90eaf34616f390 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 3 Sep 2020 23:07:41 +0000 Subject: [PATCH 0645/1906] UPDATE ::: pom.xml cleanup and version updates and removing commented out unused jars git-svn-id: svn://107.170.10.188:8080/Monolith/dev@39972 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: c07a5a5b00661f9e507618a44276031f3135d223 --- pom.xml | 1746 +++++++------------------------------------------------ 1 file changed, 205 insertions(+), 1541 deletions(-) diff --git a/pom.xml b/pom.xml index 8a9bf7479..7e3a517d6 100644 --- a/pom.xml +++ b/pom.xml @@ -271,12 +271,8 @@ - + redshift http://redshift-maven-repository.s3-website-us-east-1.amazonaws.com/release @@ -306,18 +302,6 @@ - - org.apache.lucene lucene-core @@ -343,10 +327,10 @@ - org.apache.lucene - lucene-analyzers-smartcn - 5.5.5 - + org.apache.lucene + lucene-analyzers-smartcn + 5.5.5 + * * @@ -361,10 +345,10 @@ - com.blazegraph - bigdata-core - 2.1.4 - + com.blazegraph + bigdata-core + 2.1.4 + org.* * @@ -387,18 +371,6 @@ - - org.apache.commons commons-collections4 @@ -574,198 +546,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - org.apache.tinkerpop tinkergraph-gremlin @@ -832,18 +612,6 @@ - - org.codehaus.groovy groovy-jsr223 @@ -856,19 +624,6 @@ - - com.google.code.gson gson @@ -891,24 +646,11 @@ - - com.github.spullara.mustache.java compiler 0.9.2 - com.github.stephenc.high-scale-lib high-scale-lib @@ -920,18 +662,6 @@ - - org.apache.httpcomponents httpclient @@ -943,30 +673,6 @@ - - - - org.apache.httpcomponents httpcore @@ -978,18 +684,6 @@ - - com.ibm.icu icu4j @@ -1024,42 +718,6 @@ - - - - - - org.javatuples javatuples @@ -1082,42 +740,6 @@ - - - - - - redis.clients jedis @@ -1151,7 +773,6 @@ - org.apache.jena jena-iri @@ -1174,7 +795,6 @@ - org.apache.jena jena-tdb @@ -1186,23 +806,11 @@ - - - org.python - jython - 2.7.1b3 + org.python + jython + 2.7.1b3 org.codehaus.jet @@ -1215,18 +823,6 @@ - - org.jgrapht jgrapht-core @@ -1260,54 +856,6 @@ - - - - - - - - org.jsoup jsoup @@ -1330,18 +878,6 @@ - - net.sf.jung jung-algorithms @@ -1386,18 +922,6 @@ - - log4j log4j @@ -1420,18 +944,6 @@ - - org.mapdb mapdb @@ -1465,18 +977,6 @@ - - mysql mysql-connector-java @@ -1488,49 +988,13 @@ - - - - io.netty - + netty-all 4.1.47.Final compile - - com.oracle ojdbc6 @@ -1578,27 +1042,15 @@ org.apache.poi - ooxml-schemas - 1.4 - + ooxml-schemas + 1.4 + - org.apache.poi - poi-scratchpad - 4.1.1 + org.apache.poi + poi-scratchpad + 4.1.1 - - org.jboss.resteasy resteasy-jaxrs @@ -1631,529 +1083,45 @@ * - - - com.restfb - restfb - 1.6.16 - - - * - * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - edu.stanford.nlp - stanford-corenlp - 3.3.0 - - - * - * - - - - - edu.stanford.nlp - stanford-corenlp - 3.3.0 - models - - - * - * - - - - - - - - - - - com.univocity - univocity-parsers - 2.8.4 - - - * - * - - - - - - - com.github.dblock.waffle - waffle-jna - 1.8.1 - - - * - * - - - - - javax.servlet - javax.servlet-api - 3.1.0 - provided - - - net.java.dev.jna - jna - 4.3.0 - - - net.java.dev.jna - jna-platform - 4.3.0 - - - nz.ac.waikato.cms.weka - weka - 3.6.12 - - - * - * - - - - - - - - - - org.apache.xmlbeans - xmlbeans - 3.1.0 - - - * - * - - - - - - - - - it.unimi.dsi - dsiutils - 2.4.2 - - - - ch.qos.logback - logback-classic - - - ch.qos.logback - logback-core - - - - - aurelionribon.ui - css-engine-swing-api - 1.0.0 - - - * - * - - - - - - - - - - - - - + - com.teamdev.jxbrowser - jxbrowser - 5.2 + com.univocity + univocity-parsers + 2.8.4 * @@ -2161,70 +1129,85 @@ - - - - - - - - - - + - org.rednoise - rita - 1.0.68 + com.teamdev.jxbrowser + jxbrowser + 5.2 * @@ -2232,10 +1215,9 @@ - - + com.microsoft sqlserver @@ -2255,29 +1237,6 @@ - - - org.rosuda.REngine Rserve @@ -2311,83 +1270,12 @@ - - - - - - - - - - - - - - - - org.scala-lang scala-library 2.11.7 - - - - - - - - - org.javassist @@ -2406,14 +1294,14 @@ org.owasp.encoder - encoder - 1.2.2 + encoder + 1.2.2 - com.google.re2j - re2j - 1.3 - + com.google.re2j + re2j + 1.3 + net.lingala.zip4j zip4j @@ -2429,43 +1317,17 @@ JRI 0.5.6 - + net.sf.extjwnl extjwnl 1.9.2 - - - - - - junit junit 4.12 - - - - org.quartz-scheduler quartz @@ -2478,16 +1340,10 @@ - javax.mail - mail - 1.5.0-b01 + javax.mail + mail + 1.5.0-b01 - - com.h2database @@ -2501,29 +1357,18 @@ - io.prestosql - presto-jdbc - 340 + io.prestosql + presto-jdbc + 340 - - - - org.apache.tinkerpop neo4j-gremlin 3.4.1 - + org.neo4j neo4j-tinkerpop-api-impl @@ -2549,9 +1394,9 @@ - org.apache.shiro - shiro-core - 1.6.0 + org.apache.shiro + shiro-core + 1.6.0 @@ -2570,39 +1415,12 @@ commons-validator 1.4.0 - - - - - org.eclipse.jgit org.eclipse.jgit 4.8.0.201706111038-r - - - - - - org.kohsuke @@ -2614,31 +1432,6 @@ org.eclipse.egit.github.core 2.1.5 - - - - - com.cloudera impala4 @@ -2650,19 +1443,6 @@ - - - org.apache.thrift thrift @@ -2674,19 +1454,6 @@ - - - org.apache.hive tcli_service @@ -2698,19 +1465,6 @@ - - - - - org.json json @@ -2722,77 +1476,50 @@ 2.10.5 - com.fasterxml.jackson.core - jackson-annotations - 2.10.5 + com.fasterxml.jackson.core + jackson-annotations + 2.10.5 - com.fasterxml.jackson.core - jackson-core - 2.10.5 + com.fasterxml.jackson.core + jackson-core + 2.10.5 com.amazon.redshift redshift-jdbc41 1.2.10.1009 - + com.eclipsesource.j2v8 j2v8_win32_x86_64 4.4.0 - - - - - - - - - - - - - black.ninia - jep - 3.9.0 - - - - com.datastax.dse - dse-java-driver-graph - 1.4.0 - - - io.netty - netty - - - io.netty - netty-all - - - io.netty - netty-handler - - + + black.ninia + jep + 3.9.0 + + + + com.datastax.dse + dse-java-driver-graph + 1.4.0 + + + io.netty + netty + + + io.netty + netty-all + + + io.netty + netty-handler + + @@ -2807,56 +1534,20 @@ - org.xerial - sqlite-jdbc - 3.28.0 + org.xerial + sqlite-jdbc + 3.28.0 - com.jayway.jsonpath - json-path - 2.3.0 + com.jayway.jsonpath + json-path + 2.3.0 io.burt jmespath-jackson 0.2.0 - - - - - - - - - - au.com.bytecode @@ -2889,9 +1580,9 @@ - com.sun.jersey - jersey-core - 1.19 + com.sun.jersey + jersey-core + 1.19 * @@ -2906,10 +1597,10 @@ 3.1.0 - org.seleniumhq.selenium - selenium-java - 3.4.0 - + org.seleniumhq.selenium + selenium-java + 3.141.59 + net.java.dev.jna jna @@ -2920,32 +1611,16 @@ - - net.lingala.zip4j - zip4j - 1.3.2 + + net.lingala.zip4j + zip4j + 1.3.2 - - - io.minio - minio - 4.0.2 - + io.minio + minio + 4.0.2 + com.google.http-client google-http-client-xml @@ -2954,9 +1629,9 @@ - org.freemarker - freemarker - 2.3.20 + org.freemarker + freemarker + 2.3.20 org.apache.zookeeper @@ -3002,11 +1677,11 @@ - - org.wikidata.wdtk - wdtk-datamodel - 0.9.0 - + + org.wikidata.wdtk + wdtk-datamodel + 0.9.0 + * * @@ -3014,10 +1689,10 @@ - org.wikidata.wdtk - wdtk-util - 0.9.0 - + org.wikidata.wdtk + wdtk-util + 0.9.0 + * * @@ -3025,10 +1700,10 @@ - org.apache.commons - commons-compress - 1.19 - + org.apache.commons + commons-compress + 1.19 + * * @@ -3036,40 +1711,35 @@ - net.snowflake - snowflake-jdbc - 3.12.11 + net.snowflake + snowflake-jdbc + 3.12.11 - ru.yandex.clickhouse - clickhouse-jdbc - 0.2 + ru.yandex.clickhouse + clickhouse-jdbc + 0.2 - - com.amazonaws - aws-java-sdk-s3 - 1.11.690 + com.amazonaws + aws-java-sdk-s3 + 1.11.690 - com.syncron.amazonaws - simba-athena-jdbc-driver - 2.0.2 + com.syncron.amazonaws + simba-athena-jdbc-driver + 2.0.2 - me.xdrop - fuzzywuzzy - 1.2.0 + me.xdrop + fuzzywuzzy + 1.2.0 - io.github.classgraph - classgraph - 4.8.27 - + io.github.classgraph + classgraph + 4.8.27 + org.janusgraph janusgraph-core @@ -3135,18 +1805,6 @@ true - org.graphstream @@ -3171,7 +1829,7 @@ bouncycastle bcmail-jdk14 - + bouncycastle bcprov-jdk14 @@ -3179,5 +1837,11 @@ 1.3 + + + org.eclipse.jetty + jetty-io + 9.4.11.v20180605 + \ No newline at end of file From b6433c91c87342e4588e18831c5e0e1d2016e537 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Sat, 5 Sep 2020 14:38:27 +0000 Subject: [PATCH 0646/1906] BUGFIX ::: Fixing jar missing error by updating resteasy version git-svn-id: svn://107.170.10.188:8080/Monolith/dev@39979 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 966e5e0ca34ffecaca11b81a25f71a0d93a977a7 --- pom.xml | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/pom.xml b/pom.xml index 7e3a517d6..f02a09814 100644 --- a/pom.xml +++ b/pom.xml @@ -1054,18 +1054,12 @@ org.jboss.resteasy resteasy-jaxrs - 3.0.9.Final - - - * - * - - + 3.13.0.Final org.jboss.resteasy jaxrs-api - 3.0.9.Final + 3.0.12.Final * @@ -1076,7 +1070,7 @@ org.jboss.resteasy resteasy-multipart-provider - 3.0.9.Final + 3.13.0.Final * From bcb48aab020100ebd920ce6dd07be836f55ef52a Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Sun, 6 Sep 2020 15:27:27 +0000 Subject: [PATCH 0647/1906] UPDATE ::: Cleanup of jackson dependencies git-svn-id: svn://107.170.10.188:8080/Monolith/dev@39984 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 586e94c37acfd0303c2a049fe20fe33402c4bc04 --- pom.xml | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index f02a09814..844c82547 100644 --- a/pom.xml +++ b/pom.xml @@ -1479,10 +1479,11 @@ jackson-core 2.10.5 + - com.amazon.redshift - redshift-jdbc41 - 1.2.10.1009 + com.amazon.redshift + redshift-jdbc42 + 1.2.43.1067 @@ -1723,6 +1724,12 @@ com.syncron.amazonaws simba-athena-jdbc-driver 2.0.2 + + + com.fasterxml.* + * + + me.xdrop From e0cf7bf9c84b2b7d1bece47771bc64cf52729bb5 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Sun, 6 Sep 2020 15:50:39 +0000 Subject: [PATCH 0648/1906] UPDATE ::: Fixing log4j vulnerability git-svn-id: svn://107.170.10.188:8080/Monolith/dev@39985 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 448590da11ed81ac420adfb3b1843301bf2380fc --- pom.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pom.xml b/pom.xml index 844c82547..078200c8a 100644 --- a/pom.xml +++ b/pom.xml @@ -1729,6 +1729,10 @@ com.fasterxml.* * + + log4j + * + From 749d1ced4fe12bd04e51495404119af7a1941cdf Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Sun, 6 Sep 2020 16:34:19 +0000 Subject: [PATCH 0649/1906] UPDATE ::: Fixing collections and beanutils vulnerabilities git-svn-id: svn://107.170.10.188:8080/Monolith/dev@39986 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: fb1e75eb7c9c9052b2e1ab62352179069b2b00ed --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 078200c8a..5cbd6d9fd 100644 --- a/pom.xml +++ b/pom.xml @@ -429,12 +429,12 @@ commons-collections commons-collections - 3.2.1 + 3.2.2 commons-beanutils commons-beanutils - 1.9.2 + 1.9.4 org.apache.commons From 47c7f08d594c83a208f40833fcfb15239ebf6803 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Sun, 6 Sep 2020 16:55:17 +0000 Subject: [PATCH 0650/1906] UPDATE ::: Excluding legacy jsckson jar from gremlin neo4j jar git-svn-id: svn://107.170.10.188:8080/Monolith/dev@39990 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 8bf915d1ad4fb798a05634a67fcdfb85b416581c --- pom.xml | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 5cbd6d9fd..9d3fd0ea2 100644 --- a/pom.xml +++ b/pom.xml @@ -1368,22 +1368,26 @@ neo4j-tinkerpop-api-impl 0.9-3.4.0 - + org.bouncycastle bcpkix-jdk15on - + io.netty netty - + io.netty netty-all - + org.apache.shiro * + + org.codehaus.jackson + jackson-mapper-asl + From 7ad18d0ce1b0042a0baf6dc493fda54269fd4323 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Sun, 6 Sep 2020 18:26:56 +0000 Subject: [PATCH 0651/1906] UPDATE ::: Increasing lang3 and netty, and neo4j, and fasterxml version UPDATE ::: Code changes to use new fasterxml packages and not legacy org.codehaus.jackson package git-svn-id: svn://107.170.10.188:8080/Monolith/dev@39991 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: f31d424999d9295e6020a0d8970b0c85dfe99037 --- pom.xml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/pom.xml b/pom.xml index 9d3fd0ea2..28a3301c0 100644 --- a/pom.xml +++ b/pom.xml @@ -505,7 +505,7 @@ org.apache.commons commons-lang3 - 3.4 + 3.8.1 * @@ -990,9 +990,8 @@ io.netty - netty-all - 4.1.47.Final + 4.1.51.Final compile @@ -1400,12 +1399,12 @@ org.neo4j.driver neo4j-java-driver - 1.7.5 + 4.1.1 org.neo4j neo4j-jdbc-bolt - 3.4.0 + 4.0.1 @@ -1471,17 +1470,17 @@ com.fasterxml.jackson.core jackson-databind - 2.10.5 + 2.11.0 com.fasterxml.jackson.core jackson-annotations - 2.10.5 + 2.11.0 com.fasterxml.jackson.core jackson-core - 2.10.5 + 2.11.0 @@ -1526,10 +1525,11 @@ javapoet 1.2.0 + - com.github.wnameless - json-flattener - 0.4.1 + com.github.wnameless.json + json-flattener + 0.9.0 From cfe53cbc775357a833e732403d5868c19074c9cb Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Sun, 6 Sep 2020 18:49:02 +0000 Subject: [PATCH 0652/1906] UPDATE ::: Reverting back neo4j jars as newest versions require java 10 which is incompatible with our pipeline git-svn-id: svn://107.170.10.188:8080/Monolith/dev@39992 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 2fb1f672c4dc15659394721aa532b1a79fe9276a --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 28a3301c0..7c11b1d76 100644 --- a/pom.xml +++ b/pom.xml @@ -1399,12 +1399,12 @@ org.neo4j.driver neo4j-java-driver - 4.1.1 + 1.7.5 org.neo4j neo4j-jdbc-bolt - 4.0.1 + 3.4.0 From db4c709aff4b8297851b04cb15ee4934d3c8a996 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 7 Sep 2020 14:11:31 +0000 Subject: [PATCH 0653/1906] UPDATE ::: Fixing issues with resteasy and jetty io dependencies git-svn-id: svn://107.170.10.188:8080/Monolith/dev@39997 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 4c1afd965bff167478a5510adcad3da0490d4724 --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 7c11b1d76..bb2cb4d0b 100644 --- a/pom.xml +++ b/pom.xml @@ -1069,7 +1069,7 @@ org.jboss.resteasy resteasy-multipart-provider - 3.13.0.Final + 4.5.6.Final * @@ -1848,9 +1848,9 @@ - org.eclipse.jetty - jetty-io - 9.4.11.v20180605 + org.eclipse.jetty + jetty-io + 9.4.12.v20180830 \ No newline at end of file From 1247cb839ed6c85545c7bc6c95f6776d1070447e Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 8 Sep 2020 22:30:25 +0000 Subject: [PATCH 0654/1906] UPDATE ::: Updating log4j jar git-svn-id: svn://107.170.10.188:8080/Monolith/dev@40022 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 58b9ad2315909c70220b42415b92990dddb934ab --- pom.xml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index bb2cb4d0b..e96e2e7da 100644 --- a/pom.xml +++ b/pom.xml @@ -922,11 +922,12 @@ + - log4j - log4j - 1.2.17 - + org.apache.logging.log4j + log4j-api + 2.0 + * * From fe279e626e4713fe70232182ceebb0d3dc113665 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 9 Sep 2020 18:27:21 +0000 Subject: [PATCH 0655/1906] UPDATE ::: Increasing resteasy api jar to new maintained version git-svn-id: svn://107.170.10.188:8080/Monolith/dev@40031 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: d75f44d8a23b1a29ae12d9b46b2f7eae4d662fa3 --- pom.xml | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/pom.xml b/pom.xml index e96e2e7da..94d2154f6 100644 --- a/pom.xml +++ b/pom.xml @@ -1053,19 +1053,13 @@ org.jboss.resteasy - resteasy-jaxrs - 3.13.0.Final + resteasy-core + 4.5.6.Final org.jboss.resteasy - jaxrs-api - 3.0.12.Final - - - * - * - - + resteasy-jaxb-provider + 4.5.6.Final org.jboss.resteasy From f342c5008074b7b22ba9676c50276108ce5f8f21 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 9 Sep 2020 20:54:07 +0000 Subject: [PATCH 0656/1906] UPDATE ::: Hopefully final cleanup of jar files for security vulnerabilities git-svn-id: svn://107.170.10.188:8080/Monolith/dev@40039 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 80aeb3d970aeb27a0e9bcd67247dc82c0c16d8d6 --- pom.xml | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 94d2154f6..936f1d749 100644 --- a/pom.xml +++ b/pom.xml @@ -369,6 +369,10 @@ javax.* * + + log4j + * + @@ -926,7 +930,7 @@ org.apache.logging.log4j log4j-api - 2.0 + 2.13.2 * @@ -1279,6 +1283,12 @@ org.owasp.esapi esapi 2.1.0.1 + + + log4j + * + + org.owasp.encoder From f9b950b485391f124b40615d6cc3c3e26e698d01 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 10 Sep 2020 02:26:42 +0000 Subject: [PATCH 0657/1906] UPDATE ::: Reverting back log4j v until have way to fix cloud deployment git-svn-id: svn://107.170.10.188:8080/Monolith/dev@40046 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 16e118bdf71bc10c99dfab25ad147289922cf850 --- pom.xml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index 936f1d749..4a2a69c9c 100644 --- a/pom.xml +++ b/pom.xml @@ -926,7 +926,13 @@ - + + + log4j + log4j + 1.2.17 + + com.datumbox lpsolve From fbf35b1411d7ebb69de21ab73ae7e9b8082d8b71 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Sat, 12 Sep 2020 14:51:50 +0000 Subject: [PATCH 0658/1906] UPDATE ::: Upgrading again to log4j2 git-svn-id: svn://107.170.10.188:8080/Monolith/dev@40100 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 4e08d21d26707cc60a3d340a13f3e07b14762181 --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 4a2a69c9c..9a54410a3 100644 --- a/pom.xml +++ b/pom.xml @@ -926,13 +926,13 @@ - + + org.apache.logging.log4j log4j-api @@ -943,7 +943,7 @@ * - + com.datumbox lpsolve From 1f429a299b7fa7858c419f219fcb16483c97fc37 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Sun, 13 Sep 2020 04:20:31 +0000 Subject: [PATCH 0659/1906] UPDATE ::: Modifying logger to log4j2 UPDATE ::: Updating sesame rdf packages git-svn-id: svn://107.170.10.188:8080/Monolith/dev@40104 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 1b39d34eeaacb805d8ffbcbc6f335abc17a0d3f9 --- pom.xml | 43 +++++++++- .../cluster/RawSelectWrapperService.java | 4 +- src/prerna/semoss/web/form/FormResource.java | 5 +- .../config/ServerConfigurationResource.java | 4 +- .../web/services/local/AppResource.java | 5 +- .../services/local/AuthorizationResource.java | 5 +- .../web/services/local/DataframeResource.java | 4 +- .../web/services/local/EngineResource.java | 5 +- .../semoss/web/services/local/NameServer.java | 4 +- .../semoss/web/services/local/RunInsight.java | 4 +- .../web/services/local/SessionResource.java | 4 +- .../web/services/local/UserResource.java | 4 +- .../auth/AdminAppAuthorizationResource.java | 5 +- .../AdminInsightAuthorizationResource.java | 5 +- .../auth/AdminUserAuthorizationResource.java | 5 +- .../local/auth/AppAuthorizationResource.java | 5 +- .../auth/InsightAuthorizationResource.java | 5 +- .../services/remote/CentralNameServer.java | 19 +---- .../services/remote/EngineRemoteResource.java | 4 +- .../upload/FileUploadProgressListener.java | 4 +- src/prerna/upload/FileUploader.java | 4 +- src/prerna/upload/ImageUploader.java | 4 +- src/prerna/upload/Uploader.java | 4 +- src/prerna/web/conf/AdminStartupFilter.java | 4 +- src/prerna/web/conf/AnonymousUserFilter.java | 4 +- src/prerna/web/conf/CACFilter.java | 4 +- src/prerna/web/conf/DBLoader.java | 78 ++++++++++++------- src/prerna/web/conf/IASFilter.java | 4 +- src/prerna/web/conf/NoUserExistsFilter.java | 4 +- .../web/conf/NoUserInSessionFilter.java | 4 +- .../NoUserInSessionTrustedTokenFilter.java | 4 +- src/prerna/web/conf/PIVFilter.java | 52 ++++++------- src/prerna/web/conf/SchedulerFilter.java | 4 +- .../conf/SetAdminSessionTimeoutFilter.java | 4 +- src/prerna/web/conf/UserDBLoader.java | 4 +- src/prerna/web/conf/UserExistsFilter.java | 4 +- src/prerna/web/conf/UserSessionLoader.java | 4 +- src/prerna/web/conf/WaffleFilter.java | 4 +- src/prerna/web/conf/util/CACTrackingUtil.java | 4 +- src/prerna/web/conf/util/UserFileLogUtil.java | 4 +- .../web/services/util/InstanceStreamer.java | 8 +- .../services/util/ResponseHashSingleton.java | 4 +- .../util/SemossExecutorSingleton.java | 7 +- .../web/services/util/SemossThread.java | 6 +- .../services/util/TupleStreamingOutput.java | 4 +- src/prerna/web/services/util/WebUtility.java | 5 +- 46 files changed, 218 insertions(+), 161 deletions(-) diff --git a/pom.xml b/pom.xml index 9a54410a3..f121f6fb7 100644 --- a/pom.xml +++ b/pom.xml @@ -944,6 +944,34 @@ + + org.apache.logging.log4j + log4j-core + 2.13.2 + + + * + * + + + + + + org.apache.logging.log4j + log4j-web + 2.13.2 + + + * + * + + + + + org.apache.logging.log4j + log4j-slf4j-impl + 2.13.2 + com.datumbox lpsolve @@ -1257,7 +1285,20 @@ + + org.eclipse.rdf4j + rdf4j-bom + 3.4.0 + pom + + + * + * + + + + org.scala-lang diff --git a/src/prerna/cluster/RawSelectWrapperService.java b/src/prerna/cluster/RawSelectWrapperService.java index 9465ec36b..5bcc719a0 100644 --- a/src/prerna/cluster/RawSelectWrapperService.java +++ b/src/prerna/cluster/RawSelectWrapperService.java @@ -11,8 +11,8 @@ import javax.ws.rs.core.Context; import javax.ws.rs.core.Response; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import prerna.algorithm.api.SemossDataType; import prerna.engine.api.IEngine; diff --git a/src/prerna/semoss/web/form/FormResource.java b/src/prerna/semoss/web/form/FormResource.java index 9d40031b8..94f3d8cff 100644 --- a/src/prerna/semoss/web/form/FormResource.java +++ b/src/prerna/semoss/web/form/FormResource.java @@ -16,7 +16,8 @@ import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import prerna.auth.AuthProvider; import prerna.auth.User; @@ -36,7 +37,7 @@ @Path("/form") public class FormResource { - private static final Logger logger = Logger.getLogger(FormResource.class); + private static final Logger logger = LogManager.getLogger(FormResource.class); private IEngine formEngine; diff --git a/src/prerna/semoss/web/services/config/ServerConfigurationResource.java b/src/prerna/semoss/web/services/config/ServerConfigurationResource.java index 651a313a7..766e991bf 100644 --- a/src/prerna/semoss/web/services/config/ServerConfigurationResource.java +++ b/src/prerna/semoss/web/services/config/ServerConfigurationResource.java @@ -16,8 +16,8 @@ import javax.ws.rs.core.NewCookie; import javax.ws.rs.core.Response; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import prerna.auth.User; import prerna.auth.utils.AbstractSecurityUtils; diff --git a/src/prerna/semoss/web/services/local/AppResource.java b/src/prerna/semoss/web/services/local/AppResource.java index d7ba60746..a0f02806e 100644 --- a/src/prerna/semoss/web/services/local/AppResource.java +++ b/src/prerna/semoss/web/services/local/AppResource.java @@ -29,7 +29,8 @@ import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.io.filefilter.WildcardFileFilter; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import prerna.auth.User; import prerna.auth.utils.AbstractSecurityUtils; @@ -53,7 +54,7 @@ public class AppResource { private static String defaultEmbedLogo = null; private static boolean noLogo = false; - private static final Logger logger = Logger.getLogger(AppResource.class); + private static final Logger logger = LogManager.getLogger(AppResource.class); private static final String STACKTRACE = "StackTrace: "; private boolean canAccessApp(User user, String appId) throws IllegalAccessException { diff --git a/src/prerna/semoss/web/services/local/AuthorizationResource.java b/src/prerna/semoss/web/services/local/AuthorizationResource.java index a5a9c4df7..7818fc20b 100644 --- a/src/prerna/semoss/web/services/local/AuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/AuthorizationResource.java @@ -44,7 +44,8 @@ import javax.ws.rs.core.Response; import javax.ws.rs.core.StreamingOutput; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import com.google.gson.Gson; @@ -59,7 +60,7 @@ @Path("/authorization") public class AuthorizationResource { - private static final Logger logger = Logger.getLogger(AuthorizationResource.class); + private static final Logger logger = LogManager.getLogger(AuthorizationResource.class); private static final String STACKTRACE = "StackTrace: "; @Context protected ServletContext context; diff --git a/src/prerna/semoss/web/services/local/DataframeResource.java b/src/prerna/semoss/web/services/local/DataframeResource.java index 699d7a326..eb548a408 100644 --- a/src/prerna/semoss/web/services/local/DataframeResource.java +++ b/src/prerna/semoss/web/services/local/DataframeResource.java @@ -14,8 +14,8 @@ import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; diff --git a/src/prerna/semoss/web/services/local/EngineResource.java b/src/prerna/semoss/web/services/local/EngineResource.java index 4df5e5064..f50b632c6 100644 --- a/src/prerna/semoss/web/services/local/EngineResource.java +++ b/src/prerna/semoss/web/services/local/EngineResource.java @@ -44,7 +44,8 @@ import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; @@ -74,7 +75,7 @@ public class EngineResource { - private static final Logger logger = Logger.getLogger(EngineResource.class); + private static final Logger logger = LogManager.getLogger(EngineResource.class); private static final String STACKTRACE = "StackTrace: "; // gets everything specific to an engine diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index ed1c7e5a3..40e74e921 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -67,8 +67,8 @@ import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.jsoup.Jsoup; import com.google.gson.Gson; diff --git a/src/prerna/semoss/web/services/local/RunInsight.java b/src/prerna/semoss/web/services/local/RunInsight.java index b039f28a8..30f3f30b0 100644 --- a/src/prerna/semoss/web/services/local/RunInsight.java +++ b/src/prerna/semoss/web/services/local/RunInsight.java @@ -16,8 +16,8 @@ import javax.ws.rs.core.Context; import javax.ws.rs.core.Response; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import com.google.gson.stream.JsonWriter; diff --git a/src/prerna/semoss/web/services/local/SessionResource.java b/src/prerna/semoss/web/services/local/SessionResource.java index 3a03bc4e9..728d27447 100644 --- a/src/prerna/semoss/web/services/local/SessionResource.java +++ b/src/prerna/semoss/web/services/local/SessionResource.java @@ -17,8 +17,8 @@ import javax.ws.rs.core.Context; import javax.ws.rs.core.Response; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.owasp.encoder.Encode; import prerna.auth.User; diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index 456e88c4f..1625b71f9 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -66,8 +66,8 @@ import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.PropertiesConfiguration; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.kohsuke.github.GHMyself; import org.kohsuke.github.GitHub; import org.owasp.encoder.Encode; diff --git a/src/prerna/semoss/web/services/local/auth/AdminAppAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/AdminAppAuthorizationResource.java index 350d35fb8..65d6dc70b 100644 --- a/src/prerna/semoss/web/services/local/auth/AdminAppAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/AdminAppAuthorizationResource.java @@ -14,7 +14,8 @@ import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import prerna.auth.User; import prerna.auth.utils.SecurityAdminUtils; @@ -25,7 +26,7 @@ @Path("/auth/admin/app") public class AdminAppAuthorizationResource extends AbstractAdminResource { - private static final Logger logger = Logger.getLogger(AdminAppAuthorizationResource.class); + private static final Logger logger = LogManager.getLogger(AdminAppAuthorizationResource.class); @Context protected ServletContext context; diff --git a/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java index 35fc93b3d..c105a70b9 100644 --- a/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java @@ -14,7 +14,8 @@ import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import com.google.gson.Gson; @@ -31,7 +32,7 @@ @Path("/auth/admin/insight") public class AdminInsightAuthorizationResource extends AbstractAdminResource { - private static final Logger logger = Logger.getLogger(AdminInsightAuthorizationResource.class); + private static final Logger logger = LogManager.getLogger(AdminInsightAuthorizationResource.class); /** * Get the user insight permissions for a given insight diff --git a/src/prerna/semoss/web/services/local/auth/AdminUserAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/AdminUserAuthorizationResource.java index 40cd75249..b79b7fc22 100644 --- a/src/prerna/semoss/web/services/local/auth/AdminUserAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/AdminUserAuthorizationResource.java @@ -12,7 +12,8 @@ import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import prerna.auth.User; import prerna.auth.utils.AbstractSecurityUtils; @@ -25,7 +26,7 @@ @Path("/auth/user") public class AdminUserAuthorizationResource extends AbstractAdminResource { - private static final Logger logger = Logger.getLogger(AdminUserAuthorizationResource.class); + private static final Logger logger = LogManager.getLogger(AdminUserAuthorizationResource.class); @POST @Produces("application/json") diff --git a/src/prerna/semoss/web/services/local/auth/AppAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/AppAuthorizationResource.java index 2607329c1..f2c87977f 100644 --- a/src/prerna/semoss/web/services/local/auth/AppAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/AppAuthorizationResource.java @@ -15,7 +15,8 @@ import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import prerna.auth.User; import prerna.auth.utils.SecurityAppUtils; @@ -28,7 +29,7 @@ @Path("/auth/app") public class AppAuthorizationResource { - private static final Logger logger = Logger.getLogger(AppAuthorizationResource.class); + private static final Logger logger = LogManager.getLogger(AppAuthorizationResource.class); private static final String STACKTRACE = "StackTrace: "; @Context diff --git a/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java index b28b057d8..42a843beb 100644 --- a/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java @@ -14,7 +14,8 @@ import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import prerna.auth.AccessPermission; import prerna.auth.User; @@ -31,7 +32,7 @@ @Path("/auth/insight") public class InsightAuthorizationResource { - private static final Logger logger = Logger.getLogger(InsightAuthorizationResource.class); + private static final Logger logger = LogManager.getLogger(InsightAuthorizationResource.class); /** * Get the user insight permissions for a given insight diff --git a/src/prerna/semoss/web/services/remote/CentralNameServer.java b/src/prerna/semoss/web/services/remote/CentralNameServer.java index 76628f94b..fb7304af5 100644 --- a/src/prerna/semoss/web/services/remote/CentralNameServer.java +++ b/src/prerna/semoss/web/services/remote/CentralNameServer.java @@ -27,36 +27,23 @@ *******************************************************************************/ package prerna.semoss.web.services.remote; -import java.util.ArrayList; import java.util.Arrays; -import java.util.Hashtable; import java.util.List; import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.POST; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; import javax.ws.rs.core.Context; -import javax.ws.rs.core.MultivaluedMap; -import javax.ws.rs.core.StreamingOutput; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; -import com.google.gson.Gson; - -import prerna.semoss.web.services.local.NameServer; -import prerna.semoss.web.services.remote.CentralNameServer; import prerna.util.Constants; -import prerna.util.Utility; -import prerna.web.services.util.WebUtility; public class CentralNameServer { @Context private ServletContext context; - private static final Logger logger = Logger.getLogger(CentralNameServer.class.getName()); + private static final Logger logger = LogManager.getLogger(CentralNameServer.class.getName()); private String centralApi = ""; private List localDb = Arrays.asList(Constants.LOCAL_MASTER_DB_NAME); diff --git a/src/prerna/semoss/web/services/remote/EngineRemoteResource.java b/src/prerna/semoss/web/services/remote/EngineRemoteResource.java index 495bf89c7..9239dfa8a 100644 --- a/src/prerna/semoss/web/services/remote/EngineRemoteResource.java +++ b/src/prerna/semoss/web/services/remote/EngineRemoteResource.java @@ -39,8 +39,8 @@ import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.StreamingOutput; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import prerna.engine.api.IConstructWrapper; import prerna.engine.api.IEngine; diff --git a/src/prerna/upload/FileUploadProgressListener.java b/src/prerna/upload/FileUploadProgressListener.java index 0c2f4c8b7..356979625 100644 --- a/src/prerna/upload/FileUploadProgressListener.java +++ b/src/prerna/upload/FileUploadProgressListener.java @@ -3,8 +3,8 @@ import java.text.DecimalFormat; import org.apache.commons.fileupload.ProgressListener; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import prerna.sablecc2.comm.InMemoryConsole; diff --git a/src/prerna/upload/FileUploader.java b/src/prerna/upload/FileUploader.java index a972231a5..65b6cb3cd 100644 --- a/src/prerna/upload/FileUploader.java +++ b/src/prerna/upload/FileUploader.java @@ -20,8 +20,8 @@ import org.apache.commons.fileupload.FileItem; import org.apache.commons.io.FilenameUtils; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; diff --git a/src/prerna/upload/ImageUploader.java b/src/prerna/upload/ImageUploader.java index 89f557e54..a032c7740 100644 --- a/src/prerna/upload/ImageUploader.java +++ b/src/prerna/upload/ImageUploader.java @@ -21,8 +21,8 @@ import org.apache.commons.fileupload.FileItem; import org.apache.commons.io.filefilter.WildcardFileFilter; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import prerna.auth.User; import prerna.auth.utils.AbstractSecurityUtils; diff --git a/src/prerna/upload/Uploader.java b/src/prerna/upload/Uploader.java index 0ad9813b7..c08687106 100644 --- a/src/prerna/upload/Uploader.java +++ b/src/prerna/upload/Uploader.java @@ -40,8 +40,8 @@ import org.apache.commons.fileupload.ProgressListener; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import prerna.cache.ICache; import prerna.om.InsightStore; diff --git a/src/prerna/web/conf/AdminStartupFilter.java b/src/prerna/web/conf/AdminStartupFilter.java index 8e32095d5..a1edfd921 100644 --- a/src/prerna/web/conf/AdminStartupFilter.java +++ b/src/prerna/web/conf/AdminStartupFilter.java @@ -10,8 +10,8 @@ import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletResponse; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.owasp.encoder.Encode; import prerna.auth.utils.AbstractSecurityUtils; diff --git a/src/prerna/web/conf/AnonymousUserFilter.java b/src/prerna/web/conf/AnonymousUserFilter.java index 413bc3f51..5191f3567 100644 --- a/src/prerna/web/conf/AnonymousUserFilter.java +++ b/src/prerna/web/conf/AnonymousUserFilter.java @@ -15,8 +15,8 @@ import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import prerna.auth.User; import prerna.auth.utils.AbstractSecurityUtils; diff --git a/src/prerna/web/conf/CACFilter.java b/src/prerna/web/conf/CACFilter.java index a38e814cc..f3b86b71f 100644 --- a/src/prerna/web/conf/CACFilter.java +++ b/src/prerna/web/conf/CACFilter.java @@ -23,8 +23,8 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import prerna.auth.AccessToken; import prerna.auth.AuthProvider; diff --git a/src/prerna/web/conf/DBLoader.java b/src/prerna/web/conf/DBLoader.java index f3d6f14b2..08f21c37c 100644 --- a/src/prerna/web/conf/DBLoader.java +++ b/src/prerna/web/conf/DBLoader.java @@ -27,9 +27,13 @@ *******************************************************************************/ package prerna.web.conf; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.StringTokenizer; import java.util.Vector; import javax.servlet.ServletContext; @@ -37,11 +41,12 @@ import javax.servlet.ServletContextListener; import javax.servlet.SessionCookieConfig; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; -import org.apache.log4j.PropertyConfigurator; - -import com.ibm.icu.util.StringTokenizer; +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.core.LoggerContext; +import org.apache.logging.log4j.core.config.ConfigurationSource; +import org.apache.logging.log4j.core.config.Configurator; import prerna.engine.api.IEngine; import prerna.engine.impl.r.RserveUtil; @@ -64,6 +69,9 @@ public class DBLoader implements ServletContextListener { + private final Level STARTUP = Level.forName("STARTUP", 0); + private final Level SHUTDOWN = Level.forName("SHUTDOWN", 0); + private static final Logger logger = LogManager.getLogger(DBLoader.class); private static final String RDFMAP = "RDF-MAP"; private static String SESSION_ID_KEY = "JSESSIONID"; @@ -135,27 +143,45 @@ public void contextInitialized(ServletContextEvent arg0) { } } - logger.info("Initializing application context..." + Utility.cleanLogString(contextPath)); + logger.log(STARTUP, "Initializing application context..." + Utility.cleanLogString(contextPath)); // Set default file separator system variable - logger.info("Changing file separator value to: '/'"); + logger.log(STARTUP, "Changing file separator value to: '/'"); System.setProperty("file.separator", "/"); // Load RDF_Map.prop file - logger.info("Loading RDF_Map.prop: " + Utility.cleanLogString(rdfPropFile)); + logger.log(STARTUP, "Loading RDF_Map.prop: " + Utility.cleanLogString(rdfPropFile)); DIHelper.getInstance().loadCoreProp(rdfPropFile); // Set log4j prop String log4jConfig = DIHelper.getInstance().getProperty("LOG4J"); - logger.info("Setting log4j property: " + log4jConfig); - PropertyConfigurator.configure(log4jConfig); + logger.log(STARTUP, "Setting log4j property: " + log4jConfig); + FileInputStream fis = null; + ConfigurationSource source = null; + try { + File log4j2File = new File(log4jConfig); + System.setProperty("log4j2.configurationFile", log4j2File.toURI().toString()); + fis = new FileInputStream(log4jConfig); + source = new ConfigurationSource(fis); + Configurator.initialize(null, source); + } catch (IOException e1) { + e1.printStackTrace(); + } finally { + if(fis != null) { + try { + fis.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } if(RserveUtil.R_KILL_ON_STARTUP) { - logger.info("Killing existing RServes running on the machine"); + logger.log(STARTUP, "Killing existing RServes running on the machine"); try { RserveUtil.endR(); } catch (Exception e) { - logger.info("Unable to kill existing RServes running on the machine"); + logger.log(STARTUP, "Unable to kill existing RServes running on the machine"); } } @@ -171,7 +197,7 @@ public void contextInitialized(ServletContextEvent arg0) { DIHelper.getInstance().setLocalProperty(Constants.SESSION_ID_KEY, SESSION_ID_KEY); // Load empty engine list into DIHelper, then load engines from db folder - logger.info("Loading engines..."); + logger.log(STARTUP, "Loading engines..."); String engines = ""; DIHelper.getInstance().setLocalProperty(Constants.ENGINES, engines); loadEngines(); @@ -232,18 +258,18 @@ public void loadEngines() { } } } catch (Exception ex) { - logger.error(STACKTRACE, ex); + logger.log(STARTUP, STACKTRACE, ex); } } @Override public void contextDestroyed(ServletContextEvent arg0) { - logger.info("Start shutdown"); + logger.log(SHUTDOWN, "Start shutdown"); Set insights = new HashSet<>(InsightStore.getInstance().getAllInsights()); for (String id : insights) { Insight in = InsightStore.getInstance().get(id); - logger.info("Closing insight " + id); + logger.log(SHUTDOWN, "Closing insight " + id); InsightUtility.dropInsight(in); } @@ -259,7 +285,7 @@ public void contextDestroyed(ServletContextEvent arg0) { IEngine engine = (IEngine) DIHelper.getInstance().getLocalProp(id); if (engine != null) { // if it is loaded, close it - logger.info("Closing database " + id); + logger.log(SHUTDOWN, "Closing database " + id); engine.closeDB(); } } @@ -268,29 +294,29 @@ public void contextDestroyed(ServletContextEvent arg0) { // so specifically pull them to close IEngine engine = Utility.getEngine(AbstractFormBuilder.FORM_BUILDER_ENGINE_NAME); if (engine != null) { - logger.info("Closing database " + AbstractFormBuilder.FORM_BUILDER_ENGINE_NAME); + logger.log(SHUTDOWN, "Closing database " + AbstractFormBuilder.FORM_BUILDER_ENGINE_NAME); engine.closeDB(); } else { - logger.info("Couldn't find database " + AbstractFormBuilder.FORM_BUILDER_ENGINE_NAME); + logger.log(SHUTDOWN, "Couldn't find database " + AbstractFormBuilder.FORM_BUILDER_ENGINE_NAME); } engine = Utility.getEngine(Constants.SECURITY_DB); if (engine != null) { - logger.info("Closing database " + Constants.SECURITY_DB); + logger.log(SHUTDOWN, "Closing database " + Constants.SECURITY_DB); engine.closeDB(); } else { - logger.info("Couldn't find database " + Constants.SECURITY_DB); + logger.log(SHUTDOWN, "Couldn't find database " + Constants.SECURITY_DB); } engine = Utility.getEngine(Constants.LOCAL_MASTER_DB_NAME); if (engine != null) { - logger.info("Closing database " + Constants.LOCAL_MASTER_DB_NAME); + logger.log(SHUTDOWN, "Closing database " + Constants.LOCAL_MASTER_DB_NAME); engine.closeDB(); } else { - logger.info("Couldn't find database " + Constants.LOCAL_MASTER_DB_NAME); + logger.log(SHUTDOWN, "Couldn't find database " + Constants.LOCAL_MASTER_DB_NAME); } - logger.info("Closing scheduler"); + logger.log(SHUTDOWN, "Closing scheduler"); SchedulerFactorySingleton.getInstance().shutdownScheduler(true); // close r @@ -298,10 +324,10 @@ public void contextDestroyed(ServletContextEvent arg0) { RJavaTranslatorFactory.stopRConnection(); PyTranslatorFactory.stopPy(); } catch (Exception e) { - logger.error(STACKTRACE, e); + logger.log(SHUTDOWN, STACKTRACE, e); } - logger.info("Finished shutdown"); + logger.log(SHUTDOWN, "Finished shutdown"); } /** diff --git a/src/prerna/web/conf/IASFilter.java b/src/prerna/web/conf/IASFilter.java index 80f0e811f..3109a7eef 100644 --- a/src/prerna/web/conf/IASFilter.java +++ b/src/prerna/web/conf/IASFilter.java @@ -11,8 +11,8 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import prerna.auth.AccessToken; import prerna.auth.AuthProvider; diff --git a/src/prerna/web/conf/NoUserExistsFilter.java b/src/prerna/web/conf/NoUserExistsFilter.java index 7685dd3a2..2b752151c 100644 --- a/src/prerna/web/conf/NoUserExistsFilter.java +++ b/src/prerna/web/conf/NoUserExistsFilter.java @@ -11,8 +11,8 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import prerna.auth.utils.AbstractSecurityUtils; import prerna.engine.api.IEngine; diff --git a/src/prerna/web/conf/NoUserInSessionFilter.java b/src/prerna/web/conf/NoUserInSessionFilter.java index 4d129045b..0cc92d2a2 100644 --- a/src/prerna/web/conf/NoUserInSessionFilter.java +++ b/src/prerna/web/conf/NoUserInSessionFilter.java @@ -22,8 +22,8 @@ import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.owasp.encoder.Encode; import prerna.auth.AuthProvider; diff --git a/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java b/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java index ab6c49c3a..008507a14 100644 --- a/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java +++ b/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java @@ -18,8 +18,8 @@ import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import prerna.auth.AccessToken; import prerna.auth.AuthProvider; diff --git a/src/prerna/web/conf/PIVFilter.java b/src/prerna/web/conf/PIVFilter.java index 057f89e2f..351542dbc 100644 --- a/src/prerna/web/conf/PIVFilter.java +++ b/src/prerna/web/conf/PIVFilter.java @@ -20,8 +20,8 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import prerna.auth.AccessToken; import prerna.auth.AuthProvider; @@ -86,38 +86,38 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 try { ldapDN = new LdapName(fullName); for(Rdn rdn: ldapDN.getRdns()) { - // only care about UID - if(!rdn.getType().equals("UID")) { - // try next rdn - continue; - } - // get the full value - // this should be an email - email = rdn.getValue().toString(); - // make sure valid email - if(email == null || !email.contains("@")) { - try { - EMAIL_LOOP : for(List altNames : cert.getSubjectAlternativeNames()) { - for(Object alternative : altNames) { - if(alternative instanceof String) { - String altStr = alternative.toString(); - // really simple email check... - if(altStr.contains("@")) { - email = altStr; - break EMAIL_LOOP; + // UID for email + if(rdn.getType().equals("UID")) { + // get the full value + // this should be an email + email = rdn.getValue().toString(); + // make sure valid email + if(email == null || !email.contains("@")) { + try { + EMAIL_LOOP : for(List altNames : cert.getSubjectAlternativeNames()) { + for(Object alternative : altNames) { + if(alternative instanceof String) { + String altStr = alternative.toString(); + // really simple email check... + if(altStr.contains("@")) { + email = altStr; + break EMAIL_LOOP; + } } } } + } catch (CertificateParsingException e) { + logger.error(STACKTRACE, e); } - } catch (CertificateParsingException e) { - logger.error(STACKTRACE, e); } + // CN for name + } else if(rdn.getType().equals("CN")) { + name = rdn.getValue().toString(); } - name = email; - + // lets make sure we have all the stuff - if(email != null && email.contains("@")) { + if(email != null && email.contains("@") && name != null) { // we have everything! // this is the only time we populate the token // and then exit the cert loop diff --git a/src/prerna/web/conf/SchedulerFilter.java b/src/prerna/web/conf/SchedulerFilter.java index c8c5ddcb9..560445e0b 100644 --- a/src/prerna/web/conf/SchedulerFilter.java +++ b/src/prerna/web/conf/SchedulerFilter.java @@ -11,8 +11,8 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import prerna.auth.AccessToken; import prerna.auth.AuthProvider; diff --git a/src/prerna/web/conf/SetAdminSessionTimeoutFilter.java b/src/prerna/web/conf/SetAdminSessionTimeoutFilter.java index 3906c065e..d37ac9600 100644 --- a/src/prerna/web/conf/SetAdminSessionTimeoutFilter.java +++ b/src/prerna/web/conf/SetAdminSessionTimeoutFilter.java @@ -11,8 +11,8 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import prerna.auth.User; import prerna.auth.utils.AbstractSecurityUtils; diff --git a/src/prerna/web/conf/UserDBLoader.java b/src/prerna/web/conf/UserDBLoader.java index 33234185d..4029bf2fc 100644 --- a/src/prerna/web/conf/UserDBLoader.java +++ b/src/prerna/web/conf/UserDBLoader.java @@ -32,8 +32,8 @@ import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import prerna.cluster.util.ZKClient; diff --git a/src/prerna/web/conf/UserExistsFilter.java b/src/prerna/web/conf/UserExistsFilter.java index 7674a37d0..c1cc52104 100644 --- a/src/prerna/web/conf/UserExistsFilter.java +++ b/src/prerna/web/conf/UserExistsFilter.java @@ -11,8 +11,8 @@ import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.owasp.encoder.Encode; import prerna.auth.User; diff --git a/src/prerna/web/conf/UserSessionLoader.java b/src/prerna/web/conf/UserSessionLoader.java index f144abc41..3d9bc6e5e 100644 --- a/src/prerna/web/conf/UserSessionLoader.java +++ b/src/prerna/web/conf/UserSessionLoader.java @@ -8,8 +8,8 @@ import javax.servlet.http.HttpSessionEvent; import javax.servlet.http.HttpSessionListener; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import prerna.auth.SyncUserAppsThread; import prerna.auth.User; diff --git a/src/prerna/web/conf/WaffleFilter.java b/src/prerna/web/conf/WaffleFilter.java index ca9bfadb5..03cbf432d 100644 --- a/src/prerna/web/conf/WaffleFilter.java +++ b/src/prerna/web/conf/WaffleFilter.java @@ -15,8 +15,8 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import prerna.auth.AccessToken; import prerna.auth.AuthProvider; diff --git a/src/prerna/web/conf/util/CACTrackingUtil.java b/src/prerna/web/conf/util/CACTrackingUtil.java index 2444e317d..c919535c5 100644 --- a/src/prerna/web/conf/util/CACTrackingUtil.java +++ b/src/prerna/web/conf/util/CACTrackingUtil.java @@ -6,8 +6,8 @@ import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import prerna.engine.api.IEngine; import prerna.engine.api.IRawSelectWrapper; diff --git a/src/prerna/web/conf/util/UserFileLogUtil.java b/src/prerna/web/conf/util/UserFileLogUtil.java index 022d4aa1e..665095f98 100644 --- a/src/prerna/web/conf/util/UserFileLogUtil.java +++ b/src/prerna/web/conf/util/UserFileLogUtil.java @@ -8,8 +8,8 @@ import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import prerna.util.Utility; diff --git a/src/prerna/web/services/util/InstanceStreamer.java b/src/prerna/web/services/util/InstanceStreamer.java index f90f83838..2779b05ab 100644 --- a/src/prerna/web/services/util/InstanceStreamer.java +++ b/src/prerna/web/services/util/InstanceStreamer.java @@ -13,10 +13,7 @@ */ package prerna.web.services.util; -import static org.junit.Assert.assertTrue; - import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.LinkedHashSet; @@ -24,9 +21,8 @@ import java.util.Locale; import java.util.Set; -import org.apache.commons.lang3.RandomStringUtils; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; public class InstanceStreamer { diff --git a/src/prerna/web/services/util/ResponseHashSingleton.java b/src/prerna/web/services/util/ResponseHashSingleton.java index 5a9277392..469880ff4 100644 --- a/src/prerna/web/services/util/ResponseHashSingleton.java +++ b/src/prerna/web/services/util/ResponseHashSingleton.java @@ -4,8 +4,8 @@ import javax.ws.rs.container.AsyncResponse; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import prerna.util.Utility; diff --git a/src/prerna/web/services/util/SemossExecutorSingleton.java b/src/prerna/web/services/util/SemossExecutorSingleton.java index 6c839fc7b..ebce9f2b5 100644 --- a/src/prerna/web/services/util/SemossExecutorSingleton.java +++ b/src/prerna/web/services/util/SemossExecutorSingleton.java @@ -3,13 +3,12 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import org.apache.log4j.Logger; - -import prerna.web.services.util.SemossThread; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; public class SemossExecutorSingleton { - private static final Logger logger = Logger.getLogger(SemossExecutorSingleton.class); + private static final Logger logger = LogManager.getLogger(SemossExecutorSingleton.class); static SemossExecutorSingleton singleton = null; ExecutorService service = null; diff --git a/src/prerna/web/services/util/SemossThread.java b/src/prerna/web/services/util/SemossThread.java index 88f75ec80..003c764ad 100644 --- a/src/prerna/web/services/util/SemossThread.java +++ b/src/prerna/web/services/util/SemossThread.java @@ -1,9 +1,7 @@ package prerna.web.services.util; -import javax.ws.rs.container.AsyncResponse; - -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; public class SemossThread extends Thread { diff --git a/src/prerna/web/services/util/TupleStreamingOutput.java b/src/prerna/web/services/util/TupleStreamingOutput.java index 585f499e8..368c8b591 100644 --- a/src/prerna/web/services/util/TupleStreamingOutput.java +++ b/src/prerna/web/services/util/TupleStreamingOutput.java @@ -34,8 +34,8 @@ import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.StreamingOutput; -import org.apache.log4j.LogManager; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.openrdf.query.QueryEvaluationException; import org.openrdf.query.TupleQueryResult; diff --git a/src/prerna/web/services/util/WebUtility.java b/src/prerna/web/services/util/WebUtility.java index c05e6a7d5..52aafab3d 100644 --- a/src/prerna/web/services/util/WebUtility.java +++ b/src/prerna/web/services/util/WebUtility.java @@ -44,7 +44,8 @@ import javax.ws.rs.core.StreamingOutput; import org.apache.commons.lang.time.FastDateFormat; -import org.apache.log4j.Logger; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import com.google.gson.Gson; @@ -57,7 +58,7 @@ public class WebUtility { private static final String CLASS_NAME = WebUtility.class.getName(); - private static final Logger LOGGER = Logger.getLogger(CLASS_NAME); + private static final Logger LOGGER = LogManager.getLogger(CLASS_NAME); private static final FastDateFormat expiresDateFormat= FastDateFormat.getInstance("EEE, dd MMM yyyy HH:mm:ss zzz", TimeZone.getTimeZone("GMT")); From aa440aebb490b45d49811a03366daeed38e41ef3 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Sun, 13 Sep 2020 15:00:45 +0000 Subject: [PATCH 0660/1906] REQUIREMENT ::: Update in web.xml to new log4j2.properties location UPDATE ::: Removing old log4j.prop file and reference in RDF_Map.prop since webapps require definition in web.xml. Note - must define as a URL in web.xml - file:///{{FILE PATH}} git-svn-id: svn://107.170.10.188:8080/Monolith/dev@40107 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: aed95bd4933165931e5612be2345b2260a51b2d7 --- WebContent/WEB-INF/web.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index ed56679a7..7a89323ed 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -315,6 +315,10 @@ isLog4jAutoInitializationDisabled false + + log4jConfiguration + file:///C:/workspace/Semoss_Dev/log4j2.properties + security-enabled true From b1ca8c4cacfc152eeb33978da907c96e834ca769 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Sun, 13 Sep 2020 15:02:37 +0000 Subject: [PATCH 0661/1906] UPDATE ::: Removing log4j definition as web.xml now autoloads the configuration git-svn-id: svn://107.170.10.188:8080/Monolith/dev@40108 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 24e146218a7a32ac0e3243de1f2022206391e4c3 --- src/prerna/web/conf/DBLoader.java | 29 ----------------------------- 1 file changed, 29 deletions(-) diff --git a/src/prerna/web/conf/DBLoader.java b/src/prerna/web/conf/DBLoader.java index 08f21c37c..8558c17db 100644 --- a/src/prerna/web/conf/DBLoader.java +++ b/src/prerna/web/conf/DBLoader.java @@ -27,9 +27,6 @@ *******************************************************************************/ package prerna.web.conf; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -44,9 +41,6 @@ import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.core.LoggerContext; -import org.apache.logging.log4j.core.config.ConfigurationSource; -import org.apache.logging.log4j.core.config.Configurator; import prerna.engine.api.IEngine; import prerna.engine.impl.r.RserveUtil; @@ -153,29 +147,6 @@ public void contextInitialized(ServletContextEvent arg0) { logger.log(STARTUP, "Loading RDF_Map.prop: " + Utility.cleanLogString(rdfPropFile)); DIHelper.getInstance().loadCoreProp(rdfPropFile); - // Set log4j prop - String log4jConfig = DIHelper.getInstance().getProperty("LOG4J"); - logger.log(STARTUP, "Setting log4j property: " + log4jConfig); - FileInputStream fis = null; - ConfigurationSource source = null; - try { - File log4j2File = new File(log4jConfig); - System.setProperty("log4j2.configurationFile", log4j2File.toURI().toString()); - fis = new FileInputStream(log4jConfig); - source = new ConfigurationSource(fis); - Configurator.initialize(null, source); - } catch (IOException e1) { - e1.printStackTrace(); - } finally { - if(fis != null) { - try { - fis.close(); - } catch (IOException e) { - e.printStackTrace(); - } - } - } - if(RserveUtil.R_KILL_ON_STARTUP) { logger.log(STARTUP, "Killing existing RServes running on the machine"); try { From 70aeaa3c70563f41879d9139d87974df49d7e489 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 14 Sep 2020 23:27:35 +0000 Subject: [PATCH 0662/1906] BUGFIX ::: Fixing selenium to use updated version of guava git-svn-id: svn://107.170.10.188:8080/Monolith/dev@40123 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: d34fcce6d73571bce8a033c5a47b91ad47bdbdd2 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index f121f6fb7..161914d74 100644 --- a/pom.xml +++ b/pom.xml @@ -642,7 +642,7 @@ com.google.guava guava - 21.0 + 25.0-jre * From 9f511fbd939291c58a3d0041d1f5b72a08e70101 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 17 Sep 2020 16:40:56 +0000 Subject: [PATCH 0663/1906] UPDATE ::: Minor change, replacing STACKTRACE to constants for standardization git-svn-id: svn://107.170.10.188:8080/Monolith/dev@40188 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: af3e11bc432a39fe9db7b51413d9942daa17abbd --- src/prerna/web/conf/DBLoader.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/prerna/web/conf/DBLoader.java b/src/prerna/web/conf/DBLoader.java index 8558c17db..7b156b793 100644 --- a/src/prerna/web/conf/DBLoader.java +++ b/src/prerna/web/conf/DBLoader.java @@ -69,7 +69,6 @@ public class DBLoader implements ServletContextListener { private static final Logger logger = LogManager.getLogger(DBLoader.class); private static final String RDFMAP = "RDF-MAP"; private static String SESSION_ID_KEY = "JSESSIONID"; - private static final String STACKTRACE = "StackTrace: "; private static boolean useLogoutPage = false; private static String customLogoutUrl = null; @@ -229,7 +228,7 @@ public void loadEngines() { } } } catch (Exception ex) { - logger.log(STARTUP, STACKTRACE, ex); + logger.log(STARTUP, Constants.STACKTRACE, ex); } } @@ -295,7 +294,7 @@ public void contextDestroyed(ServletContextEvent arg0) { RJavaTranslatorFactory.stopRConnection(); PyTranslatorFactory.stopPy(); } catch (Exception e) { - logger.log(SHUTDOWN, STACKTRACE, e); + logger.log(SHUTDOWN, Constants.STACKTRACE, e); } logger.log(SHUTDOWN, "Finished shutdown"); From ef63edb391d0509e819d336b15ffe4077659b71d Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 23 Sep 2020 10:45:03 +0000 Subject: [PATCH 0664/1906] UPDATE ::: Consolidating code in DBLoader for scheduler checks git-svn-id: svn://107.170.10.188:8080/Monolith/dev@40285 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 999d84fb1cba77024d1638171be68601f382165e --- src/prerna/web/conf/DBLoader.java | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/prerna/web/conf/DBLoader.java b/src/prerna/web/conf/DBLoader.java index 7b156b793..dc505c2cf 100644 --- a/src/prerna/web/conf/DBLoader.java +++ b/src/prerna/web/conf/DBLoader.java @@ -44,7 +44,6 @@ import prerna.engine.api.IEngine; import prerna.engine.impl.r.RserveUtil; -import prerna.engine.impl.rdbms.RDBMSNativeEngine; import prerna.forms.AbstractFormBuilder; import prerna.nameserver.utility.MasterDatabaseUtility; import prerna.om.Insight; @@ -192,18 +191,21 @@ public void contextInitialized(ServletContextEvent arg0) { IEngine scheduler = (IEngine) DIHelper.getInstance().getLocalProp(Constants.SCHEDULER_DB); // if (localmaster == null || security == null || scheduler == null || !localmaster.isConnected() || !security.isConnected() || !scheduler.isConnected()) { if (localmaster == null || security == null || !localmaster.isConnected() || !security.isConnected() ) { - // you have messed up!!! StartUpSuccessFilter.setStartUpSuccess(false); } - } + + // Load and run triggerOnLoad jobs + if(scheduler != null) { + try { + SchedulerH2DatabaseUtility.executeAllTriggerOnLoads(); + // also add legacy json files + JsonConversionToQuartzJob.runUpdateFromLegacyFormat(); + } catch(Exception e) { + // ignore + } + } - // Load and run triggerOnLoad jobs - RDBMSNativeEngine schedulerDb = (RDBMSNativeEngine) Utility.getEngine(Constants.SCHEDULER_DB); - if(schedulerDb != null) { - SchedulerH2DatabaseUtility.executeAllTriggerOnLoads(); - // also add legacy json files - JsonConversionToQuartzJob.runUpdateFromLegacyFormat(); } } From f6d98016a18655a496d021b4847e75686341539e Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 29 Sep 2020 23:32:09 +0000 Subject: [PATCH 0665/1906] UPDATE ::: Allow trusted token filter to have SameSite=None in the cookie definition for cross site embedding git-svn-id: svn://107.170.10.188:8080/Monolith/dev@40397 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 76ccca27445795257b53062091bc2b27ad417998 --- .../NoUserInSessionTrustedTokenFilter.java | 31 ++++++++++++++++--- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java b/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java index 008507a14..1f9a38175 100644 --- a/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java +++ b/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java @@ -108,16 +108,26 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 String sessionId = session.getId(); sessionMapper.put(userId, sessionId); + + // add the session id cookie + // use addHeader to allow for SameSite option + String setCookieString = DBLoader.getSessionIdKey() + "=" + sessionId + + "; Path=" + contextPath + + "; HttpOnly" + + (req.isSecure() ? "; Secure" : "") + + "; SameSite=None" + ; + ((HttpServletResponse) arg1).addHeader("Set-Cookie", setCookieString); } } else { // this is the class where you redirect String redirectSessionId = (String) sessionMapper.get(userId); // add the session id cookie - Cookie k = new Cookie(DBLoader.getSessionIdKey(), redirectSessionId); - k.setHttpOnly(true); - k.setSecure(req.isSecure()); - k.setPath(contextPath); - ((HttpServletResponse)arg1).addCookie(k); +// Cookie k = new Cookie(DBLoader.getSessionIdKey(), redirectSessionId); +// k.setHttpOnly(true); +// k.setSecure(req.isSecure()); +// k.setPath(contextPath); +// ((HttpServletResponse)arg1).addCookie(k); // replace any other session id cookies Cookie[] cookies = req.getCookies(); if (cookies != null) { @@ -131,12 +141,23 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 } } + // add the session id cookie + // use addHeader to allow for SameSite option + String setCookieString = DBLoader.getSessionIdKey() + "=" + redirectSessionId + + "; Path=" + contextPath + + "; HttpOnly" + + (req.isSecure() ? "; Secure" : "") + + "; SameSite=None" + ; + String method = req.getMethod(); if(method.equalsIgnoreCase("GET")) { + ((HttpServletResponse) arg1).addHeader("Set-Cookie", setCookieString); ((HttpServletResponse) arg1).setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY); ((HttpServletResponse) arg1).sendRedirect(fullUrl + "?" + req.getQueryString()); return; } else if(method.equalsIgnoreCase("POST")) { + ((HttpServletResponse) arg1).addHeader("Set-Cookie", setCookieString); ((HttpServletResponse) arg1).setStatus(HttpServletResponse.SC_TEMPORARY_REDIRECT); ((HttpServletResponse) arg1).setHeader("Location", fullUrl); return; From 1cea27a0ad250e886ca0fbb03d80320e40a2ba18 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 30 Sep 2020 01:09:31 +0000 Subject: [PATCH 0666/1906] BUGFIX ::: Only sending same-site when secure is there git-svn-id: svn://107.170.10.188:8080/Monolith/dev@40400 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 4c2c4a4b3daff77182119cbcc1ecb80176d490a3 --- .../web/conf/NoUserInSessionTrustedTokenFilter.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java b/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java index 1f9a38175..30afe6cce 100644 --- a/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java +++ b/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java @@ -26,6 +26,7 @@ import prerna.auth.User; import prerna.auth.utils.AbstractSecurityUtils; import prerna.auth.utils.SecurityQueryUtils; +import prerna.cluster.util.ClusterUtil; import prerna.util.Constants; import prerna.util.Utility; @@ -111,11 +112,11 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 // add the session id cookie // use addHeader to allow for SameSite option + // SameSite only works if Secure tag also there String setCookieString = DBLoader.getSessionIdKey() + "=" + sessionId + "; Path=" + contextPath + "; HttpOnly" - + (req.isSecure() ? "; Secure" : "") - + "; SameSite=None" + + (ClusterUtil.IS_CLUSTER || req.isSecure() ? "; Secure; SameSite=None" : "") ; ((HttpServletResponse) arg1).addHeader("Set-Cookie", setCookieString); } @@ -143,11 +144,11 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 // add the session id cookie // use addHeader to allow for SameSite option + // SameSite only works if Secure tag also there String setCookieString = DBLoader.getSessionIdKey() + "=" + redirectSessionId + "; Path=" + contextPath + "; HttpOnly" - + (req.isSecure() ? "; Secure" : "") - + "; SameSite=None" + + (ClusterUtil.IS_CLUSTER || req.isSecure() ? "; Secure; SameSite=None" : "") ; String method = req.getMethod(); From 91aa50f54574a7edf1acedc1730dfada33f12402 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 30 Sep 2020 01:14:08 +0000 Subject: [PATCH 0667/1906] UPDATE ::: Making the boolean condition more clear git-svn-id: svn://107.170.10.188:8080/Monolith/dev@40402 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: a2ceede13f1ba0015c4b399c3ccc91a28ed9df63 --- src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java b/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java index 30afe6cce..62af3cbbd 100644 --- a/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java +++ b/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java @@ -116,7 +116,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 String setCookieString = DBLoader.getSessionIdKey() + "=" + sessionId + "; Path=" + contextPath + "; HttpOnly" - + (ClusterUtil.IS_CLUSTER || req.isSecure() ? "; Secure; SameSite=None" : "") + + ( (ClusterUtil.IS_CLUSTER || req.isSecure()) ? "; Secure; SameSite=None" : "") ; ((HttpServletResponse) arg1).addHeader("Set-Cookie", setCookieString); } @@ -148,7 +148,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 String setCookieString = DBLoader.getSessionIdKey() + "=" + redirectSessionId + "; Path=" + contextPath + "; HttpOnly" - + (ClusterUtil.IS_CLUSTER || req.isSecure() ? "; Secure; SameSite=None" : "") + + ( (ClusterUtil.IS_CLUSTER || req.isSecure()) ? "; Secure; SameSite=None" : "") ; String method = req.getMethod(); From 0a37e20eb6272a72c2a3ba0bd50ba6f28a662153 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 1 Oct 2020 18:28:51 +0000 Subject: [PATCH 0668/1906] UPDATE ::: Adding new structure for filters + adding new pipeline routine to return back data with filters, etc. git-svn-id: svn://107.170.10.188:8080/Monolith/dev@40438 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: ac71e5eeade80a61eda7f10281440448049646f6 --- .../semoss/web/services/local/NameServer.java | 165 ++++++++++++------ 1 file changed, 115 insertions(+), 50 deletions(-) diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index 40e74e921..063235c23 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -79,18 +79,12 @@ import prerna.auth.utils.SecurityAppUtils; import prerna.auth.utils.SecurityInsightUtils; import prerna.auth.utils.SecurityQueryUtils; -import prerna.ds.py.FilePyTranslator; -import prerna.ds.py.PyExecutorThread; -import prerna.ds.py.PyTranslator; -import prerna.ds.py.PyUtils; -import prerna.ds.py.TCPPyTranslator; import prerna.engine.api.IEngine; import prerna.engine.impl.rdf.RemoteSemossSesameEngine; import prerna.nameserver.utility.MasterDatabaseUtility; import prerna.om.Insight; import prerna.om.InsightStore; import prerna.om.ThreadStore; -import prerna.pyserve.NettyClient; import prerna.sablecc.PKQLRunner; import prerna.sablecc2.PixelRunner; import prerna.sablecc2.PixelStreamUtility; @@ -385,7 +379,57 @@ public Response getPixelPipelinePlan(@Context HttpServletRequest request) { ThreadStore.setUser(user); return getInsightPipeline(insight, expression); + } + + + @POST + @Path("/getPipeline2") + @Produces("application/json;charset=utf-8") + public Response getPixelPipelinePlan2(@Context HttpServletRequest request) { + HttpSession session = null; + String sessionId = null; + User user = null; + boolean securityEnabled = AbstractSecurityUtils.securityEnabled(); + // If security is enabled try to get an existing session. + // Otherwise get a session with the default user. + if (securityEnabled) { + session = request.getSession(false); + if (session != null) { + sessionId = session.getId(); + user = ((User) session.getAttribute(Constants.SESSION_USER)); + } + + if (user == null) { + Map errorMap = new HashMap<>(); + errorMap.put("error", "User session is invalid"); + logger.debug("User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + } else { + session = request.getSession(true); + user = ((User) session.getAttribute(Constants.SESSION_USER)); + sessionId = session.getId(); + } + + String insightId = request.getParameter("insightId"); + String expression = request.getParameter("expression"); + Insight insight = InsightStore.getInstance().get(insightId); + if (insight == null) { + Map errorMap = new HashMap<>(); + errorMap.put(Constants.ERROR_MESSAGE, "Could not find the insight id"); + errorMap.put(ERROR_TYPE, INSIGHT_NOT_FOUND); + return WebUtility.getResponse(errorMap, 400); + } + + // set the user + insight.setUser(user); + // set in thread + ThreadStore.setInsightId(insightId); + ThreadStore.setSessionId(sessionId); + ThreadStore.setUser(user); + + return getInsightPipeline2(insight, expression); } @@ -426,53 +470,74 @@ private Response runPixelJob(User user, Insight insight, String expression, Stri .build(); } +// /** +// * +// * @param session +// * @param sessionId +// * @param user +// */ +// private void setPythonForSession(HttpSession session, String sessionId, User user) { +// PyTranslator pyt = null; +// String port = null; +// +// boolean useFilePy = Boolean.parseBoolean(DIHelper.getInstance().getProperty("USE_PY_FILE")); +// boolean useTCP = Boolean.parseBoolean(DIHelper.getInstance().getProperty("USE_TCP_PY")); +// useTCP = useFilePy; // forcing it to be same as TCP +// +// if (!useFilePy) { +// if (session.getAttribute(Constants.PYTHON) != null) { +// pyt = (PyTranslator) session.getAttribute(Constants.PYTHON); +// } +// +// PyExecutorThread jepThread = PyUtils.getInstance().getJep(); +// pyt = new PyTranslator(); +// pyt.setPy(jepThread); +// } +// // check to see if the py translator needs to be set ? +// else if (useFilePy && session.getAttribute("USER_TUPLE") == null) { +// if (useTCP) { +// port = DIHelper.getInstance().getProperty("FORCE_PORT"); // this means someone has started it +// if (port == null) { +// port = Utility.findOpenPort(); +// session.setAttribute("USER_TUPLE", PyUtils.getInstance().startPyServe(user, +// DIHelper.getInstance().getProperty(Constants.INSIGHT_CACHE_DIR), port)); +// NettyClient nc = new NettyClient(); +// nc.connect("127.0.0.1", Integer.parseInt(port), false); +// Thread t = new Thread(nc); +// t.start(); +// user.setPyServe(nc); +// pyt = new TCPPyTranslator(); +// ((TCPPyTranslator) pyt).nc = nc; +// } +// session.setAttribute("PORT", port); +// } else { +// String userTuple = PyUtils.getInstance().getTempTupleSpace(user, DIHelper.getInstance().getProperty(Constants.INSIGHT_CACHE_DIR)); +// session.setAttribute("USER_TUPLE", userTuple); +// pyt = new FilePyTranslator(); +// } +// } +// session.setAttribute(Constants.PYTHON, pyt); +// } + /** * - * @param session - * @param sessionId - * @param user + * @param insight + * @param expression + * @return */ - private void setPythonForSession(HttpSession session, String sessionId, User user) { - PyTranslator pyt = null; - String port = null; - - boolean useFilePy = Boolean.parseBoolean(DIHelper.getInstance().getProperty("USE_PY_FILE")); - boolean useTCP = Boolean.parseBoolean(DIHelper.getInstance().getProperty("USE_TCP_PY")); - useTCP = useFilePy; // forcing it to be same as TCP - - if (!useFilePy) { - if (session.getAttribute(Constants.PYTHON) != null) { - pyt = (PyTranslator) session.getAttribute(Constants.PYTHON); - } - - PyExecutorThread jepThread = PyUtils.getInstance().getJep(); - pyt = new PyTranslator(); - pyt.setPy(jepThread); - } - // check to see if the py translator needs to be set ? - else if (useFilePy && session.getAttribute("USER_TUPLE") == null) { - if (useTCP) { - port = DIHelper.getInstance().getProperty("FORCE_PORT"); // this means someone has started it - if (port == null) { - port = Utility.findOpenPort(); - session.setAttribute("USER_TUPLE", PyUtils.getInstance().startPyServe(user, - DIHelper.getInstance().getProperty(Constants.INSIGHT_CACHE_DIR), port)); - NettyClient nc = new NettyClient(); - nc.connect("127.0.0.1", Integer.parseInt(port), false); - Thread t = new Thread(nc); - t.start(); - user.setPyServe(nc); - pyt = new TCPPyTranslator(); - ((TCPPyTranslator) pyt).nc = nc; - } - session.setAttribute("PORT", port); - } else { - String userTuple = PyUtils.getInstance().getTempTupleSpace(user, DIHelper.getInstance().getProperty(Constants.INSIGHT_CACHE_DIR)); - session.setAttribute("USER_TUPLE", userTuple); - pyt = new FilePyTranslator(); + private Response getInsightPipeline(Insight insight, String expression) { + synchronized (insight) { + try { + return Response.status(200) + .entity(GsonUtility.getDefaultGson().toJson(PixelUtility.generatePipeline(insight, expression))) + .build(); + } catch (Exception e) { + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap<>(); + errorMap.put(Constants.ERROR_MESSAGE, e.getMessage()); + return WebUtility.getResponse(errorMap, 400); } } - session.setAttribute(Constants.PYTHON, pyt); } /** @@ -481,11 +546,11 @@ else if (useFilePy && session.getAttribute("USER_TUPLE") == null) { * @param expression * @return */ - private Response getInsightPipeline(Insight insight, String expression) { + private Response getInsightPipeline2(Insight insight, String expression) { synchronized (insight) { try { return Response.status(200) - .entity(GsonUtility.getDefaultGson().toJson(PixelUtility.generatePipeline(insight, expression))) + .entity(GsonUtility.getDefaultGson().toJson(PixelUtility.generatePipeline2(insight, expression))) .build(); } catch (Exception e) { logger.error(Constants.STACKTRACE, e); From 055f51f41137140614e8ccc20803d565734abe7a Mon Sep 17 00:00:00 2001 From: rramirezjimenez Date: Mon, 5 Oct 2020 18:37:40 +0000 Subject: [PATCH 0669/1906] UPDATE ::: Adding rest endpoints to see users that don't have access to an insight or app git-svn-id: svn://107.170.10.188:8080/Monolith/dev@40472 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 733a30013e2b24ddfee6b2be791ad6a86094186f --- .../auth/AdminAppAuthorizationResource.java | 39 +++++++++++++++++++ .../local/auth/AppAuthorizationResource.java | 36 +++++++++++++++++ .../auth/InsightAuthorizationResource.java | 36 ++++++++++++++++- 3 files changed, 110 insertions(+), 1 deletion(-) diff --git a/src/prerna/semoss/web/services/local/auth/AdminAppAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/AdminAppAuthorizationResource.java index 65d6dc70b..26c31b330 100644 --- a/src/prerna/semoss/web/services/local/auth/AdminAppAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/AdminAppAuthorizationResource.java @@ -1,6 +1,7 @@ package prerna.semoss.web.services.local.auth; import java.util.HashMap; +import java.util.List; import java.util.Map; import javax.servlet.ServletContext; @@ -275,4 +276,42 @@ public Response setAppGlobal(@Context HttpServletRequest request, MultivaluedMap ret.put("success", true); return WebUtility.getResponse(ret, 200); } + + /** + * Get users with no access to a given app + * @param request + * @param form + * @return + */ + @GET + @Produces("application/json") + @Path("getAppUsersNoCredentials") + public Response getAppUsersNoCredentials(@Context HttpServletRequest request, @QueryParam("appId") String appId) { + SecurityAdminUtils adminUtils = null; + User user = null; + try { + user = ResourceUtility.getUser(request); + adminUtils = performAdminCheck(request, user); + } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), " is trying to get all users when not an admin")); + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + + List> ret = null; + try { + ret = adminUtils.getAppUsersNoCredentials(user, appId); + } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), " is trying to pull users for " + appId + " that do not have credentials without having proper access")); + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + + return WebUtility.getResponse(ret, 200); + } + } diff --git a/src/prerna/semoss/web/services/local/auth/AppAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/AppAuthorizationResource.java index f2c87977f..41c867af4 100644 --- a/src/prerna/semoss/web/services/local/auth/AppAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/AppAuthorizationResource.java @@ -364,4 +364,40 @@ public Response setAppVisibility(@Context HttpServletRequest request, Multivalue return WebUtility.getResponse(true, 200); } + + /** + * Get users with no access to a given app + * @param request + * @param form + * @return + */ + @GET + @Produces("application/json") + @Path("getAppUsersNoCredentials") + public Response getAppUsersNoCredentials(@Context HttpServletRequest request, @QueryParam("appId") String appId) { + User user = null; + try { + user = ResourceUtility.getUser(request); + } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), " invalid user session trying to access authorization resources")); + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + + List> ret = null; + try { + ret = SecurityAppUtils.getAppUsersNoCredentials(user, appId); + } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), " is trying to pull users for " + appId + " that do not have credentials without having proper access")); + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + + return WebUtility.getResponse(ret, 200); + } + } diff --git a/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java index 42a843beb..3fba8afcf 100644 --- a/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java @@ -319,5 +319,39 @@ public Response setInsightGlobal(@Context HttpServletRequest request, Multivalue ret.put("success", true); return WebUtility.getResponse(ret, 200); } - + + /** + * Get the users with no access to a given insight + * @param request + * @param form + * @return + */ + @GET + @Produces("application/json") + @Path("getInsightUsersNoCredentials") + public Response getInsightUsersNoCredentials(@Context HttpServletRequest request, @QueryParam("appId") String appId, @QueryParam("insightId") String insightId) { + User user = null; + try { + user = ResourceUtility.getUser(request); + } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), " user does not have access to provided insight")); + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + + List> ret = null; + try { + ret = SecurityInsightUtils.getInsightUsersNoCredentials(user, appId, insightId); + } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), " is trying to pull users without access to insight " + insightId + " in app " + appId + " without having proper access")); + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + + return WebUtility.getResponse(ret, 200); + } } From 81d075252930ba5a617c791653b9806f5f283e1c Mon Sep 17 00:00:00 2001 From: rramirezjimenez Date: Tue, 6 Oct 2020 14:58:19 +0000 Subject: [PATCH 0670/1906] UPDATE ::: Adding rest call for admin insight list unauthorized users git-svn-id: svn://107.170.10.188:8080/Monolith/dev@40494 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 20d13e68f47dafb1cbe6adfc429162a33e11f292 --- .../auth/AdminAppAuthorizationResource.java | 2 +- .../AdminInsightAuthorizationResource.java | 36 +++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/prerna/semoss/web/services/local/auth/AdminAppAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/AdminAppAuthorizationResource.java index 26c31b330..835b36914 100644 --- a/src/prerna/semoss/web/services/local/auth/AdminAppAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/AdminAppAuthorizationResource.java @@ -302,7 +302,7 @@ public Response getAppUsersNoCredentials(@Context HttpServletRequest request, @Q List> ret = null; try { - ret = adminUtils.getAppUsersNoCredentials(user, appId); + ret = adminUtils.getAppUsersNoCredentials(appId); } catch (IllegalAccessException e) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), " is trying to pull users for " + appId + " that do not have credentials without having proper access")); logger.error(Constants.STACKTRACE, e); diff --git a/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java index c105a70b9..02f46ec9e 100644 --- a/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java @@ -365,4 +365,40 @@ public Response setInsightGlobal(@Context HttpServletRequest request, Multivalue return WebUtility.getResponse(ret, 200); } + /** + * Get the users with no access to a given insight + * @param request + * @param form + * @return + */ + @GET + @Produces("application/json") + @Path("getInsightUsersNoCredentials") + public Response getInsightUsersNoCredentials(@Context HttpServletRequest request, @QueryParam("appId") String appId, @QueryParam("insightId") String insightId) { + SecurityAdminUtils adminUtils = null; + User user = null; + try { + user = ResourceUtility.getUser(request); + adminUtils = performAdminCheck(request, user); + } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to get all users who have access to insight " + insightId + " in app " + appId + " when not an admin")); + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + + List> ret = null; + try { + ret = adminUtils.getInsightUsersNoCredentials(appId, insightId); + } catch (IllegalAccessException e) { + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + + return WebUtility.getResponse(ret, 200); + } + } From 137f6be5aca1ec53e97353ec1e7c17f72680de9f Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 8 Oct 2020 02:53:14 +0000 Subject: [PATCH 0671/1906] UPDATE ::: Adding logic to return the userId in the whoami call since we do not continuously parse the windows principal after login has occurred git-svn-id: svn://107.170.10.188:8080/Monolith/dev@40526 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: a509421449de609f6183d71dc6033ca3c2ad0c1a --- .../web/services/local/UserResource.java | 61 ++++++++++++------- 1 file changed, 38 insertions(+), 23 deletions(-) diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index 1625b71f9..992266138 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -1671,17 +1671,17 @@ private void setMainPageRedirect(@Context HttpServletRequest request, @Context H } } - /** - * Set the information in the JSON return after logging in - * - * @param token - * @param ret - */ - private void setAccessTokenDetails(AccessToken token, Map ret) { - ret.put("name", token.getName()); - ret.put("email", token.getEmail()); - ret.put("type", token.getToken_type()); - } +// /** +// * Set the information in the JSON return after logging in +// * +// * @param token +// * @param ret +// */ +// private void setAccessTokenDetails(AccessToken token, Map ret) { +// ret.put("name", token.getName()); +// ret.put("email", token.getEmail()); +// ret.put("type", token.getToken_type()); +// } ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// @@ -1785,19 +1785,34 @@ public StreamingOutput manCookie(@Context HttpServletRequest request, @Context H public Response show(@Context HttpServletRequest request, @Context HttpServletResponse response) { Principal principal = request.getUserPrincipal(); Map output = new HashMap<>(); - output.put("name", principal.getName()); - if (principal instanceof WindowsPrincipal) { - WindowsPrincipal windowsPrincipal = (WindowsPrincipal) principal; - List> gropus = new Vector<>(); - for (waffle.windows.auth.WindowsAccount account : windowsPrincipal.getGroups().values()) { - Map m = new HashMap<>(); - m.put("name", account.getName()); - m.put("domain", account.getDomain()); - m.put("fqn", account.getFqn()); - m.put("sid", account.getSidString()); - gropus.add(m); + if(principal != null) { + output.put("name", principal.getName()); + if (principal instanceof WindowsPrincipal) { + WindowsPrincipal windowsPrincipal = (WindowsPrincipal) principal; + List> gropus = new Vector<>(); + for (waffle.windows.auth.WindowsAccount account : windowsPrincipal.getGroups().values()) { + Map m = new HashMap<>(); + m.put("name", account.getName()); + m.put("domain", account.getDomain()); + m.put("fqn", account.getFqn()); + m.put("sid", account.getSidString()); + gropus.add(m); + } + output.put("groups", gropus); + } + } else { + HttpSession session = request.getSession(false); + if(session != null) { + User user = (User) session.getAttribute(Constants.SESSION_USER); + if(user != null) { + AccessToken token = user.getAccessToken(user.getPrimaryLogin()); + output.put("name", token.getId()); + output.put("warning", "null principal - grab from user"); + } + } + if(output.isEmpty()) { + output.put("error", "null principal"); } - output.put("groups", gropus); } return WebUtility.getResponse(output, 200); } From 33649067e59ef2a579b210973a716fd3dae180b1 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 8 Oct 2020 15:56:54 +0000 Subject: [PATCH 0672/1906] UPDATE ::: Pushing new query struct adapters for csv/excel files git-svn-id: svn://107.170.10.188:8080/Monolith/dev@40531 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 2e6955245746ab4fe88f75899ecf67e066e00a54 --- src/prerna/semoss/web/services/local/NameServer.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index 063235c23..772bc61f7 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -91,6 +91,7 @@ import prerna.sablecc2.PixelUtility; import prerna.sablecc2.comm.JobManager; import prerna.sablecc2.comm.JobThread; +import prerna.sablecc2.pipeline.PipelineOperation; import prerna.semoss.web.services.remote.CentralNameServer; import prerna.semoss.web.services.remote.EngineRemoteResource; import prerna.util.Constants; @@ -549,8 +550,9 @@ private Response getInsightPipeline(Insight insight, String expression) { private Response getInsightPipeline2(Insight insight, String expression) { synchronized (insight) { try { + List> pipeline = PixelUtility.generatePipeline2(insight, expression); return Response.status(200) - .entity(GsonUtility.getDefaultGson().toJson(PixelUtility.generatePipeline2(insight, expression))) + .entity(GsonUtility.getDefaultGson().toJson(pipeline)) .build(); } catch (Exception e) { logger.error(Constants.STACKTRACE, e); From fa7400b895694f812099eeb563a50ebc8e033966 Mon Sep 17 00:00:00 2001 From: rramirezjimenez Date: Fri, 9 Oct 2020 19:11:27 +0000 Subject: [PATCH 0673/1906] UPDATE ::: Adding new admin rest calls for insights/apps git-svn-id: svn://107.170.10.188:8080/Monolith/dev@40550 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 48b1c561b11f69c9f4486a565af46735e2c8a45f --- .../auth/AdminAppAuthorizationResource.java | 124 ++++++++++++++++- .../AdminInsightAuthorizationResource.java | 131 ++++++++++++++++++ 2 files changed, 253 insertions(+), 2 deletions(-) diff --git a/src/prerna/semoss/web/services/local/auth/AdminAppAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/AdminAppAuthorizationResource.java index 835b36914..6e009e0a8 100644 --- a/src/prerna/semoss/web/services/local/auth/AdminAppAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/AdminAppAuthorizationResource.java @@ -78,6 +78,43 @@ public Response getAllUserApps(@Context HttpServletRequest request, MultivaluedM return WebUtility.getResponse(adminUtils.getAllUserDbs(userId), 200); } + @POST + @Path("/grantALlApps") + @Produces("application/json") + public Response grantALlApps(@Context HttpServletRequest request, MultivaluedMap form) { + SecurityAdminUtils adminUtils = null; + User user = null; + String userId = form.getFirst("userId"); + String permission = form.getFirst("permission"); + try { + user = ResourceUtility.getUser(request); + adminUtils = performAdminCheck(request, user); + } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to grant all the apps to user " + userId + " when not an admin")); + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + + try { + adminUtils.grantAllApps(userId, permission); + } catch (Exception e) { + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 400); + } + + // log the operation + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), + "has granted all apps to " + userId + "with permission " + permission)); + + Map ret = new HashMap(); + ret.put("success", true); + return WebUtility.getResponse(ret, 200); + } + /** * Get the app users and their permissions * @param request @@ -116,11 +153,9 @@ public Response getAppUsers(@Context HttpServletRequest request, @QueryParam("ap public Response addAppUserPermission(@Context HttpServletRequest request, MultivaluedMap form) { SecurityAdminUtils adminUtils = null; User user = null; - String newUserId = form.getFirst("id"); String appId = form.getFirst("appId"); String permission = form.getFirst("permission"); - try { user = ResourceUtility.getUser(request); adminUtils = performAdminCheck(request, user); @@ -149,6 +184,49 @@ public Response addAppUserPermission(@Context HttpServletRequest request, Multiv return WebUtility.getResponse(ret, 200); } + /** + * Add all users to an app + * @param request + * @param form + * @return + */ + @POST + @Produces("application/json") + @Path("addAllUsers") + public Response addAllUsers(@Context HttpServletRequest request, MultivaluedMap form) { + SecurityAdminUtils adminUtils = null; + User user = null; + String appId = form.getFirst("appId"); + String permission = form.getFirst("permission"); + + try { + user = ResourceUtility.getUser(request); + adminUtils = performAdminCheck(request, user); + } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to add all users to app " + appId + " when not an admin")); + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + + try { + adminUtils.addAllAppUsers(appId, permission); + } catch (Exception e) { + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 400); + } + + // log the operation + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has added all users to app " + appId + " with permission " + permission)); + + Map ret = new HashMap(); + ret.put("success", true); + return WebUtility.getResponse(ret, 200); + } + /** * Edit user permission for an app * @param request @@ -194,6 +272,48 @@ public Response editAppUserPermission(@Context HttpServletRequest request, Multi return WebUtility.getResponse(ret, 200); } + /** + * update all user's permission level to new permission level for an app + * @param request + * @param form + * @return + */ + @POST + @Produces("application/json") + @Path("updateAppUserPermissions") + public Response updateAppUserPermissions(@Context HttpServletRequest request, MultivaluedMap form) { + SecurityAdminUtils adminUtils = null; + User user = null; + String appId = form.getFirst("appId"); + String newPermission = form.getFirst("permission"); + try { + user = ResourceUtility.getUser(request); + adminUtils = performAdminCheck(request, user); + } catch (IllegalAccessException e) { + logger.error(Constants.STACKTRACE, e); + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to edit user permissions for app " + appId + " when not an admin")); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + + try { + adminUtils.updateAppUserPermissions(appId, newPermission); + } catch (Exception e) { + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 400); + } + + // log the operation + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has edited user permissions to app " + appId + " with level " + newPermission)); + + Map ret = new HashMap(); + ret.put("success", true); + return WebUtility.getResponse(ret, 200); + } + /** * Remove user permission for an app * @param request diff --git a/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java index 02f46ec9e..e344a6695 100644 --- a/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java @@ -219,6 +219,94 @@ public Response addInsightUserPermission(@Context HttpServletRequest request, Mu return WebUtility.getResponse(ret, 200); } + /** + * Give permission to user for all insights in an app + * @param request + * @param form + * @return + */ + @POST + @Path("/grantALlAppInsights") + @Produces("application/json") + public Response grantALlAppInsights(@Context HttpServletRequest request, MultivaluedMap form) { + SecurityAdminUtils adminUtils = null; + User user = null; + String appId = form.getFirst("appId"); + String userId = form.getFirst("userId"); + String permission = form.getFirst("permission"); + try { + user = ResourceUtility.getUser(request); + adminUtils = performAdminCheck(request, user); + } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to pull the apps that user " + userId + " has access to when not an admin")); + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + + try { + adminUtils.grantAllAppInsights(appId, userId, permission); + } catch (Exception e) { + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 400); + } + + // log the operation + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), + "has granted all apps to " + userId + "with permission " + permission)); + + Map ret = new HashMap(); + ret.put("success", true); + return WebUtility.getResponse(ret, 200); + } + + /** + * Add all users to an insight + * @param request + * @param form + * @return + */ + @POST + @Produces("application/json") + @Path("addAllUsers") + public Response addAllUsers(@Context HttpServletRequest request, MultivaluedMap form) { + SecurityAdminUtils adminUtils = null; + User user = null; + String appId = form.getFirst("appId"); + String insightId = form.getFirst("insightId"); + String permission = form.getFirst("permission"); + try { + user = ResourceUtility.getUser(request); + adminUtils = performAdminCheck(request, user); + } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to add all users to insight " + insightId + " in app " + appId + " when not an admin")); + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + + try { + adminUtils.addAllInsightUsers(appId, insightId, permission); + } catch (Exception e) { + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 400); + } + + // log the operation + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has added all users to app " + appId + " with permission " + permission)); + + Map ret = new HashMap(); + ret.put("success", true); + return WebUtility.getResponse(ret, 200); + } + + /** * Edit user permission for an insight * @param request @@ -265,6 +353,49 @@ public Response editInsightUserPermission(@Context HttpServletRequest request, M return WebUtility.getResponse(ret, 200); } + /** + * update all user's permission level to new permission level for an insight + * @param request + * @param form + * @return + */ + @POST + @Produces("application/json") + @Path("updateInsightUserPermissions") + public Response updateAppUserPermissions(@Context HttpServletRequest request, MultivaluedMap form) { + SecurityAdminUtils adminUtils = null; + User user = null; + String appId = form.getFirst("appId"); + String newPermission = form.getFirst("permission"); + String insightId = form.getFirst("insightId"); + try { + user = ResourceUtility.getUser(request); + adminUtils = performAdminCheck(request, user); + } catch (IllegalAccessException e) { + logger.error(Constants.STACKTRACE, e); + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to edit user permissions for app " + appId + " when not an admin")); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + + try { + adminUtils.updateInsightUserPermissions(appId, insightId, newPermission); + } catch (Exception e) { + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 400); + } + + // log the operation + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has added all users to insight " + insightId + " with level " + newPermission)); + + Map ret = new HashMap(); + ret.put("success", true); + return WebUtility.getResponse(ret, 200); + } + /** * Remove user permission for an insight * @param request From bd7a4597a6a192023393501eb367e79a11053416 Mon Sep 17 00:00:00 2001 From: rramirezjimenez Date: Wed, 14 Oct 2020 22:02:58 +0000 Subject: [PATCH 0674/1906] UDPATE ::: end point fix :/ git-svn-id: svn://107.170.10.188:8080/Monolith/dev@40604 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 289f47b6c1c9095fb54da420bee94ff175fcbf52 --- .../services/local/auth/AdminAppAuthorizationResource.java | 4 ++-- .../local/auth/AdminInsightAuthorizationResource.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/prerna/semoss/web/services/local/auth/AdminAppAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/AdminAppAuthorizationResource.java index 6e009e0a8..5d20a7fdd 100644 --- a/src/prerna/semoss/web/services/local/auth/AdminAppAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/AdminAppAuthorizationResource.java @@ -79,9 +79,9 @@ public Response getAllUserApps(@Context HttpServletRequest request, MultivaluedM } @POST - @Path("/grantALlApps") + @Path("/grantAllApps") @Produces("application/json") - public Response grantALlApps(@Context HttpServletRequest request, MultivaluedMap form) { + public Response grantAllApps(@Context HttpServletRequest request, MultivaluedMap form) { SecurityAdminUtils adminUtils = null; User user = null; String userId = form.getFirst("userId"); diff --git a/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java index e344a6695..940c46b48 100644 --- a/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java @@ -226,9 +226,9 @@ public Response addInsightUserPermission(@Context HttpServletRequest request, Mu * @return */ @POST - @Path("/grantALlAppInsights") + @Path("/grantAllAppInsights") @Produces("application/json") - public Response grantALlAppInsights(@Context HttpServletRequest request, MultivaluedMap form) { + public Response grantAllAppInsights(@Context HttpServletRequest request, MultivaluedMap form) { SecurityAdminUtils adminUtils = null; User user = null; String appId = form.getFirst("appId"); From 13e2aadb9fdafd9444ad9d0401037654af3946a3 Mon Sep 17 00:00:00 2001 From: rramirezjimenez Date: Fri, 16 Oct 2020 18:28:29 +0000 Subject: [PATCH 0675/1906] UPDATE ::: Adding new rest call to add new users to app git-svn-id: svn://107.170.10.188:8080/Monolith/dev@40643 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: a0b60b63e17e457eec58f60d278558a123311e82 --- .../auth/AdminAppAuthorizationResource.java | 51 ++++++++++++++----- 1 file changed, 39 insertions(+), 12 deletions(-) diff --git a/src/prerna/semoss/web/services/local/auth/AdminAppAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/AdminAppAuthorizationResource.java index 5d20a7fdd..5699a0f21 100644 --- a/src/prerna/semoss/web/services/local/auth/AdminAppAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/AdminAppAuthorizationResource.java @@ -115,6 +115,44 @@ public Response grantAllApps(@Context HttpServletRequest request, MultivaluedMap return WebUtility.getResponse(ret, 200); } + + @POST + @Path("/grantNewUsersAppAccess") + @Produces("application/json") + public Response grantNewUsersAppAccess(@Context HttpServletRequest request, MultivaluedMap form) { + SecurityAdminUtils adminUtils = null; + User user = null; + String permission = form.getFirst("permission"); + String appId = form.getFirst("appId"); + try { + user = ResourceUtility.getUser(request); + adminUtils = performAdminCheck(request, user); + } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to grant app to new users when not an admin")); + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + + try { + adminUtils.grantNewUsersAppAccess(appId, permission); + } catch (Exception e) { + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 400); + } + + // log the operation + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), + "has granted app " + appId + "to new users with permission " + permission)); + + Map ret = new HashMap(); + ret.put("success", true); + return WebUtility.getResponse(ret, 200); + } + /** * Get the app users and their permissions * @param request @@ -419,18 +457,7 @@ public Response getAppUsersNoCredentials(@Context HttpServletRequest request, @Q errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 401); } - - List> ret = null; - try { - ret = adminUtils.getAppUsersNoCredentials(appId); - } catch (IllegalAccessException e) { - logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), " is trying to pull users for " + appId + " that do not have credentials without having proper access")); - logger.error(Constants.STACKTRACE, e); - Map errorMap = new HashMap(); - errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); - return WebUtility.getResponse(errorMap, 401); - } - + List> ret = adminUtils.getAppUsersNoCredentials(appId); return WebUtility.getResponse(ret, 200); } From 71422d9e4765505547d7fd2ee147f818f5112ca8 Mon Sep 17 00:00:00 2001 From: rramirezjimenez Date: Fri, 16 Oct 2020 18:31:22 +0000 Subject: [PATCH 0676/1906] UPDATE ::: Adding change to endpoint git-svn-id: svn://107.170.10.188:8080/Monolith/dev@40644 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: aa25c1eb8b30ccabffe08e08f78012d29f7855f8 --- .../auth/AdminInsightAuthorizationResource.java | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java index 940c46b48..e5a3e7b50 100644 --- a/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java @@ -518,17 +518,7 @@ public Response getInsightUsersNoCredentials(@Context HttpServletRequest request errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 401); } - - List> ret = null; - try { - ret = adminUtils.getInsightUsersNoCredentials(appId, insightId); - } catch (IllegalAccessException e) { - logger.error(Constants.STACKTRACE, e); - Map errorMap = new HashMap(); - errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); - return WebUtility.getResponse(errorMap, 401); - } - + List> ret = adminUtils.getInsightUsersNoCredentials(appId, insightId); return WebUtility.getResponse(ret, 200); } From bb6df6f38a42e0f1422c2fa6cc902b60aed81205 Mon Sep 17 00:00:00 2001 From: rramirezjimenez Date: Fri, 16 Oct 2020 19:01:38 +0000 Subject: [PATCH 0677/1906] UPDATE ::: grant insight access for new users git-svn-id: svn://107.170.10.188:8080/Monolith/dev@40647 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: cf1d1c5f753ae3600480b547e5336a9b5d94b311 --- .../AdminInsightAuthorizationResource.java | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java index e5a3e7b50..09e1a3634 100644 --- a/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java @@ -263,6 +263,50 @@ public Response grantAllAppInsights(@Context HttpServletRequest request, Multiva return WebUtility.getResponse(ret, 200); } + /** + * Give permission to user for all insights in an app + * @param request + * @param form + * @return + */ + @POST + @Path("/grantNewUsersInsightAccess") + @Produces("application/json") + public Response grantNewUsersInsightAccess(@Context HttpServletRequest request, MultivaluedMap form) { + SecurityAdminUtils adminUtils = null; + User user = null; + String appId = form.getFirst("appId"); + String insightId = form.getFirst("insightId"); + String permission = form.getFirst("permission"); + try { + user = ResourceUtility.getUser(request); + adminUtils = performAdminCheck(request, user); + } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to grant new users insight access when not an admin")); + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + + try { + adminUtils.grantNewUsersInsightAccess(appId, insightId, permission); + } catch (Exception e) { + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 400); + } + + // log the operation + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), + "has granted new users with permission " + permission)); + + Map ret = new HashMap(); + ret.put("success", true); + return WebUtility.getResponse(ret, 200); + } + /** * Add all users to an insight * @param request From 37bedbd01709d4e32b4c31681c8837ba40f90ff9 Mon Sep 17 00:00:00 2001 From: rramirezjimenez Date: Tue, 20 Oct 2020 19:12:10 +0000 Subject: [PATCH 0678/1906] UPDATE ::: Adding email and type when an admin register a user git-svn-id: svn://107.170.10.188:8080/Monolith/dev@40692 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 22f09b974f2553323014c770e7deedc6f497b396 --- .../semoss/web/services/local/AuthorizationResource.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/prerna/semoss/web/services/local/AuthorizationResource.java b/src/prerna/semoss/web/services/local/AuthorizationResource.java index 7818fc20b..cd1e98667 100644 --- a/src/prerna/semoss/web/services/local/AuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/AuthorizationResource.java @@ -99,10 +99,13 @@ public Response registerUser(@Context HttpServletRequest request, MultivaluedMap User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); String newUserId = form.getFirst("userId"); + String name = form.getFirst("name"); + String email = form.getFirst("email"); + String type = form.getFirst("type"); Boolean newUserAdmin = Boolean.parseBoolean(form.getFirst("admin")); if(SecurityAdminUtils.userIsAdmin(user)){ - success = SecurityUpdateUtils.registerUser(newUserId, newUserAdmin, !AbstractSecurityUtils.adminSetPublisher()); + success = SecurityUpdateUtils.registerUser(newUserId, name, email, type, newUserAdmin, !AbstractSecurityUtils.adminSetPublisher()); } else { errorRet.put("error", "The user doesn't have the permissions to perform this action."); return WebUtility.getResponse(errorRet, 400); From 02373ce9c5edf6200273d8240185c0a9499757c5 Mon Sep 17 00:00:00 2001 From: rramirezjimenez Date: Tue, 20 Oct 2020 20:28:37 +0000 Subject: [PATCH 0679/1906] UPDATE ::: fixing calls to register new user git-svn-id: svn://107.170.10.188:8080/Monolith/dev@40702 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 554480cc43914c23c5901175ddf602d3e18a724b --- .../semoss/web/services/config/AdminConfigService.java | 2 +- .../services/local/auth/AdminUserAuthorizationResource.java | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/prerna/semoss/web/services/config/AdminConfigService.java b/src/prerna/semoss/web/services/config/AdminConfigService.java index 91dc5c459..219e691e4 100644 --- a/src/prerna/semoss/web/services/config/AdminConfigService.java +++ b/src/prerna/semoss/web/services/config/AdminConfigService.java @@ -41,7 +41,7 @@ public Response setInitialAdmins(@Context HttpServletRequest request, @Context H List ids = GSON.fromJson(idString, List.class); for (String id : ids) { - SecurityUpdateUtils.registerUser(id, true, true); + SecurityUpdateUtils.registerUser(id, null, null, null, true, true); } if (session.getAttribute(ADMIN_REDIRECT_KEY) != null) { diff --git a/src/prerna/semoss/web/services/local/auth/AdminUserAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/AdminUserAuthorizationResource.java index b79b7fc22..1e618443c 100644 --- a/src/prerna/semoss/web/services/local/auth/AdminUserAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/AdminUserAuthorizationResource.java @@ -38,12 +38,14 @@ public Response registerUser(@Context HttpServletRequest request, MultivaluedMap User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); String newUserId = form.getFirst("userId"); + String name = form.getFirst("name"); + String email = form.getFirst("email"); + String type = form.getFirst("type"); Boolean newUserAdmin = Boolean.parseBoolean(form.getFirst("admin")); - Boolean autoGenPassword = Boolean.parseBoolean(form.getFirst("admin")); String userPassword = form.getFirst("password"); if(SecurityAdminUtils.userIsAdmin(user)){ - success = SecurityUpdateUtils.registerUser(newUserId, newUserAdmin, !AbstractSecurityUtils.adminSetPublisher()); + success = SecurityUpdateUtils.registerUser(newUserId, name, email, type, newUserAdmin, !AbstractSecurityUtils.adminSetPublisher()); } else { errorRet.put("error", "The user doesn't have the permissions to perform this action."); return WebUtility.getResponse(errorRet, 400); From 5c4283fc4acc87b1b0830b93202e73590bb90b81 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 20 Oct 2020 22:22:10 +0000 Subject: [PATCH 0680/1906] UPDATE ::: Adding formal PixelList and Pixel objects for the recipe management UPDATE ::: Adding getPipeline to return back original data + unique ids for each pixel step git-svn-id: svn://107.170.10.188:8080/Monolith/dev@40704 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: b73dc4788ce5560a04ebee1c30ad69aeea824210 --- src/prerna/semoss/web/services/local/NameServer.java | 7 +++---- src/prerna/semoss/web/services/local/RunInsight.java | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index 772bc61f7..7ee501351 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -363,7 +363,6 @@ public Response getPixelPipelinePlan(@Context HttpServletRequest request) { } String insightId = request.getParameter("insightId"); - String expression = request.getParameter("expression"); Insight insight = InsightStore.getInstance().get(insightId); if (insight == null) { Map errorMap = new HashMap<>(); @@ -379,7 +378,7 @@ public Response getPixelPipelinePlan(@Context HttpServletRequest request) { ThreadStore.setSessionId(sessionId); ThreadStore.setUser(user); - return getInsightPipeline(insight, expression); + return getInsightPipeline(insight); } @@ -526,11 +525,11 @@ private Response runPixelJob(User user, Insight insight, String expression, Stri * @param expression * @return */ - private Response getInsightPipeline(Insight insight, String expression) { + private Response getInsightPipeline(Insight insight) { synchronized (insight) { try { return Response.status(200) - .entity(GsonUtility.getDefaultGson().toJson(PixelUtility.generatePipeline(insight, expression))) + .entity(GsonUtility.getDefaultGson().toJson(PixelUtility.generatePipeline(insight))) .build(); } catch (Exception e) { logger.error(Constants.STACKTRACE, e); diff --git a/src/prerna/semoss/web/services/local/RunInsight.java b/src/prerna/semoss/web/services/local/RunInsight.java index 30f3f30b0..d7f67477e 100644 --- a/src/prerna/semoss/web/services/local/RunInsight.java +++ b/src/prerna/semoss/web/services/local/RunInsight.java @@ -68,7 +68,7 @@ public Response getInsightData(@Context HttpServletRequest request) { @Path("/getInsightState") @Produces("application/json") public Response recreateInsightState(@Context HttpServletRequest request) { - List recipe = in.getPixelRecipe(); + List recipe = in.getPixelList().getPixelRecipe(); OptimizeRecipeTranslation opTrans = getOptimizedRecipe(recipe); Insight rerunInsight = new Insight(); From c91b16c5967a65e0ab2b67b66a2fbd867dc3d852 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 21 Oct 2020 21:33:28 +0000 Subject: [PATCH 0681/1906] UPDATE ::: Adding missing dependency for jStyleParser git-svn-id: svn://107.170.10.188:8080/Monolith/dev@40738 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 3940f1204f8ecf007c00d7888cfc65de85b1d76e --- pom.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pom.xml b/pom.xml index 161914d74..9dbe02069 100644 --- a/pom.xml +++ b/pom.xml @@ -1089,6 +1089,12 @@ poi-scratchpad 4.1.1 + + + net.sf.cssbox + jstyleparser + 3.5 + org.jboss.resteasy resteasy-core From 9be6a3969d9f498abecfdd18bddbdca15362e411 Mon Sep 17 00:00:00 2001 From: rramirezjimenez Date: Thu, 22 Oct 2020 14:34:28 +0000 Subject: [PATCH 0682/1906] UPDATE ::: Adding password when registering native user git-svn-id: svn://107.170.10.188:8080/Monolith/dev@40751 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: c543b2f55137d236208824431435b781cf75a617 --- .../services/config/AdminConfigService.java | 2 +- .../services/local/AuthorizationResource.java | 16 +++++++++++++++- .../auth/AdminUserAuthorizationResource.java | 19 ++++++++++++++++--- 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/src/prerna/semoss/web/services/config/AdminConfigService.java b/src/prerna/semoss/web/services/config/AdminConfigService.java index 219e691e4..8def4701f 100644 --- a/src/prerna/semoss/web/services/config/AdminConfigService.java +++ b/src/prerna/semoss/web/services/config/AdminConfigService.java @@ -41,7 +41,7 @@ public Response setInitialAdmins(@Context HttpServletRequest request, @Context H List ids = GSON.fromJson(idString, List.class); for (String id : ids) { - SecurityUpdateUtils.registerUser(id, null, null, null, true, true); + SecurityUpdateUtils.registerUser(id, null, null, null, null , true, true); } if (session.getAttribute(ADMIN_REDIRECT_KEY) != null) { diff --git a/src/prerna/semoss/web/services/local/AuthorizationResource.java b/src/prerna/semoss/web/services/local/AuthorizationResource.java index cd1e98667..bb382334c 100644 --- a/src/prerna/semoss/web/services/local/AuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/AuthorizationResource.java @@ -101,11 +101,25 @@ public Response registerUser(@Context HttpServletRequest request, MultivaluedMap String newUserId = form.getFirst("userId"); String name = form.getFirst("name"); String email = form.getFirst("email"); + // validate email & password + if (email != null && !email.isEmpty()) { + String emailError = AbstractSecurityUtils.validEmail(email); + if (!emailError.isEmpty()) { + throw new IllegalArgumentException(emailError); + } + } + String password = form.getFirst("password"); + if (password != null && !password.isEmpty()) { + String passwordError = AbstractSecurityUtils.validPassword(password); + if (!passwordError.isEmpty()) { + throw new IllegalArgumentException(passwordError); + } + } String type = form.getFirst("type"); Boolean newUserAdmin = Boolean.parseBoolean(form.getFirst("admin")); if(SecurityAdminUtils.userIsAdmin(user)){ - success = SecurityUpdateUtils.registerUser(newUserId, name, email, type, newUserAdmin, !AbstractSecurityUtils.adminSetPublisher()); + success = SecurityUpdateUtils.registerUser(newUserId, name, email, password, type, newUserAdmin, !AbstractSecurityUtils.adminSetPublisher()); } else { errorRet.put("error", "The user doesn't have the permissions to perform this action."); return WebUtility.getResponse(errorRet, 400); diff --git a/src/prerna/semoss/web/services/local/auth/AdminUserAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/AdminUserAuthorizationResource.java index 1e618443c..d6cc1e0c1 100644 --- a/src/prerna/semoss/web/services/local/auth/AdminUserAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/AdminUserAuthorizationResource.java @@ -42,10 +42,23 @@ public Response registerUser(@Context HttpServletRequest request, MultivaluedMap String email = form.getFirst("email"); String type = form.getFirst("type"); Boolean newUserAdmin = Boolean.parseBoolean(form.getFirst("admin")); - String userPassword = form.getFirst("password"); - + String password = form.getFirst("password"); + // validate email & password + if (email != null && !email.isEmpty()) { + String emailError = AbstractSecurityUtils.validEmail(email); + if (!emailError.isEmpty()) { + throw new IllegalArgumentException(emailError); + } + } + // password is only defined if native type + if (password != null && !password.isEmpty()) { + String passwordError = AbstractSecurityUtils.validPassword(password); + if (!passwordError.isEmpty()) { + throw new IllegalArgumentException(passwordError); + } + } if(SecurityAdminUtils.userIsAdmin(user)){ - success = SecurityUpdateUtils.registerUser(newUserId, name, email, type, newUserAdmin, !AbstractSecurityUtils.adminSetPublisher()); + success = SecurityUpdateUtils.registerUser(newUserId, name, email, password, type, newUserAdmin, !AbstractSecurityUtils.adminSetPublisher()); } else { errorRet.put("error", "The user doesn't have the permissions to perform this action."); return WebUtility.getResponse(errorRet, 400); From 4031a8e463c49feb4bc5fca269cf7e34d0f88476 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 23 Oct 2020 20:15:32 +0000 Subject: [PATCH 0683/1906] UPDATE ::: Deleting legacy getPipeline2 git-svn-id: svn://107.170.10.188:8080/Monolith/dev@40792 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 108e6ccd8ec5e566186ec79d036c83b310123da7 --- .../semoss/web/services/local/NameServer.java | 75 ------------------- 1 file changed, 75 deletions(-) diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index 7ee501351..c69612745 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -91,7 +91,6 @@ import prerna.sablecc2.PixelUtility; import prerna.sablecc2.comm.JobManager; import prerna.sablecc2.comm.JobThread; -import prerna.sablecc2.pipeline.PipelineOperation; import prerna.semoss.web.services.remote.CentralNameServer; import prerna.semoss.web.services.remote.EngineRemoteResource; import prerna.util.Constants; @@ -381,58 +380,6 @@ public Response getPixelPipelinePlan(@Context HttpServletRequest request) { return getInsightPipeline(insight); } - - @POST - @Path("/getPipeline2") - @Produces("application/json;charset=utf-8") - public Response getPixelPipelinePlan2(@Context HttpServletRequest request) { - HttpSession session = null; - String sessionId = null; - User user = null; - - boolean securityEnabled = AbstractSecurityUtils.securityEnabled(); - // If security is enabled try to get an existing session. - // Otherwise get a session with the default user. - if (securityEnabled) { - session = request.getSession(false); - if (session != null) { - sessionId = session.getId(); - user = ((User) session.getAttribute(Constants.SESSION_USER)); - } - - if (user == null) { - Map errorMap = new HashMap<>(); - errorMap.put("error", "User session is invalid"); - logger.debug("User session is invalid"); - return WebUtility.getResponse(errorMap, 401); - } - } else { - session = request.getSession(true); - user = ((User) session.getAttribute(Constants.SESSION_USER)); - sessionId = session.getId(); - } - - String insightId = request.getParameter("insightId"); - String expression = request.getParameter("expression"); - Insight insight = InsightStore.getInstance().get(insightId); - if (insight == null) { - Map errorMap = new HashMap<>(); - errorMap.put(Constants.ERROR_MESSAGE, "Could not find the insight id"); - errorMap.put(ERROR_TYPE, INSIGHT_NOT_FOUND); - return WebUtility.getResponse(errorMap, 400); - } - - // set the user - insight.setUser(user); - // set in thread - ThreadStore.setInsightId(insightId); - ThreadStore.setSessionId(sessionId); - ThreadStore.setUser(user); - - return getInsightPipeline2(insight, expression); - } - - /** * * @param user @@ -540,28 +487,6 @@ private Response getInsightPipeline(Insight insight) { } } - /** - * - * @param insight - * @param expression - * @return - */ - private Response getInsightPipeline2(Insight insight, String expression) { - synchronized (insight) { - try { - List> pipeline = PixelUtility.generatePipeline2(insight, expression); - return Response.status(200) - .entity(GsonUtility.getDefaultGson().toJson(pipeline)) - .build(); - } catch (Exception e) { - logger.error(Constants.STACKTRACE, e); - Map errorMap = new HashMap<>(); - errorMap.put(Constants.ERROR_MESSAGE, e.getMessage()); - return WebUtility.getResponse(errorMap, 400); - } - } - } - @POST @Path("runPixelAsync") @Produces("application/json;charset=utf-8") From b5d52e3e1ce089412e933db85b05a6e92bdb8a3d Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 4 Nov 2020 18:14:16 +0000 Subject: [PATCH 0684/1906] UPDATE ::: Modifying the payload structure for console so the FE can determine when to cancel the console call git-svn-id: svn://107.170.10.188:8080/Monolith/dev@41065 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: cc9c8e457388788179862047c4d9403257ad8721 --- .../semoss/web/services/local/NameServer.java | 83 ++++++------------- 1 file changed, 25 insertions(+), 58 deletions(-) diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index c69612745..3362d6b68 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -90,6 +90,7 @@ import prerna.sablecc2.PixelStreamUtility; import prerna.sablecc2.PixelUtility; import prerna.sablecc2.comm.JobManager; +import prerna.sablecc2.comm.JobStatus; import prerna.sablecc2.comm.JobThread; import prerna.semoss.web.services.remote.CentralNameServer; import prerna.semoss.web.services.remote.EngineRemoteResource; @@ -411,61 +412,17 @@ private Response runPixelJob(User user, Insight insight, String expression, Stri jt.run(); PixelRunner pixelRunner = jt.getRunner(); - return Response.status(200).entity(PixelStreamUtility.collectPixelData(pixelRunner)) - .header("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0, post-check=0, pre-check=0") - .header("Pragma", "no-cache") - .build(); + try { + return Response.status(200).entity(PixelStreamUtility.collectPixelData(pixelRunner)) + .header("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0, post-check=0, pre-check=0") + .header("Pragma", "no-cache") + .build(); + } finally { + jt.setStatus(JobStatus.COMPLETE); + manager.removeJob(jobId); + } } -// /** -// * -// * @param session -// * @param sessionId -// * @param user -// */ -// private void setPythonForSession(HttpSession session, String sessionId, User user) { -// PyTranslator pyt = null; -// String port = null; -// -// boolean useFilePy = Boolean.parseBoolean(DIHelper.getInstance().getProperty("USE_PY_FILE")); -// boolean useTCP = Boolean.parseBoolean(DIHelper.getInstance().getProperty("USE_TCP_PY")); -// useTCP = useFilePy; // forcing it to be same as TCP -// -// if (!useFilePy) { -// if (session.getAttribute(Constants.PYTHON) != null) { -// pyt = (PyTranslator) session.getAttribute(Constants.PYTHON); -// } -// -// PyExecutorThread jepThread = PyUtils.getInstance().getJep(); -// pyt = new PyTranslator(); -// pyt.setPy(jepThread); -// } -// // check to see if the py translator needs to be set ? -// else if (useFilePy && session.getAttribute("USER_TUPLE") == null) { -// if (useTCP) { -// port = DIHelper.getInstance().getProperty("FORCE_PORT"); // this means someone has started it -// if (port == null) { -// port = Utility.findOpenPort(); -// session.setAttribute("USER_TUPLE", PyUtils.getInstance().startPyServe(user, -// DIHelper.getInstance().getProperty(Constants.INSIGHT_CACHE_DIR), port)); -// NettyClient nc = new NettyClient(); -// nc.connect("127.0.0.1", Integer.parseInt(port), false); -// Thread t = new Thread(nc); -// t.start(); -// user.setPyServe(nc); -// pyt = new TCPPyTranslator(); -// ((TCPPyTranslator) pyt).nc = nc; -// } -// session.setAttribute("PORT", port); -// } else { -// String userTuple = PyUtils.getInstance().getTempTupleSpace(user, DIHelper.getInstance().getProperty(Constants.INSIGHT_CACHE_DIR)); -// session.setAttribute("USER_TUPLE", userTuple); -// pyt = new FilePyTranslator(); -// } -// } -// session.setAttribute(Constants.PYTHON, pyt); -// } - /** * * @param insight @@ -582,7 +539,11 @@ public Response status(MultivaluedMap form, @Context HttpServlet HttpSession session = request.getSession(true); String jobId = form.getFirst("jobId"); if (session.getAttribute(jobId) != null) { - dataReturn = JobManager.getManager().getStatus(jobId); + JobThread jt = JobManager.getManager().getJob(jobId); + if(jt == null) { + dataReturn = JobStatus.UNKNOWN_JOB; + } + dataReturn = jt.getStatus(); } return WebUtility.getResponseNoCache(dataReturn, 200); } @@ -592,12 +553,15 @@ public Response status(MultivaluedMap form, @Context HttpServlet @Path("/console") @Produces("application/json") public Response console(MultivaluedMap form, @Context HttpServletRequest request) { - Object dataReturn = "NULL"; String jobId = form.getFirst("jobId"); // HttpSession session = request.getSession(true); // if(session.getAttribute(jobId) != null) { // if(jobId != null) - dataReturn = JobManager.getManager().getStdOut(jobId); + JobThread jt = JobManager.getManager().getJob(jobId); + List console = JobManager.getManager().getStdOut(jobId); + Map dataReturn = new HashMap<>(); + dataReturn.put("status", jt == null ? JobStatus.UNKNOWN_JOB : jt.getStatus()); + dataReturn.put("message", console); // } return WebUtility.getResponseNoCache(dataReturn, 200); } @@ -606,11 +570,14 @@ public Response console(MultivaluedMap form, @Context HttpServle @Path("/error") @Produces("application/json") public Response error(MultivaluedMap form, @Context HttpServletRequest request) { - Object dataReturn = "NULL"; String jobId = form.getFirst("jobId"); // HttpSession session = request.getSession(true); // if(session.getAttribute(jobId) != null) { - dataReturn = JobManager.getManager().getError(jobId); + JobThread jt = JobManager.getManager().getJob(jobId); + List console = JobManager.getManager().getError(jobId); + Map dataReturn = new HashMap<>(); + dataReturn.put("status", jt == null ? JobStatus.UNKNOWN_JOB : jt.getStatus()); + dataReturn.put("message", console); // } return WebUtility.getResponseNoCache(dataReturn, 200); } From d13dfd8f1fe9c2cf5bffa2693bfacd32d872cb01 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 6 Nov 2020 01:18:11 +0000 Subject: [PATCH 0685/1906] UPDATE ::: Also making sure to close R when session timeouts git-svn-id: svn://107.170.10.188:8080/Monolith/dev@41103 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 8b726c519d116c5f3fae06c69a027c7e9626ec84 --- src/prerna/web/conf/UserSessionLoader.java | 77 +++++++++++++++++----- 1 file changed, 60 insertions(+), 17 deletions(-) diff --git a/src/prerna/web/conf/UserSessionLoader.java b/src/prerna/web/conf/UserSessionLoader.java index 3d9bc6e5e..416fb3d4f 100644 --- a/src/prerna/web/conf/UserSessionLoader.java +++ b/src/prerna/web/conf/UserSessionLoader.java @@ -2,6 +2,9 @@ import java.util.HashSet; import java.util.Set; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import javax.servlet.annotation.WebListener; import javax.servlet.http.HttpSession; @@ -17,6 +20,7 @@ import prerna.ds.py.FilePyTranslator; import prerna.ds.py.PyTranslator; import prerna.ds.py.PyUtils; +import prerna.engine.impl.r.IRUserConnection; import prerna.om.Insight; import prerna.om.InsightStore; import prerna.util.Constants; @@ -26,7 +30,7 @@ @WebListener public class UserSessionLoader implements HttpSessionListener { - private static final Logger LOGGER = LogManager.getLogger(UserSessionLoader.class.getName()); + private static final Logger logger = LogManager.getLogger(UserSessionLoader.class.getName()); private static final String DIR_SEPARATOR = java.nio.file.FileSystems.getDefault().getSeparator(); public void sessionCreated(HttpSessionEvent sessionEvent) { @@ -36,7 +40,12 @@ public void sessionCreated(HttpSessionEvent sessionEvent) { public void sessionDestroyed(HttpSessionEvent sessionEvent) { HttpSession session = sessionEvent.getSession(); String sessionId = session.getId(); - + User thisUser = (User) session.getAttribute(Constants.SESSION_USER); + if(thisUser == null) { + logger.info(sessionId + " >>> Unknown user ending session"); + } else { + logger.info(sessionId + " >>> User " + User.getSingleLogginName(thisUser) + " ending session"); + } // back up the workspace and asset apps SyncUserAppsThread.execute(session); @@ -50,11 +59,11 @@ public void sessionDestroyed(HttpSessionEvent sessionEvent) { if(insight == null) { continue; } - LOGGER.info("Trying to drop insight " + insightId); + logger.info(sessionId + " >>> Trying to drop insight " + insightId); InsightUtility.dropInsight(insight); - LOGGER.info("Dropped insight " + insightId); + logger.info(sessionId + " >>> Dropped insight " + insightId); } - LOGGER.info("successfully removed insight information from session"); + logger.info(sessionId + " >>> Successfully removed insight information from session"); // clear the current session store insightIDs.removeAll(copy); @@ -63,21 +72,55 @@ public void sessionDestroyed(HttpSessionEvent sessionEvent) { String sessionStorage = DIHelper.getInstance().getProperty(Constants.INSIGHT_CACHE_DIR) + DIR_SEPARATOR + sessionId; ICache.deleteFolder(sessionStorage); - // now drop the thread - if(PyUtils.pyEnabled()) { - PyTranslator pyThread = (PyTranslator) session.getAttribute(Constants.PYTHON); - if(pyThread != null ) { - if(!(pyThread instanceof FilePyTranslator)) { - if(pyThread.getPy() != null) { - PyUtils.getInstance().killPyThread(pyThread.getPy()); + // drop the r thread + try { + if (thisUser != null) { + IRUserConnection rserve = thisUser.getRcon(); + if (rserve != null) { + logger.info(sessionId + " >>> Dropping user r serve"); + ExecutorService executor = Executors.newSingleThreadExecutor(); + try { + executor.submit(new Callable() { + @Override + public Void call() throws Exception { + try { + rserve.stopR(); + logger.info(sessionId + " >>> Successfully dropped user r serve"); + } catch (Exception e) { + logger.warn(sessionId + " >>> Unable to drop user r serve"); + } + return null; + } + }); + } finally { + executor.shutdown(); } - } else { - User user = (User)session.getAttribute(Constants.SESSION_USER); - if(user != null) { - PyUtils.getInstance().killTempTupleSpace(user); + } + } + } catch(Exception e) { + logger.error(Constants.STACKTRACE, e); + } + + // now drop the py thread + if(PyUtils.pyEnabled()) { + try { + PyTranslator pyThread = (PyTranslator) session.getAttribute(Constants.PYTHON); + if(pyThread != null ) { + logger.info(sessionId + " >>> Found python thread to drop"); + if(!(pyThread instanceof FilePyTranslator)) { + if(pyThread.getPy() != null) { + PyUtils.getInstance().killPyThread(pyThread.getPy()); + } + } else { + User user = (User)session.getAttribute(Constants.SESSION_USER); + if(user != null) { + PyUtils.getInstance().killTempTupleSpace(user); + } } + logger.info(sessionId + " >>> Successfully dropped python thread"); } - LOGGER.info("Dropped all python"); + } catch(Exception e) { + logger.error(Constants.STACKTRACE, e); } } } From 8309cf7cc297c254a2c55fdbe3c7a3d05d1522df Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 6 Nov 2020 15:07:33 +0000 Subject: [PATCH 0686/1906] BUGFIX ::: Fixing error when sending the FE the enum string instead of the value git-svn-id: svn://107.170.10.188:8080/Monolith/dev@41118 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 3035b52cefd3b0d0fb8db959cd0dd84d2ee100dd --- src/prerna/semoss/web/services/local/NameServer.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index 3362d6b68..4b6910cfa 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -541,7 +541,7 @@ public Response status(MultivaluedMap form, @Context HttpServlet if (session.getAttribute(jobId) != null) { JobThread jt = JobManager.getManager().getJob(jobId); if(jt == null) { - dataReturn = JobStatus.UNKNOWN_JOB; + dataReturn = JobStatus.UNKNOWN_JOB.getValue(); } dataReturn = jt.getStatus(); } @@ -560,7 +560,7 @@ public Response console(MultivaluedMap form, @Context HttpServle JobThread jt = JobManager.getManager().getJob(jobId); List console = JobManager.getManager().getStdOut(jobId); Map dataReturn = new HashMap<>(); - dataReturn.put("status", jt == null ? JobStatus.UNKNOWN_JOB : jt.getStatus()); + dataReturn.put("status", jt == null ? JobStatus.UNKNOWN_JOB.getValue() : jt.getStatus()); dataReturn.put("message", console); // } return WebUtility.getResponseNoCache(dataReturn, 200); @@ -576,7 +576,7 @@ public Response error(MultivaluedMap form, @Context HttpServletR JobThread jt = JobManager.getManager().getJob(jobId); List console = JobManager.getManager().getError(jobId); Map dataReturn = new HashMap<>(); - dataReturn.put("status", jt == null ? JobStatus.UNKNOWN_JOB : jt.getStatus()); + dataReturn.put("status", jt == null ? JobStatus.UNKNOWN_JOB.getValue() : jt.getStatus()); dataReturn.put("message", console); // } return WebUtility.getResponseNoCache(dataReturn, 200); From 6a51f5a0a661e7a1b425cec91dca2a470f83fb93 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 12 Nov 2020 15:45:08 +0000 Subject: [PATCH 0687/1906] UPDATE ::: Adding rest endpoint to get the insights a user can edit git-svn-id: svn://107.170.10.188:8080/Monolith/dev@41261 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: ed4ec67b48b4d458cd47f12c49b08edc31ae9d24 --- .../AdminInsightAuthorizationResource.java | 2 +- .../auth/InsightAuthorizationResource.java | 26 ++++++++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java index 09e1a3634..540d8fd38 100644 --- a/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java @@ -35,7 +35,7 @@ public class AdminInsightAuthorizationResource extends AbstractAdminResource { private static final Logger logger = LogManager.getLogger(AdminInsightAuthorizationResource.class); /** - * Get the user insight permissions for a given insight + * Get the insights for the app * @param request * @param form * @return diff --git a/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java index 3fba8afcf..4b3b48b16 100644 --- a/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java @@ -34,6 +34,31 @@ public class InsightAuthorizationResource { private static final Logger logger = LogManager.getLogger(InsightAuthorizationResource.class); + /** + * Get the insights the user can edit in the app + * @param request + * @param form + * @return + */ + @GET + @Produces("application/json") + @Path("getAppInsights") + public Response getAppInsights(@Context HttpServletRequest request, @QueryParam("appId") String appId) { + User user = null; + try { + user = ResourceUtility.getUser(request); + } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "invalid user session trying to access authorization resources")); + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + + List> ret = SecurityInsightUtils.getUserEditableInsighs(user, appId); + return WebUtility.getResponse(ret, 200); + } + /** * Get the user insight permissions for a given insight * @param request @@ -68,7 +93,6 @@ public Response getUserInsightPermission(@Context HttpServletRequest request, @Q return WebUtility.getResponse(ret, 200); } - /** * Get the user insight permissions for a given insight * @param request From 112705478181cc7e57cdba0dd60ea029b45a5922 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 16 Nov 2020 15:23:44 +0000 Subject: [PATCH 0688/1906] UPDATE ::: Adding jar for Anthem encryption git-svn-id: svn://107.170.10.188:8080/Monolith/dev@41329 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: f10baa6cf5416876d09f1490cbc698552899bafe --- pom.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pom.xml b/pom.xml index 9dbe02069..284b5cfb1 100644 --- a/pom.xml +++ b/pom.xml @@ -1910,5 +1910,11 @@ jetty-io 9.4.12.v20180830 + + + com.github.ulisesbocchio + jasypt-spring-boot-starter + 2.0.0 + \ No newline at end of file From 6e979807a6cbf5a9b6f27dec2288b1f932e6c9a8 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 17 Nov 2020 21:15:17 +0000 Subject: [PATCH 0689/1906] UPDATE ::: Adding CORS filter options if required git-svn-id: svn://107.170.10.188:8080/Monolith/dev@41353 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: fdef22bad8e95061c8ecde48d124610dfef6a803 --- WebContent/WEB-INF/web.xml | 57 +++++++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index 7a89323ed..2f45ee9a4 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -26,7 +26,62 @@ HeaderSecurityFilter /* - + + + SetCharacterEncoding + org.apache.catalina.filters.SetCharacterEncodingFilter + + encoding + UTF-8 + + + + SetCharacterEncoding + /* + + + HeaderSecurityFilter + org.apache.catalina.filters.HttpHeaderSecurityFilter + + + + HeaderSecurityFilter + /* + + + + CorsFilter + org.apache.catalina.filters.CorsFilter + + cors.allowed.origins + + + + cors.allowed.methods + GET,POST,HEAD,OPTIONS,PUT + + + cors.allowed.headers + Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers + + + cors.exposed.headers + Access-Control-Allow-Origin,Access-Control-Allow-Credentials + + + cors.support.credentials + true + + + cors.preflight.maxage + 10 + + + + CorsFilter + /api/* + + StartUpSuccessFilter From bfb4124680c30612245ceacb90a377a631bf4598 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 17 Nov 2020 23:04:44 +0000 Subject: [PATCH 0690/1906] UPDATE ::: Cleanup for stacktrace error to go to Constants UPDATE ::: Switching the trusted domains to be comma separated from semicolon (this seems to be more standard as tomcat CORS filter uses comma separated values) git-svn-id: svn://107.170.10.188:8080/Monolith/dev@41358 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: bb8f468e216d3c808fe94a580a2e572ceea53f53 --- .../web/services/local/UserResource.java | 31 +++++++++---------- .../NoUserInSessionTrustedTokenFilter.java | 2 +- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index 992266138..ee32d95b0 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -118,7 +118,6 @@ public class UserResource { private static final Logger logger = LogManager.getLogger(UserResource.class); - private static final String STACKTRACE = "StackTrace: "; private static Properties socialData = null; private static Map loginsAllowedMap; @@ -138,17 +137,17 @@ private static void loadSocialProperties() { setLoginsAllowed(); } } catch (FileNotFoundException fnfe) { - logger.error(STACKTRACE, fnfe); + logger.error(Constants.STACKTRACE, fnfe); } catch (IOException ioe) { - logger.error(STACKTRACE, ioe); + logger.error(Constants.STACKTRACE, ioe); } catch (Exception e) { - logger.error(STACKTRACE, e); + logger.error(Constants.STACKTRACE, e); } finally { if (fis != null) { try { fis.close(); } catch (IOException e) { - logger.error(STACKTRACE, e); + logger.error(Constants.STACKTRACE, e); } } } @@ -454,7 +453,7 @@ public Response userinfoGoogle(@Context HttpServletRequest request) { ret.put("picture", accessToken2.getProfile()); } } catch (Exception e) { - logger.error(STACKTRACE, e); + logger.error(Constants.STACKTRACE, e); } return WebUtility.getResponse(ret, 200); @@ -532,7 +531,7 @@ public Response userinfoDropbox(@Context HttpServletRequest request) { } ret.put("name", accessToken2.getName()); } catch (Exception e) { - logger.error(STACKTRACE, e); + logger.error(Constants.STACKTRACE, e); } return WebUtility.getResponse(ret, 200); @@ -574,7 +573,7 @@ public Response userinfoGithub(@Context HttpServletRequest request) { try { ret.put("name", accessToken2.getProfile()); } catch (Exception e) { - logger.error(STACKTRACE, e); + logger.error(Constants.STACKTRACE, e); } return WebUtility.getResponse(ret, 200); } @@ -1125,7 +1124,7 @@ private void performGoogleOps(HttpServletRequest request, Map ret) { try { ret.put("files", BeanFiller.getJson(fileList)); } catch (Exception e) { - logger.error(STACKTRACE, e); + logger.error(Constants.STACKTRACE, e); } IConnectorIOp lat = new GoogleLatLongGetter(); @@ -1467,7 +1466,7 @@ public Response loginNative(@Context HttpServletRequest request, @Context HttpSe return WebUtility.getResponse(ret, 401); } } catch (Exception e) { - logger.error(STACKTRACE, e); + logger.error(Constants.STACKTRACE, e); ret.put("error", "An unexpected error happened. Please try again."); return WebUtility.getResponse(ret, 500); } @@ -1508,11 +1507,11 @@ public Response createUser(@Context HttpServletRequest request) { return WebUtility.getResponse(ret, 400); } } catch (IllegalArgumentException iae) { - logger.error(STACKTRACE, iae); + logger.error(Constants.STACKTRACE, iae); ret.put("error", iae.getMessage()); return WebUtility.getResponse(ret, 500); } catch (Exception e) { - logger.error(STACKTRACE, e); + logger.error(Constants.STACKTRACE, e); ret.put("error", "An unexpected error happened. Please try again."); return WebUtility.getResponse(ret, 500); } @@ -1601,7 +1600,7 @@ public synchronized Response modifyLoginProperties(@PathParam("provider") String try { config = new PropertiesConfiguration(DIHelper.getInstance().getProperty("SOCIAL")); } catch (ConfigurationException e1) { - logger.error(STACKTRACE, e1); + logger.error(Constants.STACKTRACE, e1); Hashtable errorRet = new Hashtable<>(); errorRet.put("error", "An unexpected error happened trying to access the properties. Please try again or reach out to server admin."); @@ -1616,7 +1615,7 @@ public synchronized Response modifyLoginProperties(@PathParam("provider") String config.save(); loadSocialProperties(); } catch (ConfigurationException e1) { - logger.error(STACKTRACE, e1); + logger.error(Constants.STACKTRACE, e1); Hashtable errorRet = new Hashtable<>(); errorRet.put("error", "An unexpected error happened when saving the new login properties. Please try again or reach out to server admin."); @@ -1667,7 +1666,7 @@ private void setMainPageRedirect(@Context HttpServletRequest request, @Context H response.sendRedirect(socialData.getProperty("redirect")); } } catch (IOException e) { - logger.error(STACKTRACE, e); + logger.error(Constants.STACKTRACE, e); } } @@ -1773,7 +1772,7 @@ public StreamingOutput manCookie(@Context HttpServletRequest request, @Context H // dont allow user.addShare(sessionId); } catch (NoSuchAlgorithmException e) { - logger.error(STACKTRACE, e); + logger.error(Constants.STACKTRACE, e); } return WebUtility.getSO(outputHash); diff --git a/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java b/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java index 62af3cbbd..46223dc55 100644 --- a/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java +++ b/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java @@ -207,7 +207,7 @@ private void setInitParams(ServletRequest arg0) { // the token domains if(NoUserInSessionTrustedTokenFilter.trustedDomains == null) { - String [] trustedIPs = this.filterConfig.getInitParameter(NoUserInSessionTrustedTokenFilter.TRUSTED_TOKEN_DOMAIN).split(";"); + String [] trustedIPs = this.filterConfig.getInitParameter(NoUserInSessionTrustedTokenFilter.TRUSTED_TOKEN_DOMAIN).split(","); NoUserInSessionTrustedTokenFilter.trustedDomains = new Vector<>(); for(String trustedIP : trustedIPs) { NoUserInSessionTrustedTokenFilter.trustedDomains.add(trustedIP.toLowerCase()); From c92a8ad968d41345cdcb1997ab5db80dba18fcea Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 18 Nov 2020 01:57:05 +0000 Subject: [PATCH 0691/1906] UPDATE ::: Pushing cors with * by default git-svn-id: svn://107.170.10.188:8080/Monolith/dev@41364 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 6268cc647668ea2344165b4e4187328c6b399ecd --- WebContent/WEB-INF/web.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index 2f45ee9a4..60c46004a 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -54,7 +54,7 @@ org.apache.catalina.filters.CorsFilter cors.allowed.origins - + * cors.allowed.methods From fec2acf205e8c89770ff6b01a3bac31ab588087f Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 18 Nov 2020 02:08:56 +0000 Subject: [PATCH 0692/1906] BUGFIX ::: Turning support credentials to false git-svn-id: svn://107.170.10.188:8080/Monolith/dev@41365 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 6f2b2f49d9612f0f46256eef768992bc8162c12e --- WebContent/WEB-INF/web.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index 60c46004a..e555bd3cf 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -70,7 +70,7 @@ cors.support.credentials - true + false cors.preflight.maxage From 09e87d885069c0161f127dba8e4424ff07ed713a Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 18 Nov 2020 13:40:56 +0000 Subject: [PATCH 0693/1906] UPDATE ::: Removing duplicate filters git-svn-id: svn://107.170.10.188:8080/Monolith/dev@41374 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: d2790dd71075832804d6788c57d4c9a0c30f0cac --- WebContent/WEB-INF/web.xml | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index e555bd3cf..bf3fb17de 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -22,28 +22,6 @@ HeaderSecurityFilter org.apache.catalina.filters.HttpHeaderSecurityFilter - - HeaderSecurityFilter - /* - - - - SetCharacterEncoding - org.apache.catalina.filters.SetCharacterEncodingFilter - - encoding - UTF-8 - - - - SetCharacterEncoding - /* - - - HeaderSecurityFilter - org.apache.catalina.filters.HttpHeaderSecurityFilter - - HeaderSecurityFilter /* From 3048ab54afe99fe8fe5e5ccb2742a44f5824323d Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 18 Nov 2020 14:44:52 +0000 Subject: [PATCH 0694/1906] UPDATE ::: Increasing cors preflight maxage git-svn-id: svn://107.170.10.188:8080/Monolith/dev@41375 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 8764aaa69905e15d7c58950656ff288a483417d1 --- WebContent/WEB-INF/web.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index bf3fb17de..9bb7ea5ba 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -52,7 +52,7 @@ cors.preflight.maxage - 10 + 1800 From 1e31d37703aa40f0dcc0d9e7ceae4dbd9359e245 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 18 Nov 2020 14:59:17 +0000 Subject: [PATCH 0695/1906] UPDATE ::: Only allowing GET/POST/OPTIONS on cors git-svn-id: svn://107.170.10.188:8080/Monolith/dev@41376 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 848d6df324557e62d1872c5df63f4b693eb11ada --- WebContent/WEB-INF/web.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index 9bb7ea5ba..161e79639 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -36,7 +36,7 @@ cors.allowed.methods - GET,POST,HEAD,OPTIONS,PUT + GET,POST,OPTIONS cors.allowed.headers From 7cd0de0ba0922051fec8fbf6f22d68a056caa93a Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 18 Nov 2020 16:11:55 +0000 Subject: [PATCH 0696/1906] UPDATE ::: Adding the authorization key as well git-svn-id: svn://107.170.10.188:8080/Monolith/dev@41377 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: c87e6213db53fa96b38cc590bc220c10a599f534 --- WebContent/WEB-INF/web.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index 161e79639..934f48e4f 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -40,7 +40,7 @@ cors.allowed.headers - Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers + Authorization,Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers cors.exposed.headers @@ -57,7 +57,7 @@ CorsFilter - /api/* + /* From e02bc90c2fb0d8ecdc0febd136b4262ae68d31a5 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Sun, 22 Nov 2020 14:38:41 +0000 Subject: [PATCH 0697/1906] UPDATE ::: Exposing additional properties for anti click jacking git-svn-id: svn://107.170.10.188:8080/Monolith/dev@41464 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 958dbd7b84e9c02ad8a3cb5e598310f87bbc3839 --- WebContent/WEB-INF/web.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index 934f48e4f..ea64fae58 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -21,6 +21,18 @@ HeaderSecurityFilter org.apache.catalina.filters.HttpHeaderSecurityFilter + + hstsMaxAgeSeconds + 31536000 + + + antiClickJackingEnabled + true + + + antiClickJackingOption + SAMEORIGIN + HeaderSecurityFilter From 0709ec7ee52bac2c3dcf4194c1cd410bcf1c437a Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Sun, 22 Nov 2020 15:01:42 +0000 Subject: [PATCH 0698/1906] UPDATE ::: Adding the cookie header directly to allow for login through an iframe git-svn-id: svn://107.170.10.188:8080/Monolith/dev@41465 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 71c5f847b2ccb6a6d5733aa1ed264873f38abfb8 --- .../web/services/local/UserResource.java | 35 ++++++++----------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index ee32d95b0..4b8330605 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -86,6 +86,7 @@ import prerna.auth.utils.NativeUserSecurityUtils; import prerna.auth.utils.SecurityAdminUtils; import prerna.auth.utils.SecurityUpdateUtils; +import prerna.cluster.util.ClusterUtil; import prerna.ds.py.FilePyTranslator; import prerna.ds.py.PyTranslator; import prerna.ds.py.PyUtils; @@ -1639,28 +1640,34 @@ private void setMainPageRedirect(@Context HttpServletRequest request, @Context H * * @param response */ - private void setMainPageRedirect(@Context HttpServletRequest request, @Context HttpServletResponse response, + private void setMainPageRedirect(@Context HttpServletRequest request, + @Context HttpServletResponse response, String customRedirect) { // see if we have a location to redirect the user // if so, we will send them back to that URL // otherwise, we send them back to the FE HttpSession session = request.getSession(); + String contextPath = request.getContextPath(); + boolean useCustom = customRedirect != null && !customRedirect.isEmpty(); boolean endpoint = session.getAttribute(NoUserInSessionFilter.ENDPOINT_REDIRECT_KEY) != null; response.setStatus(302); try { - Cookie cookie = new Cookie(DBLoader.getSessionIdKey(), request.getSession().getId()); - cookie.setSecure(request.isSecure()); - cookie.setHttpOnly(true); - // cookie.setPath("/dev"); - response.addCookie(cookie); + // add the cookie to the header directly + // to allow for cross site login when embedded as iframe + String setCookieString = DBLoader.getSessionIdKey() + "=" + session.getId() + + "; Path=" + contextPath + + "; HttpOnly" + + ( (ClusterUtil.IS_CLUSTER || request.isSecure()) ? "; Secure; SameSite=None" : "") + ; + response.addHeader("Set-Cookie", setCookieString); if (useCustom) { - response.setHeader("redirect", customRedirect); + response.addHeader("redirect", customRedirect); String encodedCustomRedirect = Encode.forHtml(customRedirect); response.sendError(302, "Need to redirect to " + encodedCustomRedirect); } else if (endpoint) { String redirectUrl = session.getAttribute(NoUserInSessionFilter.ENDPOINT_REDIRECT_KEY) + ""; - response.setHeader("redirect", redirectUrl); + response.addHeader("redirect", redirectUrl); response.sendError(302, "Need to redirect to " + redirectUrl); } else { response.sendRedirect(socialData.getProperty("redirect")); @@ -1670,18 +1677,6 @@ private void setMainPageRedirect(@Context HttpServletRequest request, @Context H } } -// /** -// * Set the information in the JSON return after logging in -// * -// * @param token -// * @param ret -// */ -// private void setAccessTokenDetails(AccessToken token, Map ret) { -// ret.put("name", token.getName()); -// ret.put("email", token.getEmail()); -// ret.put("type", token.getToken_type()); -// } - ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// From 66a924ffbd09373b574c8c69f092ab0ee9b889ad Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 24 Nov 2020 21:33:29 +0000 Subject: [PATCH 0699/1906] UPDATE ::: Pushing just the insights database git-svn-id: svn://107.170.10.188:8080/Monolith/dev@41502 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: c1b5c4f4124accd688477fc7cb43cad3ef9473f4 --- .../services/local/auth/AdminInsightAuthorizationResource.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java index 540d8fd38..e4f1ff759 100644 --- a/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java @@ -120,10 +120,11 @@ public Response deleteAppInsights(@Context HttpServletRequest request, Multivalu } try { + ClusterUtil.reactorPullInsightsDB(appId); adminUtils.deleteAppInsights(appId, insightIds); // since modifying insight list // need to push to cloud storage - ClusterUtil.reactorPushApp(appId); + ClusterUtil.reactorPushInsightDB(appId); } catch (Exception e) { logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); From f24d44d0f43b235c2e914d3746db56d8943f4ac6 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 4 Dec 2020 17:45:37 +0000 Subject: [PATCH 0700/1906] UPDATE ::: Trying to fix issue with export dashboard when you have 2 different frames git-svn-id: svn://107.170.10.188:8080/Monolith/dev@41609 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 2426ca53908bdabe25ee0aed7e495b5c513c9bf5 --- .../semoss/web/services/local/RunInsight.java | 95 +++++++++++-------- 1 file changed, 56 insertions(+), 39 deletions(-) diff --git a/src/prerna/semoss/web/services/local/RunInsight.java b/src/prerna/semoss/web/services/local/RunInsight.java index d7f67477e..c5588cf70 100644 --- a/src/prerna/semoss/web/services/local/RunInsight.java +++ b/src/prerna/semoss/web/services/local/RunInsight.java @@ -1,13 +1,11 @@ package prerna.semoss.web.services.local; -import java.io.ByteArrayInputStream; import java.io.IOException; -import java.io.InputStreamReader; -import java.io.PushbackReader; import java.io.StringWriter; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.POST; @@ -21,21 +19,19 @@ import com.google.gson.stream.JsonWriter; +import prerna.algorithm.api.ITableDataFrame; import prerna.om.Insight; import prerna.om.InsightPanel; import prerna.om.InsightSheet; import prerna.om.ThreadStore; -import prerna.sablecc2.PixelPreProcessor; import prerna.sablecc2.PixelRunner; import prerna.sablecc2.PixelStreamUtility; -import prerna.sablecc2.lexer.Lexer; -import prerna.sablecc2.lexer.LexerException; -import prerna.sablecc2.node.Start; -import prerna.sablecc2.parser.Parser; -import prerna.sablecc2.parser.ParserException; +import prerna.sablecc2.PixelUtility; +import prerna.sablecc2.om.PixelDataType; +import prerna.sablecc2.om.PixelOperationType; +import prerna.sablecc2.om.VarStore; +import prerna.sablecc2.om.nounmeta.NounMetadata; import prerna.sablecc2.reactor.job.JobReactor; -import prerna.sablecc2.translations.OptimizeRecipeTranslation; -import prerna.util.Constants; import prerna.util.gson.InsightPanelAdapter; import prerna.util.gson.InsightSheetAdapter; import prerna.util.insight.InsightUtility; @@ -68,9 +64,8 @@ public Response getInsightData(@Context HttpServletRequest request) { @Path("/getInsightState") @Produces("application/json") public Response recreateInsightState(@Context HttpServletRequest request) { - List recipe = in.getPixelList().getPixelRecipe(); + List recipe = PixelUtility.getCachedInsightRecipe(in); - OptimizeRecipeTranslation opTrans = getOptimizedRecipe(recipe); Insight rerunInsight = new Insight(); rerunInsight.setVarStore(in.getVarStore()); rerunInsight.setUser(in.getUser()); @@ -109,38 +104,60 @@ public Response recreateInsightState(@Context HttpServletRequest request) { e.printStackTrace(); } - PixelRunner pixelRunner = rerunInsight.runPixel(opTrans.getCachedPixelRecipeSteps()); + PixelRunner pixelRunner = rerunInsight.runPixel(recipe); + // add all the frame headers to the payload + try { + VarStore vStore = in.getVarStore(); + Set keys = vStore.getFrameKeys(); + for(String k : keys) { + NounMetadata noun = vStore.get(k); + PixelDataType type = noun.getNounType(); + if(type == PixelDataType.FRAME) { + try { + ITableDataFrame frame = (ITableDataFrame) noun.getValue(); + pixelRunner.addResult(0, "CACHED_FRAME_HEADERS", + new NounMetadata(frame.getFrameHeadersObject(), PixelDataType.CUSTOM_DATA_STRUCTURE, PixelOperationType.FRAME_HEADERS)); + } catch(Exception e) { + e.printStackTrace(); + // ignore + } + } + } + } catch (Exception e) { + e.printStackTrace(); + } + return Response.status(200).entity(PixelStreamUtility.collectPixelData(pixelRunner)) .header("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0, post-check=0, pre-check=0") .header("Pragma", "no-cache") .build(); } - private OptimizeRecipeTranslation getOptimizedRecipe(List recipe) { - OptimizeRecipeTranslation translation = new OptimizeRecipeTranslation(); - for (int i = 0; i < recipe.size(); i++) { - String expression = recipe.get(i); - // fill in the encodedToOriginal with map for the current expression - expression = PixelPreProcessor.preProcessPixel(expression.trim(), translation.encodingList, translation.encodedToOriginal); - try { - Parser p = new Parser( - new Lexer( - new PushbackReader( - new InputStreamReader( - new ByteArrayInputStream(expression.getBytes("UTF-8")), "UTF-8"), expression.length()))); - // parsing the pixel - this process also determines if expression is syntactically correct - Start tree = p.parse(); - // apply the translation - // when we apply the translation, we will change encoded expressions back to their original form - tree.apply(translation); - // reset translation.encodedToOriginal for each expression - translation.encodedToOriginal = new HashMap(); - } catch (ParserException | LexerException | IOException e) { - logger.error(Constants.STACKTRACE, e); - } - } - return translation; - } +// private OptimizeRecipeTranslation getOptimizedRecipe(List recipe) { +// OptimizeRecipeTranslation translation = new OptimizeRecipeTranslation(); +// for (int i = 0; i < recipe.size(); i++) { +// String expression = recipe.get(i); +// // fill in the encodedToOriginal with map for the current expression +// expression = PixelPreProcessor.preProcessPixel(expression.trim(), translation.encodingList, translation.encodedToOriginal); +// try { +// Parser p = new Parser( +// new Lexer( +// new PushbackReader( +// new InputStreamReader( +// new ByteArrayInputStream(expression.getBytes("UTF-8")), "UTF-8"), expression.length()))); +// // parsing the pixel - this process also determines if expression is syntactically correct +// Start tree = p.parse(); +// // apply the translation +// // when we apply the translation, we will change encoded expressions back to their original form +// tree.apply(translation); +// // reset translation.encodedToOriginal for each expression +// translation.encodedToOriginal = new HashMap(); +// } catch (ParserException | LexerException | IOException e) { +// logger.error(Constants.STACKTRACE, e); +// } +// } +// return translation; +// } /** * Utility method to execute the pixel on the insight From 15727eff81bdf2a3e9721a6b18db4e1361be2285 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 4 Dec 2020 19:46:39 +0000 Subject: [PATCH 0701/1906] UPDATE ::: Not dropping the log messages for certain calls where we call runPixel during an existing runPixel. This is because the same insight id is used for the job ids git-svn-id: svn://107.170.10.188:8080/Monolith/dev@41612 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: ea063847e004650342e4d13deb1b0de4439ac3b4 --- .../semoss/web/services/local/NameServer.java | 27 +++++++++++++++---- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index 4b6910cfa..69d4600da 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -275,7 +275,8 @@ public Response runPixelSync(@Context HttpServletRequest request) { String sessionId = null; User user = null; Insight insight = null; - + boolean dropLogging = true; + boolean securityEnabled = AbstractSecurityUtils.securityEnabled(); // If security is enabled try to get an existing session. // Otherwise get a session with the default user. @@ -328,7 +329,15 @@ public Response runPixelSync(@Context HttpServletRequest request) { // set the user insight.setUser(user); - return runPixelJob(user, insight, expression, jobId, insightId, sessionId); + // are we running runPixel in runPixel on the same insight? + { + String logStr = request.getParameter("dropLogging"); + if(logStr != null) { + dropLogging = Boolean.parseBoolean(logStr); + } + } + + return runPixelJob(user, insight, expression, jobId, insightId, sessionId, dropLogging); } @@ -391,7 +400,8 @@ public Response getPixelPipelinePlan(@Context HttpServletRequest request) { * @param sessionId * @return */ - private Response runPixelJob(User user, Insight insight, String expression, String jobId, String insightId, String sessionId) { + private Response runPixelJob(User user, Insight insight, String expression, String jobId, + String insightId, String sessionId, boolean dropLogging) { JobManager manager = JobManager.getManager(); JobThread jt = manager.makeJob(insightId); jobId = jt.getJobId(); @@ -418,8 +428,15 @@ private Response runPixelJob(User user, Insight insight, String expression, Stri .header("Pragma", "no-cache") .build(); } finally { - jt.setStatus(JobStatus.COMPLETE); - manager.removeJob(jobId); + // there are times when we spin up + // other runPixel requests on the same + // insight but don't want to drop the master insight + // console logging + // example is ExportToExcel grids + if(dropLogging) { + jt.setStatus(JobStatus.COMPLETE); + manager.removeJob(jobId); + } } } From 1c77ca2ea61abb03e0a002c53887cf664ef075c7 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 7 Dec 2020 18:22:26 +0000 Subject: [PATCH 0702/1906] UPDATE ::: Pushing updates to allow updating information when, for example, you add a user but the certificate has a more accurate name/email git-svn-id: svn://107.170.10.188:8080/Monolith/dev@41640 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 7093de36ea2ab2d659f496f9ebba3f3769646276 --- src/prerna/web/conf/CACFilter.java | 37 +++++++++++++++++++++--------- src/prerna/web/conf/PIVFilter.java | 17 +++++++++++++- 2 files changed, 42 insertions(+), 12 deletions(-) diff --git a/src/prerna/web/conf/CACFilter.java b/src/prerna/web/conf/CACFilter.java index f3b86b71f..6ccdbc436 100644 --- a/src/prerna/web/conf/CACFilter.java +++ b/src/prerna/web/conf/CACFilter.java @@ -44,18 +44,19 @@ public class CACFilter implements Filter { private static final Logger logger = LogManager.getLogger(CACFilter.class); - private static final String STACKTRACE = "StackTrace: "; // filter init params private static final String AUTO_ADD = "autoAdd"; + private static final String UPDATE_USER_INFO = "updateUserInfo"; private static final String COUNT_USER_ENTRY = "countUserEntry"; private static final String COUNT_USER_ENTRY_DATABASE = "countUserEntryDb"; private static final String LOG_USER_INFO = "logUserInfo"; private static final String LOG_USER_INFO_PATH = "logUserInfoPath"; private static final String LOG_USER_INFO_SEP = "logUserInfoSep"; - + // realization of init params private static Boolean autoAdd = null; + private static Boolean updateUser = null; private static CACTrackingUtil tracker = null; private static UserFileLogUtil userLogger = null; @@ -158,7 +159,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 } } } catch (CertificateParsingException e) { - logger.error(STACKTRACE, e); + logger.error(Constants.STACKTRACE, e); } if(email != null) { @@ -176,7 +177,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 } // end rdn loop } catch (InvalidNameException e) { logger.error("ERROR WITH PARSING CAC INFORMATION!"); - logger.error(STACKTRACE, e); + logger.error(Constants.STACKTRACE, e); } } @@ -192,6 +193,12 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 if(CACFilter.autoAdd) { SecurityUpdateUtils.addOAuthUser(token); } + // do we need to update credentials? + // might be useful for when we add users + // but the cert has different values we want to use + if(CACFilter.updateUser) { + SecurityUpdateUtils.updateOAuthUser(token); + } // new user has entered! // do we need to count? @@ -235,6 +242,14 @@ private void setInitParams(ServletRequest arg0) { CACFilter.autoAdd = true; } + String updateUserStr = CACFilter.filterConfig.getInitParameter(UPDATE_USER_INFO); + if(updateUserStr != null) { + CACFilter.updateUser = Boolean.parseBoolean(updateUserStr); + } else { + // Default value is true + CACFilter.updateUser = false; + } + boolean logUsers = false; String logUserInfoStr = CACFilter.filterConfig.getInitParameter(LOG_USER_INFO); if(logUserInfoStr != null) { @@ -312,7 +327,7 @@ private void updateCacUsersStorage(String previousId, String newId) { try { securityDb.insertData(updateQuery); } catch (SQLException e) { - logger.error(STACKTRACE, e); + logger.error(Constants.STACKTRACE, e); } // need to update all the places the user id is used @@ -320,7 +335,7 @@ private void updateCacUsersStorage(String previousId, String newId) { try { securityDb.insertData(updateQuery); } catch (SQLException e) { - logger.error(STACKTRACE, e); + logger.error(Constants.STACKTRACE, e); } // need to update all the places the user id is used @@ -328,11 +343,11 @@ private void updateCacUsersStorage(String previousId, String newId) { try { securityDb.insertData(updateQuery); } catch (SQLException e) { - logger.error(STACKTRACE, e); + logger.error(Constants.STACKTRACE, e); } } } catch (Exception e1) { - logger.error(STACKTRACE, e1); + logger.error(Constants.STACKTRACE, e1); } finally { if(wrapper != null) { wrapper.cleanUp(); @@ -363,7 +378,7 @@ private void updateCacUsersStorage(String previousId, String newId) { formEngine.insertData("UPDATE FORMS_USER_ACCESS SET EMAIL = USER_ID;"); } } catch (Exception e) { - logger.error(STACKTRACE, e); + logger.error(Constants.STACKTRACE, e); } finally { if(requireFormUpdateWrapper != null) { requireFormUpdateWrapper.cleanUp(); @@ -375,12 +390,12 @@ private void updateCacUsersStorage(String previousId, String newId) { try { formEngine.insertData(updateQuery); } catch (SQLException e) { - logger.error(STACKTRACE, e); + logger.error(Constants.STACKTRACE, e); } } } catch (Exception e1) { - logger.error(STACKTRACE, e1); + logger.error(Constants.STACKTRACE, e1); } finally { if(wrapper != null) { wrapper.cleanUp(); diff --git a/src/prerna/web/conf/PIVFilter.java b/src/prerna/web/conf/PIVFilter.java index 351542dbc..f28a4db64 100644 --- a/src/prerna/web/conf/PIVFilter.java +++ b/src/prerna/web/conf/PIVFilter.java @@ -40,6 +40,7 @@ public class PIVFilter implements Filter { // filter init params private static final String AUTO_ADD = "autoAdd"; + private static final String UPDATE_USER_INFO = "updateUserInfo"; private static final String COUNT_USER_ENTRY = "countUserEntry"; private static final String COUNT_USER_ENTRY_DATABASE = "countUserEntryDb"; private static final String LOG_USER_INFO = "logUserInfo"; @@ -48,12 +49,12 @@ public class PIVFilter implements Filter { // realization of init params private static Boolean autoAdd = null; + private static Boolean updateUser = null; private static CACTrackingUtil tracker = null; private static UserFileLogUtil userLogger = null; private static FilterConfig filterConfig; - // TODO >>>timb: WORKSPACE - call logic to pull workspace here, or make into a reactor @Override public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { setInitParams(arg0); @@ -151,6 +152,12 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 if(PIVFilter.autoAdd) { SecurityUpdateUtils.addOAuthUser(token); } + // do we need to update credentials? + // might be useful for when we add users + // but the cert has different values we want to use + if(PIVFilter.updateUser) { + SecurityUpdateUtils.updateOAuthUser(token); + } // new user has entered! // do we need to count? @@ -194,6 +201,14 @@ private void setInitParams(ServletRequest arg0) { PIVFilter.autoAdd = true; } + String updateUserStr = PIVFilter.filterConfig.getInitParameter(UPDATE_USER_INFO); + if(updateUserStr != null) { + PIVFilter.updateUser = Boolean.parseBoolean(updateUserStr); + } else { + // Default value is true + PIVFilter.updateUser = false; + } + boolean logUsers = false; String logUserInfoStr = PIVFilter.filterConfig.getInitParameter(LOG_USER_INFO); if(logUserInfoStr != null) { From d36d3e8a6f2b7dbf3217eb343eee2e0f16e85520 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 7 Dec 2020 18:26:38 +0000 Subject: [PATCH 0703/1906] UPDATE ::: Exposing additional parameters for updating the user information from the token git-svn-id: svn://107.170.10.188:8080/Monolith/dev@41642 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 47a0e2cdf1e82e5c313e56b6b567e31a07202840 --- WebContent/WEB-INF/web.xml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index ea64fae58..d4bac48d7 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -123,6 +123,10 @@ autoAdd true + + updateUserInfo + false + countUserEntry false @@ -159,6 +163,10 @@ autoAdd true + + updateUserInfo + false + countUserEntry false From 423fac7b83d9585948f817c7057ac8ea36032f08 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 7 Dec 2020 18:36:12 +0000 Subject: [PATCH 0704/1906] UPDATE ::: Moving to constants class instead of redefining parameter again git-svn-id: svn://107.170.10.188:8080/Monolith/dev@41643 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 2c05e26c82fdb423b53646c437352b0a8e300342 --- src/prerna/web/conf/PIVFilter.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/prerna/web/conf/PIVFilter.java b/src/prerna/web/conf/PIVFilter.java index f28a4db64..2f20c2e03 100644 --- a/src/prerna/web/conf/PIVFilter.java +++ b/src/prerna/web/conf/PIVFilter.java @@ -36,7 +36,6 @@ public class PIVFilter implements Filter { private static final Logger logger = LogManager.getLogger(PIVFilter.class); - private static final String STACKTRACE = "StackTrace: "; // filter init params private static final String AUTO_ADD = "autoAdd"; @@ -109,7 +108,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 } } } catch (CertificateParsingException e) { - logger.error(STACKTRACE, e); + logger.error(Constants.STACKTRACE, e); } } // CN for name @@ -136,7 +135,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 } // end rdn loop } catch (InvalidNameException e) { logger.error("ERROR WITH PARSING CAC INFORMATION!"); - logger.error(STACKTRACE,e); + logger.error(Constants.STACKTRACE,e); } } From 299b171cf9d77087e76a1487a71c7c4aaec345e3 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 8 Dec 2020 15:40:21 +0000 Subject: [PATCH 0705/1906] UPDATE ::: Adding login through siteminder git-svn-id: svn://107.170.10.188:8080/Monolith/dev@41660 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 8f39dc465e23c8929bc2012bebe620b6fcdece0f --- .../web/services/local/UserResource.java | 85 +++++++++++++++++++ 1 file changed, 85 insertions(+) diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index 4b8330605..78b96b379 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -914,6 +914,91 @@ private String getMSRedirect(HttpServletRequest request) throws UnsupportedEncod return redirectUrl; } + + /** + * Logs user in through siteminder + */ + @GET + @Produces("application/json") + @Path("/login/siteminder") + public Response loginSiteminder(@Context HttpServletRequest request, @Context HttpServletResponse response) + throws IOException { + /* + * Try to log in the user + * If they are not logged in + * Redirect the FE + */ + + User userObj = (User) request.getSession().getAttribute(Constants.SESSION_USER); + String queryString = request.getQueryString(); + if (queryString != null && queryString.contains("code=")) { + if (userObj == null || ((User) userObj).getAccessToken(AuthProvider.SITEMINDER) == null) { + String[] outputs = AbstractHttpHelper.getCodes(queryString); + + String prefix = "siteminder_"; + String clientId = socialData.getProperty(prefix + "client_id"); + String clientSecret = socialData.getProperty(prefix + "secret_key"); + String redirectUri = socialData.getProperty(prefix + "redirect_uri"); + String tenant = socialData.getProperty(prefix + "tenant"); + String scope = socialData.getProperty(prefix + "scope"); + + logger.debug(">> " + Utility.cleanLogString(request.getQueryString())); + + Hashtable params = new Hashtable(); + params.put("client_id", clientId); + params.put("scope", scope); + params.put("redirect_uri", redirectUri); + params.put("code", outputs[0]); + params.put("grant_type", "authorization_code"); + params.put("client_secret", clientSecret); + + String url = "https://login.microsoftonline.com/" + tenant + "/oauth2/v2.0/token"; + + AccessToken accessToken = AbstractHttpHelper.getAccessToken(url, params, true, true); + if (accessToken == null) { + // not authenticated + response.setStatus(302); + response.sendRedirect(getSiteminderRedirect(request)); + return null; + } + + accessToken.setProvider(AuthProvider.SITEMINDER); + MSProfile.fillAccessToken(accessToken, null); + addAccessToken(accessToken, request); + + logger.debug("Access Token is.. " + accessToken.getAccess_token()); + } + } + + // grab the user again + userObj = (User) request.getSession().getAttribute(Constants.SESSION_USER); + if (userObj == null || userObj.getAccessToken(AuthProvider.SITEMINDER) == null) { + // not authenticated + response.setStatus(302); + response.sendRedirect(getSiteminderRedirect(request)); + return null; + } + + setMainPageRedirect(request, response); + return null; + } + + private String getSiteminderRedirect(HttpServletRequest request) throws UnsupportedEncodingException { + String prefix = "siteminder_"; + String clientId = socialData.getProperty(prefix + "client_id"); + String redirectUri = socialData.getProperty(prefix + "redirect_uri"); + String tenant = socialData.getProperty(prefix + "tenant"); + String scope = socialData.getProperty(prefix + "scope"); // need to set this up and reuse + + String state = UUID.randomUUID().toString(); + String redirectUrl = "https://login.microsoftonline.com/" + tenant + "/oauth2/v2.0/authorize?" + "client_id=" + + clientId + "&response_type=code" + "&redirect_uri=" + URLEncoder.encode(redirectUri, "UTF-8") + + "&response_mode=query" + "&scope=" + URLEncoder.encode(scope) + "&state=" + state; + + logger.debug("Sending redirect.. " + Utility.cleanLogString(redirectUrl)); + + return redirectUrl; + } /** * Logs user in through drop box From fe9716cff95740e56a5e73aef17136def18c4362 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 9 Dec 2020 17:46:20 +0000 Subject: [PATCH 0706/1906] BUGFIX ::: Only closing r/py on the session invalidation instead of also on logout since logout calls the invalidation and we get a conflict where we restart r just to close it again git-svn-id: svn://107.170.10.188:8080/Monolith/dev@41678 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: f3f93947b9ce667c76d2e76b81b53d846e31daf6 --- .../web/services/local/UserResource.java | 74 ++++--------------- src/prerna/web/conf/UserSessionLoader.java | 52 ++++++------- 2 files changed, 37 insertions(+), 89 deletions(-) diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index 78b96b379..243e1bbed 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -45,9 +45,6 @@ import java.util.TreeMap; import java.util.UUID; import java.util.Vector; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; @@ -87,11 +84,6 @@ import prerna.auth.utils.SecurityAdminUtils; import prerna.auth.utils.SecurityUpdateUtils; import prerna.cluster.util.ClusterUtil; -import prerna.ds.py.FilePyTranslator; -import prerna.ds.py.PyTranslator; -import prerna.ds.py.PyUtils; -import prerna.ds.py.TCPPyTranslator; -import prerna.engine.impl.r.IRUserConnection; import prerna.io.connector.IConnectorIOp; import prerna.io.connector.google.GoogleEntityResolver; import prerna.io.connector.google.GoogleFileRetriever; @@ -102,7 +94,6 @@ import prerna.io.connector.surveymonkey.MonkeyProfile; import prerna.io.connector.twitter.TwitterSearcher; import prerna.om.NLPDocumentInput; -import prerna.pyserve.NettyClient; import prerna.security.AbstractHttpHelper; import prerna.util.BeanFiller; import prerna.util.Constants; @@ -225,17 +216,17 @@ public Response logout(@PathParam("provider") String provider, @Context HttpServ HttpSession session = request.getSession(); User thisUser = (User) session.getAttribute(Constants.SESSION_USER); - // log the logout - if(thisUser != null) { - // log the user login - logger.info(ResourceUtility.getLogMessage(request, session, User.getSingleLogginName(thisUser), "is logging out of provider " + provider)); - } else { - logger.info(ResourceUtility.getLogMessage(request, session, "Unknown user", "is logging out of provider " + provider)); + if(thisUser == null) { + Map ret = new Hashtable<>(); + ret.put("success", false); + ret.put("errorMessage", "No user is currently logged in the session"); + return WebUtility.getResponse(ret, 400); } + // log the user logout + logger.info(ResourceUtility.getLogMessage(request, session, User.getSingleLogginName(thisUser), "is logging out of provider " + provider)); + if (provider.equalsIgnoreCase("ALL")) { - // remove the user from session call it a day - request.getSession().removeAttribute(Constants.SESSION_USER); removed = true; noUser = true; } else { @@ -264,51 +255,13 @@ public Response logout(@PathParam("provider") String provider, @Context HttpServ } if(noUser) { - // stop R - if (thisUser != null) { - IRUserConnection rserve = thisUser.getRcon(); - if (rserve != null) { - ExecutorService executor = Executors.newSingleThreadExecutor(); - try { - executor.submit(new Callable() { - @Override - public Void call() throws Exception { - try { - rserve.stopR(); - } catch (Exception e) { - logger.warn("Unable to stop R."); - } - return null; - } - }); - } finally { - executor.shutdown(); - } - } - } - - // stop python too - if (PyUtils.pyEnabled()) { - PyTranslator pyt = thisUser.getPyTranslator(false); - - if (pyt instanceof prerna.ds.py.PyTranslator) - PyUtils.getInstance().killPyThread(pyt.getPy()); - if (pyt instanceof FilePyTranslator && thisUser != null) - PyUtils.getInstance().killTempTupleSpace(thisUser); - if (pyt instanceof TCPPyTranslator) { - NettyClient nc = thisUser.getPyServe(); - String dir = thisUser.pyTupleSpace; - nc.stopPyServe(dir); - } - } - // if there are no users and there is security // redirect the user // and invalidate the session + // session invalidation will go to UserSessionLoader + // which will close R and Python on the user object if (AbstractSecurityUtils.securityEnabled()) { logger.info(ResourceUtility.getLogMessage(request, session, User.getSingleLogginName(thisUser), "has logged out from all providers in the session")); - logger.info("Removing user object from session"); - session.removeAttribute(Constants.SESSION_USER); // well, you have logged out and we always require a login // so i will redirect you response.setStatus(302); @@ -366,11 +319,10 @@ public Void call() throws Exception { } } } - - // invalidate the session - session.invalidate(); - return null; } + // invalidate the session + session.invalidate(); + return null; } Map ret = new Hashtable<>(); diff --git a/src/prerna/web/conf/UserSessionLoader.java b/src/prerna/web/conf/UserSessionLoader.java index 416fb3d4f..87560c90e 100644 --- a/src/prerna/web/conf/UserSessionLoader.java +++ b/src/prerna/web/conf/UserSessionLoader.java @@ -20,23 +20,25 @@ import prerna.ds.py.FilePyTranslator; import prerna.ds.py.PyTranslator; import prerna.ds.py.PyUtils; +import prerna.ds.py.TCPPyTranslator; import prerna.engine.impl.r.IRUserConnection; import prerna.om.Insight; import prerna.om.InsightStore; +import prerna.pyserve.NettyClient; import prerna.util.Constants; import prerna.util.DIHelper; import prerna.util.insight.InsightUtility; @WebListener public class UserSessionLoader implements HttpSessionListener { - + private static final Logger logger = LogManager.getLogger(UserSessionLoader.class.getName()); private static final String DIR_SEPARATOR = java.nio.file.FileSystems.getDefault().getSeparator(); public void sessionCreated(HttpSessionEvent sessionEvent) { } - + public void sessionDestroyed(HttpSessionEvent sessionEvent) { HttpSession session = sessionEvent.getSession(); String sessionId = session.getId(); @@ -48,7 +50,7 @@ public void sessionDestroyed(HttpSessionEvent sessionEvent) { } // back up the workspace and asset apps SyncUserAppsThread.execute(session); - + // clear up insight store InsightStore inStore = InsightStore.getInstance(); Set insightIDs = inStore.getInsightIDsForSession(sessionId); @@ -64,19 +66,19 @@ public void sessionDestroyed(HttpSessionEvent sessionEvent) { logger.info(sessionId + " >>> Dropped insight " + insightId); } logger.info(sessionId + " >>> Successfully removed insight information from session"); - + // clear the current session store insightIDs.removeAll(copy); } - + String sessionStorage = DIHelper.getInstance().getProperty(Constants.INSIGHT_CACHE_DIR) + DIR_SEPARATOR + sessionId; ICache.deleteFolder(sessionStorage); - + // drop the r thread try { if (thisUser != null) { IRUserConnection rserve = thisUser.getRcon(); - if (rserve != null) { + if (rserve != null && !rserve.isStopped()) { logger.info(sessionId + " >>> Dropping user r serve"); ExecutorService executor = Executors.newSingleThreadExecutor(); try { @@ -100,29 +102,23 @@ public Void call() throws Exception { } catch(Exception e) { logger.error(Constants.STACKTRACE, e); } - - // now drop the py thread - if(PyUtils.pyEnabled()) { - try { - PyTranslator pyThread = (PyTranslator) session.getAttribute(Constants.PYTHON); - if(pyThread != null ) { - logger.info(sessionId + " >>> Found python thread to drop"); - if(!(pyThread instanceof FilePyTranslator)) { - if(pyThread.getPy() != null) { - PyUtils.getInstance().killPyThread(pyThread.getPy()); - } - } else { - User user = (User)session.getAttribute(Constants.SESSION_USER); - if(user != null) { - PyUtils.getInstance().killTempTupleSpace(user); - } - } - logger.info(sessionId + " >>> Successfully dropped python thread"); + + // stop python too + if (PyUtils.pyEnabled()) { + if(thisUser != null) { + PyTranslator pyt = thisUser.getPyTranslator(false); + + if (pyt instanceof prerna.ds.py.PyTranslator) + PyUtils.getInstance().killPyThread(pyt.getPy()); + if (pyt instanceof FilePyTranslator && thisUser != null) + PyUtils.getInstance().killTempTupleSpace(thisUser); + if (pyt instanceof TCPPyTranslator) { + NettyClient nc = thisUser.getPyServe(); + String dir = thisUser.pyTupleSpace; + nc.stopPyServe(dir); } - } catch(Exception e) { - logger.error(Constants.STACKTRACE, e); } } } - + } \ No newline at end of file From 359fdd02aab54535fc1af73ec502d78bcd6629d4 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 9 Dec 2020 22:36:57 +0000 Subject: [PATCH 0707/1906] UPDATE ::: Moving some of the rest endpoints and consolidating into the intended/proper resources git-svn-id: svn://107.170.10.188:8080/Monolith/dev@41691 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: a031a738153ca88737c2216fa8857d64bf366941 --- .../semoss/web/app/MonolithApplication.java | 5 +- .../services/local/AuthorizationResource.java | 170 +----------------- .../auth/AdminUserAuthorizationResource.java | 105 ++++++++++- 3 files changed, 111 insertions(+), 169 deletions(-) diff --git a/src/prerna/semoss/web/app/MonolithApplication.java b/src/prerna/semoss/web/app/MonolithApplication.java index 29e95ebd2..cadf9a855 100644 --- a/src/prerna/semoss/web/app/MonolithApplication.java +++ b/src/prerna/semoss/web/app/MonolithApplication.java @@ -46,6 +46,7 @@ import prerna.semoss.web.services.local.UserResource; import prerna.semoss.web.services.local.auth.AdminAppAuthorizationResource; import prerna.semoss.web.services.local.auth.AdminInsightAuthorizationResource; +import prerna.semoss.web.services.local.auth.AdminUserAuthorizationResource; import prerna.semoss.web.services.local.auth.AppAuthorizationResource; import prerna.semoss.web.services.local.auth.InsightAuthorizationResource; import prerna.upload.FileUploader; @@ -66,9 +67,11 @@ public MonolithApplication() { // authorization resources singletons.add(new AuthorizationResource()); singletons.add(new AppAuthorizationResource()); - singletons.add(new AdminAppAuthorizationResource()); singletons.add(new InsightAuthorizationResource()); + // admin authorization + singletons.add(new AdminAppAuthorizationResource()); singletons.add(new AdminInsightAuthorizationResource()); + singletons.add(new AdminUserAuthorizationResource()); // insight execution singletons.add(new ExecuteInsightResource()); singletons.add(new ShareInsightResource()); diff --git a/src/prerna/semoss/web/services/local/AuthorizationResource.java b/src/prerna/semoss/web/services/local/AuthorizationResource.java index bb382334c..99de0ed59 100644 --- a/src/prerna/semoss/web/services/local/AuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/AuthorizationResource.java @@ -28,7 +28,6 @@ package prerna.semoss.web.services.local; import java.util.HashMap; -import java.util.Hashtable; import java.util.List; import java.util.Map; @@ -47,11 +46,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import com.google.gson.Gson; - import prerna.auth.User; -import prerna.auth.utils.AbstractSecurityUtils; -import prerna.auth.utils.SecurityAdminUtils; import prerna.auth.utils.SecurityQueryUtils; import prerna.auth.utils.SecurityUpdateUtils; import prerna.util.Constants; @@ -61,26 +56,9 @@ public class AuthorizationResource { private static final Logger logger = LogManager.getLogger(AuthorizationResource.class); - private static final String STACKTRACE = "StackTrace: "; @Context protected ServletContext context; - @GET - @Path("/admin/isAdminUser") - public Response isAdminUser(@Context HttpServletRequest request) { - User user = null; - try { - user = ResourceUtility.getUser(request); - } catch (IllegalAccessException e) { - Map errorMap = new HashMap<>(); - errorMap.put("error", "User session is invalid"); - return WebUtility.getResponse(errorMap, 401); - } - - boolean isAdmin = SecurityAdminUtils.userIsAdmin(user); - return WebUtility.getResponse(isAdmin, 200); - } - @GET @Produces("application/json") @Path("searchForUser") @@ -89,146 +67,6 @@ public StreamingOutput searchForUser(@Context HttpServletRequest request, @Query return WebUtility.getSO(ret); } - @POST - @Produces("application/json") - @Path("/admin/registerUser") - public Response registerUser(@Context HttpServletRequest request, MultivaluedMap form) { - Hashtable errorRet = new Hashtable<>(); - boolean success = false; - try{ - User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); - - String newUserId = form.getFirst("userId"); - String name = form.getFirst("name"); - String email = form.getFirst("email"); - // validate email & password - if (email != null && !email.isEmpty()) { - String emailError = AbstractSecurityUtils.validEmail(email); - if (!emailError.isEmpty()) { - throw new IllegalArgumentException(emailError); - } - } - String password = form.getFirst("password"); - if (password != null && !password.isEmpty()) { - String passwordError = AbstractSecurityUtils.validPassword(password); - if (!passwordError.isEmpty()) { - throw new IllegalArgumentException(passwordError); - } - } - String type = form.getFirst("type"); - Boolean newUserAdmin = Boolean.parseBoolean(form.getFirst("admin")); - - if(SecurityAdminUtils.userIsAdmin(user)){ - success = SecurityUpdateUtils.registerUser(newUserId, name, email, password, type, newUserAdmin, !AbstractSecurityUtils.adminSetPublisher()); - } else { - errorRet.put("error", "The user doesn't have the permissions to perform this action."); - return WebUtility.getResponse(errorRet, 400); - } - } catch (IllegalArgumentException e){ - logger.error(STACKTRACE, e); - errorRet.put("error", e.getMessage()); - return WebUtility.getResponse(errorRet, 400); - } catch (Exception e){ - logger.error(STACKTRACE, e); - errorRet.put("error", "An unexpected error happened. Please try again."); - return WebUtility.getResponse(errorRet, 500); - } - return WebUtility.getResponse(success, 200); - } - - /** - * Edit user properties - * @param request - * @param form - * @return true if the edition was performed - */ - @POST - @Path("/editUser") - @Produces("application/json") - public Response editUser(@Context HttpServletRequest request, MultivaluedMap form) { - User user = null; - try { - user = ResourceUtility.getUser(request); - } catch (IllegalAccessException e) { - Map errorMap = new HashMap<>(); - errorMap.put("error", "User session is invalid"); - return WebUtility.getResponse(errorMap, 401); - } - - SecurityAdminUtils adminUtils = SecurityAdminUtils.getInstance(user); - if(adminUtils == null) { - Map retMap = new Hashtable<>(); - retMap.put("error", "User does not have admin priviledges"); - return WebUtility.getResponse(retMap, 400); - } - - Gson gson = new Gson(); - Map userInfo = gson.fromJson(form.getFirst("user"), Map.class); - boolean ret = false; - try { - ret = adminUtils.editUser(userInfo); - } catch(IllegalArgumentException e) { - Map retMap = new Hashtable<>(); - retMap.put("error", e.getMessage()); - return WebUtility.getResponse(retMap, 400); - } - if(!ret) { - Map retMap = new Hashtable<>(); - retMap.put("error", "Unknown error occured with updating user. Please try again."); - return WebUtility.getResponse(retMap, 400); - } - return WebUtility.getResponse(ret, 200); - } - - @POST - @Produces("application/json") - @Path("/admin/deleteUser") - public Response deleteUser(@Context HttpServletRequest request, MultivaluedMap form) { - User user = null; - try { - user = ResourceUtility.getUser(request); - } catch (IllegalAccessException e) { - Map errorMap = new HashMap<>(); - errorMap.put("error", "User session is invalid"); - return WebUtility.getResponse(errorMap, 401); - } - - SecurityAdminUtils adminUtils = SecurityAdminUtils.getInstance(user); - if(adminUtils == null) { - Map retMap = new Hashtable<>(); - retMap.put("error", "User does not have admin priviledges"); - return WebUtility.getResponse(retMap, 400); - } - - String userToDelete = form.getFirst("userId"); - boolean success = adminUtils.deleteUser(userToDelete); - return WebUtility.getResponse(success, 200); - } - - @GET - @Path("/getAllDbUsers") - @Produces("application/json") - public Response getAllUsers(@Context HttpServletRequest request) { - User user = null; - try { - user = ResourceUtility.getUser(request); - } catch (IllegalAccessException e) { - Map errorMap = new HashMap<>(); - errorMap.put("error", "User session is invalid"); - return WebUtility.getResponse(errorMap, 401); - } - - SecurityAdminUtils adminUtils = SecurityAdminUtils.getInstance(user); - if(adminUtils == null) { - Map retMap = new Hashtable<>(); - retMap.put("error", "User does not have admin priviledges"); - return WebUtility.getResponse(retMap, 400); - } - - List> ret = adminUtils.getAllUsers(); - return WebUtility.getResponse(ret, 200); - } - @POST @Produces("application/json") @Path("requestAccess") @@ -251,12 +89,12 @@ public Response requestAccess(@Context HttpServletRequest request, MultivaluedMa try { addedRequests = SecurityUpdateUtils.makeRequest(user, engineId, requestedPermission); } catch(IllegalArgumentException e) { - logger.error(STACKTRACE, e); + logger.error(Constants.STACKTRACE, e); Map errorRet = new HashMap<>(); errorRet.put("error", e.getMessage()); return WebUtility.getResponse(errorRet, 400); } catch (Exception e){ - logger.error(STACKTRACE, e); + logger.error(Constants.STACKTRACE, e); Map errorRet = new HashMap<>(); errorRet.put("error", "An unexpected error happened. Please try again."); return WebUtility.getResponse(errorRet, 500); @@ -282,12 +120,12 @@ public Response getMyRequests(@Context HttpServletRequest request) { try { userRequests = SecurityQueryUtils.getUserAccessRequests(user); } catch(IllegalArgumentException e) { - logger.error(STACKTRACE, e); + logger.error(Constants.STACKTRACE, e); Map errorRet = new HashMap<>(); errorRet.put("error", e.getMessage()); return WebUtility.getResponse(errorRet, 400); } catch (Exception e){ - logger.error(STACKTRACE, e); + logger.error(Constants.STACKTRACE, e); Map errorRet = new HashMap<>(); errorRet.put("error", "An unexpected error happened. Please try again."); return WebUtility.getResponse(errorRet, 500); diff --git a/src/prerna/semoss/web/services/local/auth/AdminUserAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/AdminUserAuthorizationResource.java index d6cc1e0c1..12504f8bf 100644 --- a/src/prerna/semoss/web/services/local/auth/AdminUserAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/AdminUserAuthorizationResource.java @@ -2,9 +2,11 @@ import java.util.HashMap; import java.util.Hashtable; +import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.Produces; @@ -15,6 +17,8 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import com.google.gson.Gson; + import prerna.auth.User; import prerna.auth.utils.AbstractSecurityUtils; import prerna.auth.utils.SecurityAdminUtils; @@ -23,11 +27,27 @@ import prerna.util.Constants; import prerna.web.services.util.WebUtility; -@Path("/auth/user") +@Path("/auth/admin/user") public class AdminUserAuthorizationResource extends AbstractAdminResource { private static final Logger logger = LogManager.getLogger(AdminUserAuthorizationResource.class); + @GET + @Path("/isAdminUser") + public Response isAdminUser(@Context HttpServletRequest request) { + User user = null; + try { + user = ResourceUtility.getUser(request); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap<>(); + errorMap.put("error", "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + + boolean isAdmin = SecurityAdminUtils.userIsAdmin(user); + return WebUtility.getResponse(isAdmin, 200); + } + @POST @Produces("application/json") @Path("/registerUser") @@ -83,7 +103,7 @@ public Response registerUser(@Context HttpServletRequest request, MultivaluedMap */ @POST @Produces("application/json") - @Path("setUserPublisher") + @Path("/setUserPublisher") public Response setUserPublisher(@Context HttpServletRequest request, MultivaluedMap form) { SecurityAdminUtils adminUtils = null; User user = null; @@ -113,4 +133,85 @@ public Response setUserPublisher(@Context HttpServletRequest request, Multivalue ret.put("success", true); return WebUtility.getResponse(ret, 200); } + + /** + * Edit user properties + * @param request + * @param form + * @return true if the edition was performed + */ + @POST + @Path("/editUser") + @Produces("application/json") + public Response editUser(@Context HttpServletRequest request, MultivaluedMap form) { + SecurityAdminUtils adminUtils = null; + User user = null; + try { + user = ResourceUtility.getUser(request); + adminUtils = performAdminCheck(request, user); + } catch (IllegalAccessException e) { + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + + Gson gson = new Gson(); + Map userInfo = gson.fromJson(form.getFirst("user"), Map.class); + boolean ret = false; + try { + ret = adminUtils.editUser(userInfo); + } catch(IllegalArgumentException e) { + Map retMap = new Hashtable<>(); + retMap.put("error", e.getMessage()); + return WebUtility.getResponse(retMap, 400); + } + if(!ret) { + Map retMap = new Hashtable<>(); + retMap.put("error", "Unknown error occured with updating user. Please try again."); + return WebUtility.getResponse(retMap, 400); + } + return WebUtility.getResponse(ret, 200); + } + + @POST + @Produces("application/json") + @Path("/deleteUser") + public Response deleteUser(@Context HttpServletRequest request, MultivaluedMap form) { + SecurityAdminUtils adminUtils = null; + User user = null; + try { + user = ResourceUtility.getUser(request); + adminUtils = performAdminCheck(request, user); + } catch (IllegalAccessException e) { + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + + String userToDelete = form.getFirst("userId"); + boolean success = adminUtils.deleteUser(userToDelete); + return WebUtility.getResponse(success, 200); + } + + @GET + @Path("/getAllDbUsers") + @Produces("application/json") + public Response getAllUsers(@Context HttpServletRequest request) { + SecurityAdminUtils adminUtils = null; + User user = null; + try { + user = ResourceUtility.getUser(request); + adminUtils = performAdminCheck(request, user); + } catch (IllegalAccessException e) { + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + + List> ret = adminUtils.getAllUsers(); + return WebUtility.getResponse(ret, 200); + } } From c473acb2c103502c7b1dd6d578bf480479abe374 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 14 Dec 2020 20:43:41 +0000 Subject: [PATCH 0708/1906] UPDATE ::: Adding logic to control when we add an additional insight config on re-execution of the insight recipe git-svn-id: svn://107.170.10.188:8080/Monolith/dev@41735 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 5126426f3368427b39643a4d6b9f24d2fa12fb3a --- .../semoss/web/services/local/ExecuteInsightResource.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prerna/semoss/web/services/local/ExecuteInsightResource.java b/src/prerna/semoss/web/services/local/ExecuteInsightResource.java index 7299e979b..500d0fdfc 100644 --- a/src/prerna/semoss/web/services/local/ExecuteInsightResource.java +++ b/src/prerna/semoss/web/services/local/ExecuteInsightResource.java @@ -91,7 +91,7 @@ public Object generateInsight(@Context HttpServletRequest request, } InsightStore.getInstance().put(newInsight); - newInsight.reRunPixelInsight(); + newInsight.reRunPixelInsight(false); RunInsight runner = new RunInsight(newInsight); runner.dropInsight(true); return runner; From 12ea9f019d73b30135a02112186935edf442fc9e Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 16 Dec 2020 18:33:19 +0000 Subject: [PATCH 0709/1906] UPDATE ::: Sending to the FE if the insight should be cached by default on save or not git-svn-id: svn://107.170.10.188:8080/Monolith/dev@41794 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: afda5fab437eef0583fedae7ca0ae552d0e7281f --- .../web/services/config/ServerConfigurationResource.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/prerna/semoss/web/services/config/ServerConfigurationResource.java b/src/prerna/semoss/web/services/config/ServerConfigurationResource.java index 766e991bf..29f4d9ef8 100644 --- a/src/prerna/semoss/web/services/config/ServerConfigurationResource.java +++ b/src/prerna/semoss/web/services/config/ServerConfigurationResource.java @@ -28,6 +28,7 @@ import prerna.theme.AdminThemeUtils; import prerna.util.Constants; import prerna.util.DIHelper; +import prerna.util.Utility; import prerna.web.conf.DBLoader; import prerna.web.services.util.WebUtility; @@ -142,6 +143,10 @@ private static void loadConfig(HttpSession session) { } loadConfig.put("localDeployment", localMode); + // insights are cacheable by default + boolean cacheableOnByDefault = Utility.getApplicationCacheInsight(); + loadConfig.put("cacheInsightByDefault", cacheableOnByDefault); + ServerConfigurationResource.config = loadConfig; } From fd7e6e7d5ff68178e85d9e886bbff2b00b3d1559 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 16 Dec 2020 23:23:12 +0000 Subject: [PATCH 0710/1906] UPDATE ::: Upping the h2 version git-svn-id: svn://107.170.10.188:8080/Monolith/dev@41804 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: ca8f1f7ae64ad87bd1c61f746acb6166d15f947c --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 284b5cfb1..63b60f9c9 100644 --- a/pom.xml +++ b/pom.xml @@ -1399,7 +1399,7 @@ com.h2database h2 - 1.4.199 + 1.4.200 org.postgresql From bd34fab4509dc065708d25972b83f9acf10d50d7 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 17 Dec 2020 02:39:50 +0000 Subject: [PATCH 0711/1906] UPDATE ::: Accounting for sqlite (or other rdbms types) where clob is not allowed UPDATE ::: Storing the recipe in the security database git-svn-id: svn://107.170.10.188:8080/Monolith/dev@41807 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 743b92f16ac37549e4b5b5f9090df9719e295da7 --- src/prerna/semoss/web/services/config/AdminConfigService.java | 3 ++- .../web/services/config/ServerConfigurationResource.java | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/prerna/semoss/web/services/config/AdminConfigService.java b/src/prerna/semoss/web/services/config/AdminConfigService.java index 8def4701f..b1967342d 100644 --- a/src/prerna/semoss/web/services/config/AdminConfigService.java +++ b/src/prerna/semoss/web/services/config/AdminConfigService.java @@ -13,6 +13,7 @@ import javax.ws.rs.core.Context; import javax.ws.rs.core.MultivaluedMap; import javax.ws.rs.core.Response; + import org.owasp.encoder.Encode; import com.google.gson.Gson; @@ -44,7 +45,7 @@ public Response setInitialAdmins(@Context HttpServletRequest request, @Context H SecurityUpdateUtils.registerUser(id, null, null, null, null , true, true); } - if (session.getAttribute(ADMIN_REDIRECT_KEY) != null) { + if (session != null && session.getAttribute(ADMIN_REDIRECT_KEY) != null) { String originalRedirect = session.getAttribute(ADMIN_REDIRECT_KEY) + ""; String encodedRedirectUrl = Encode.forHtml(originalRedirect); response.setHeader("redirect", encodedRedirectUrl); diff --git a/src/prerna/semoss/web/services/config/ServerConfigurationResource.java b/src/prerna/semoss/web/services/config/ServerConfigurationResource.java index 29f4d9ef8..22bc77a88 100644 --- a/src/prerna/semoss/web/services/config/ServerConfigurationResource.java +++ b/src/prerna/semoss/web/services/config/ServerConfigurationResource.java @@ -37,7 +37,6 @@ public class ServerConfigurationResource { private static final Logger logger = LogManager.getLogger(ServerConfigurationResource.class); - private static volatile Map config = null; /** From 328285b7ba6fe5f594c08c3befa56bfe276c9cf5 Mon Sep 17 00:00:00 2001 From: rramirezjimenez Date: Thu, 17 Dec 2020 15:55:16 +0000 Subject: [PATCH 0712/1906] UPDATE ::: Exposing publisher option in admin add/edit user git-svn-id: svn://107.170.10.188:8080/Monolith/dev@41820 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 818a300101ac0e08d9fb6e5c0b1656d49960b5ec --- .../services/local/auth/AdminUserAuthorizationResource.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/prerna/semoss/web/services/local/auth/AdminUserAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/AdminUserAuthorizationResource.java index 12504f8bf..188458428 100644 --- a/src/prerna/semoss/web/services/local/auth/AdminUserAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/AdminUserAuthorizationResource.java @@ -62,6 +62,8 @@ public Response registerUser(@Context HttpServletRequest request, MultivaluedMap String email = form.getFirst("email"); String type = form.getFirst("type"); Boolean newUserAdmin = Boolean.parseBoolean(form.getFirst("admin")); + Boolean publisher = Boolean.parseBoolean(form.getFirst("publisher")); + String password = form.getFirst("password"); // validate email & password if (email != null && !email.isEmpty()) { @@ -78,7 +80,7 @@ public Response registerUser(@Context HttpServletRequest request, MultivaluedMap } } if(SecurityAdminUtils.userIsAdmin(user)){ - success = SecurityUpdateUtils.registerUser(newUserId, name, email, password, type, newUserAdmin, !AbstractSecurityUtils.adminSetPublisher()); + success = SecurityUpdateUtils.registerUser(newUserId, name, email, password, type, newUserAdmin, publisher); } else { errorRet.put("error", "The user doesn't have the permissions to perform this action."); return WebUtility.getResponse(errorRet, 400); From 5821ba645803ba444e971703fc6b5f8c457220e5 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 18 Dec 2020 00:01:27 +0000 Subject: [PATCH 0713/1906] UPDATE ::: Ability to edit user information when the individual is not native UPDATE ::: Standardizing error messages sent from permission api UPDATE ::: Using BE error messages instead of FE generic messages when errors occur when editing user information git-svn-id: svn://107.170.10.188:8080/Monolith/dev@41845 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 417c421fc0e75d0cf8c1f996f8d9e6ffa8160a33 --- .../semoss/web/services/local/UserResource.java | 2 ++ .../auth/AdminUserAuthorizationResource.java | 15 +++++++++------ .../local/auth/AppAuthorizationResource.java | 9 ++++----- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index 243e1bbed..eee78a044 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -1525,6 +1525,8 @@ public Response loginNative(@Context HttpServletRequest request, @Context HttpSe public Response createUser(@Context HttpServletRequest request) { Hashtable ret = new Hashtable<>(); try { + // Note - for native users + // the id and the username are always the same String username = request.getParameter("username"); String name = request.getParameter("name"); String password = request.getParameter("password"); diff --git a/src/prerna/semoss/web/services/local/auth/AdminUserAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/AdminUserAuthorizationResource.java index 188458428..7f5a2d723 100644 --- a/src/prerna/semoss/web/services/local/auth/AdminUserAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/AdminUserAuthorizationResource.java @@ -40,7 +40,7 @@ public Response isAdminUser(@Context HttpServletRequest request) { user = ResourceUtility.getUser(request); } catch (IllegalAccessException e) { Map errorMap = new HashMap<>(); - errorMap.put("error", "User session is invalid"); + errorMap.put(ResourceUtility.ERROR_KEY, "User session is invalid"); return WebUtility.getResponse(errorMap, 401); } @@ -58,6 +58,9 @@ public Response registerUser(@Context HttpServletRequest request, MultivaluedMap User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); String newUserId = form.getFirst("userId"); + if(newUserId == null || newUserId.isEmpty()) { + throw new IllegalArgumentException("The user id cannot be null or empty"); + } String name = form.getFirst("name"); String email = form.getFirst("email"); String type = form.getFirst("type"); @@ -82,16 +85,16 @@ public Response registerUser(@Context HttpServletRequest request, MultivaluedMap if(SecurityAdminUtils.userIsAdmin(user)){ success = SecurityUpdateUtils.registerUser(newUserId, name, email, password, type, newUserAdmin, publisher); } else { - errorRet.put("error", "The user doesn't have the permissions to perform this action."); + errorRet.put(ResourceUtility.ERROR_KEY, "The user doesn't have the permissions to perform this action."); return WebUtility.getResponse(errorRet, 400); } } catch (IllegalArgumentException e){ logger.error(Constants.STACKTRACE, e); - errorRet.put("error", e.getMessage()); + errorRet.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorRet, 400); } catch (Exception e){ logger.error(Constants.STACKTRACE, e); - errorRet.put("error", "An unexpected error happened. Please try again."); + errorRet.put(ResourceUtility.ERROR_KEY, "An unexpected error happened. Please try again."); return WebUtility.getResponse(errorRet, 500); } return WebUtility.getResponse(success, 200); @@ -165,12 +168,12 @@ public Response editUser(@Context HttpServletRequest request, MultivaluedMap retMap = new Hashtable<>(); - retMap.put("error", e.getMessage()); + retMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(retMap, 400); } if(!ret) { Map retMap = new Hashtable<>(); - retMap.put("error", "Unknown error occured with updating user. Please try again."); + retMap.put(ResourceUtility.ERROR_KEY, "Unknown error occured with updating user. Please try again."); return WebUtility.getResponse(retMap, 400); } return WebUtility.getResponse(ret, 200); diff --git a/src/prerna/semoss/web/services/local/auth/AppAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/AppAuthorizationResource.java index 41c867af4..c8dc97616 100644 --- a/src/prerna/semoss/web/services/local/auth/AppAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/AppAuthorizationResource.java @@ -30,7 +30,6 @@ public class AppAuthorizationResource { private static final Logger logger = LogManager.getLogger(AppAuthorizationResource.class); - private static final String STACKTRACE = "StackTrace: "; @Context protected ServletContext context; @@ -300,12 +299,12 @@ public Response setAppGlobal(@Context HttpServletRequest request, MultivaluedMap SecurityAppUtils.setAppGlobal(user, appId, isPublic); } catch(IllegalAccessException e) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to set the app " + appId + logPublic + " without having proper access")); - logger.error(STACKTRACE, e); + logger.error(Constants.STACKTRACE, e); Map errorRet = new HashMap(); errorRet.put("error", e.getMessage()); return WebUtility.getResponse(errorRet, 400); } catch (Exception e){ - logger.error(STACKTRACE, e); + logger.error(Constants.STACKTRACE, e); Map errorRet = new HashMap(); errorRet.put("error", "An unexpected error happened. Please try again."); return WebUtility.getResponse(errorRet, 500); @@ -348,12 +347,12 @@ public Response setAppVisibility(@Context HttpServletRequest request, Multivalue SecurityUpdateUtils.setDbVisibility(user, appId, visible); } catch(IllegalAccessException e) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to set the app " + appId + logVisible + " without having proper access")); - logger.error(STACKTRACE, e); + logger.error(Constants.STACKTRACE, e); Map errorRet = new HashMap(); errorRet.put("error", e.getMessage()); return WebUtility.getResponse(errorRet, 400); } catch (Exception e){ - logger.error(STACKTRACE, e); + logger.error(Constants.STACKTRACE, e); Map errorRet = new HashMap(); errorRet.put("error", "An unexpected error happened. Please try again."); return WebUtility.getResponse(errorRet, 500); From 970e9a57f5a68a143e753146d2444527e5a98fc2 Mon Sep 17 00:00:00 2001 From: pkapaleeswaran Date: Fri, 25 Dec 2020 20:59:24 +0000 Subject: [PATCH 0714/1906] Adding apache commons exec git-svn-id: svn://107.170.10.188:8080/Monolith/dev@41902 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 69fd539654eb4eb452f62a658123ff1e352a81c0 --- pom.xml | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/pom.xml b/pom.xml index 63b60f9c9..11a112cf2 100644 --- a/pom.xml +++ b/pom.xml @@ -284,13 +284,6 @@ semoss ${ci.version} - - jdk.tools - jdk.tools - 1.8 - system - ${env.JAVA_HOME}/lib/tools.jar - org.antlr antlr-complete @@ -1915,6 +1908,12 @@ com.github.ulisesbocchio jasypt-spring-boot-starter 2.0.0 - + + + org.apache.commons + commons-exec + 1.3 + + \ No newline at end of file From 8b8a03e497b7e7bfe1e04e9b7a0e497e8bc704ec Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 4 Jan 2021 20:58:44 +0000 Subject: [PATCH 0715/1906] BUGFIX ::: Adding back removed tools.jar path git-svn-id: svn://107.170.10.188:8080/Monolith/dev@41935 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: f4d81b9b91f2262be1be05dc96975ddad65121da --- pom.xml | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/pom.xml b/pom.xml index 11a112cf2..78f2e1c20 100644 --- a/pom.xml +++ b/pom.xml @@ -284,6 +284,13 @@ semoss ${ci.version} + + jdk.tools + jdk.tools + 1.8 + system + ${env.JAVA_HOME}/lib/tools.jar + org.antlr antlr-complete @@ -1910,10 +1917,9 @@ 2.0.0 - org.apache.commons - commons-exec - 1.3 - - + org.apache.commons + commons-exec + 1.3 + \ No newline at end of file From 19181ae80d1eea7d42415e06afe3ddbed8fbec02 Mon Sep 17 00:00:00 2001 From: kunalppatel9 Date: Wed, 6 Jan 2021 17:44:43 +0000 Subject: [PATCH 0716/1906] UPDATE ::: Adding in calls for param'ed token and auth urls for ms and siteminder and checking login enabled for siteminder git-svn-id: svn://107.170.10.188:8080/Monolith/dev@41958 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 3285593d39f80a8264185b76994f330e7862f029 --- .../web/services/local/UserResource.java | 35 ++++++++++++++----- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index eee78a044..d79b011a5 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -69,6 +69,7 @@ import org.kohsuke.github.GitHub; import org.owasp.encoder.Encode; +import com.google.common.base.Strings; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; @@ -159,6 +160,7 @@ private static void setLoginsAllowed() { boolean githubLogin = Boolean.parseBoolean(socialData.getProperty("github_login")); boolean googleLogin = Boolean.parseBoolean(socialData.getProperty("google_login")); boolean onedriveLogin = Boolean.parseBoolean(socialData.getProperty("ms_login")); + boolean siteminderLogin = Boolean.parseBoolean(socialData.getProperty("siteminder_login")); boolean dropboxLogin = Boolean.parseBoolean(socialData.getProperty("dropbox_login")); boolean cacLogin = Boolean.parseBoolean(socialData.getProperty("cac_login")); boolean registration = Boolean.parseBoolean(socialData.getProperty("native_registration")); @@ -167,6 +169,7 @@ private static void setLoginsAllowed() { UserResource.loginsAllowedMap.put("google", googleLogin); UserResource.loginsAllowedMap.put("github", githubLogin); UserResource.loginsAllowedMap.put("ms", onedriveLogin); + UserResource.loginsAllowedMap.put("siteminder", siteminderLogin); UserResource.loginsAllowedMap.put("dropbox", dropboxLogin); UserResource.loginsAllowedMap.put("cac", cacLogin); UserResource.loginsAllowedMap.put("registration", registration); @@ -808,6 +811,7 @@ public Response loginMS(@Context HttpServletRequest request, @Context HttpServle String redirectUri = socialData.getProperty(prefix + "redirect_uri"); String tenant = socialData.getProperty(prefix + "tenant"); String scope = socialData.getProperty(prefix + "scope"); + String token_url = socialData.getProperty(prefix + "token_url"); logger.debug(">> " + Utility.cleanLogString(request.getQueryString())); @@ -819,9 +823,12 @@ public Response loginMS(@Context HttpServletRequest request, @Context HttpServle params.put("grant_type", "authorization_code"); params.put("client_secret", clientSecret); - String url = "https://login.microsoftonline.com/" + tenant + "/oauth2/v2.0/token"; + + if(Strings.isNullOrEmpty(token_url)){ + token_url = "https://login.microsoftonline.com/" + tenant + "/oauth2/v2.0/token"; + } - AccessToken accessToken = AbstractHttpHelper.getAccessToken(url, params, true, true); + AccessToken accessToken = AbstractHttpHelper.getAccessToken(token_url); if (accessToken == null) { // not authenticated response.setStatus(302); @@ -856,9 +863,14 @@ private String getMSRedirect(HttpServletRequest request) throws UnsupportedEncod String redirectUri = socialData.getProperty(prefix + "redirect_uri"); String tenant = socialData.getProperty(prefix + "tenant"); String scope = socialData.getProperty(prefix + "scope"); // need to set this up and reuse + String auth_url = socialData.getProperty(prefix + "auth_url"); String state = UUID.randomUUID().toString(); - String redirectUrl = "https://login.microsoftonline.com/" + tenant + "/oauth2/v2.0/authorize?" + "client_id=" + + if(Strings.isNullOrEmpty(auth_url)){ + auth_url = "https://login.microsoftonline.com/" + tenant + "/oauth2/v2.0/authorize"; + } + String redirectUrl = auth_url + "?" + "client_id=" + clientId + "&response_type=code" + "&redirect_uri=" + URLEncoder.encode(redirectUri, "UTF-8") + "&response_mode=query" + "&scope=" + URLEncoder.encode(scope) + "&state=" + state; @@ -893,6 +905,7 @@ public Response loginSiteminder(@Context HttpServletRequest request, @Context Ht String redirectUri = socialData.getProperty(prefix + "redirect_uri"); String tenant = socialData.getProperty(prefix + "tenant"); String scope = socialData.getProperty(prefix + "scope"); + String token_url = socialData.getProperty(prefix + "token_url"); logger.debug(">> " + Utility.cleanLogString(request.getQueryString())); @@ -904,9 +917,10 @@ public Response loginSiteminder(@Context HttpServletRequest request, @Context Ht params.put("grant_type", "authorization_code"); params.put("client_secret", clientSecret); - String url = "https://login.microsoftonline.com/" + tenant + "/oauth2/v2.0/token"; - - AccessToken accessToken = AbstractHttpHelper.getAccessToken(url, params, true, true); + if(Strings.isNullOrEmpty(token_url)){ + token_url = "https://login.microsoftonline.com/" + tenant + "/oauth2/v2.0/token"; + } + AccessToken accessToken = AbstractHttpHelper.getAccessToken(token_url, params, true, true); if (accessToken == null) { // not authenticated response.setStatus(302); @@ -941,9 +955,14 @@ private String getSiteminderRedirect(HttpServletRequest request) throws Unsuppor String redirectUri = socialData.getProperty(prefix + "redirect_uri"); String tenant = socialData.getProperty(prefix + "tenant"); String scope = socialData.getProperty(prefix + "scope"); // need to set this up and reuse - + String auth_url = socialData.getProperty(prefix + "auth_url"); String state = UUID.randomUUID().toString(); - String redirectUrl = "https://login.microsoftonline.com/" + tenant + "/oauth2/v2.0/authorize?" + "client_id=" + + if(Strings.isNullOrEmpty(auth_url)){ + auth_url = "https://login.microsoftonline.com/" + tenant + "/oauth2/v2.0/authorize"; + } + + String redirectUrl = auth_url + "?" + "client_id=" + clientId + "&response_type=code" + "&redirect_uri=" + URLEncoder.encode(redirectUri, "UTF-8") + "&response_mode=query" + "&scope=" + URLEncoder.encode(scope) + "&state=" + state; From f136d216734b510a118a9f7a399d3245d08fcc5b Mon Sep 17 00:00:00 2001 From: kunalppatel9 Date: Thu, 7 Jan 2021 16:34:21 +0000 Subject: [PATCH 0717/1906] BUGFIX ::: adding back param and booleans for getAccessToken call for MS login git-svn-id: svn://107.170.10.188:8080/Monolith/dev@41973 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 0ba10b3e9463bef5680b9c3dd8776a9df1614b07 --- src/prerna/semoss/web/services/local/UserResource.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index d79b011a5..ad6891645 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -828,7 +828,7 @@ public Response loginMS(@Context HttpServletRequest request, @Context HttpServle token_url = "https://login.microsoftonline.com/" + tenant + "/oauth2/v2.0/token"; } - AccessToken accessToken = AbstractHttpHelper.getAccessToken(token_url); + AccessToken accessToken = AbstractHttpHelper.getAccessToken(token_url, params, true, true); if (accessToken == null) { // not authenticated response.setStatus(302); From 8dc90096c17c0f95eea444bc55d9fa667e4fd02f Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 7 Jan 2021 19:18:23 +0000 Subject: [PATCH 0718/1906] UPDATE ::: Removing fake prefix for APP_FOLDER/ that was not used and not properly removed at times causing file not found errors git-svn-id: svn://107.170.10.188:8080/Monolith/dev@41976 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 375711e1716efff14b1c2964caae29a639bc586a --- src/prerna/upload/FileUploader.java | 4 +--- src/prerna/web/conf/NoUserInSessionFilter.java | 3 +-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/src/prerna/upload/FileUploader.java b/src/prerna/upload/FileUploader.java index 65b6cb3cd..5e5c26695 100644 --- a/src/prerna/upload/FileUploader.java +++ b/src/prerna/upload/FileUploader.java @@ -246,10 +246,9 @@ public Response uploadFile(@Context ServletContext context, @Context HttpServlet private List> getBaseUploadData(List fileItems, Insight in, String relativePath, String appId) { // get base asset folder String assetFolder = null; - String fePath = Insight.getInsightRelativeFolderKey(in); + String fePath = Insight.getInsightRelativeFolderKey(); if (appId != null) { assetFolder = AssetUtility.getAssetBasePath(in, appId, true); - fePath = Insight.getAppRelativeFolderKey(); } else { assetFolder = in.getInsightFolder(); } @@ -324,7 +323,6 @@ private List> getBaseUploadData(List fileItems, In logger.info("Writing Input To File"); // Date date = new Date(); // String modifiedDate = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_SSSS").format(date); - // String fileSuffix = "FileString_" + modifiedDate;; // String fileLocation = filePath + DIR_SEPARATOR + fileSuffix; diff --git a/src/prerna/web/conf/NoUserInSessionFilter.java b/src/prerna/web/conf/NoUserInSessionFilter.java index 0cc92d2a2..2a72bebed 100644 --- a/src/prerna/web/conf/NoUserInSessionFilter.java +++ b/src/prerna/web/conf/NoUserInSessionFilter.java @@ -49,7 +49,6 @@ public class NoUserInSessionFilter implements Filter { public static final String MONOLITH_PREFIX = "MONOLITH_PREFIX"; private static final String LOGIN = "login"; - private static final String STACKTRACE = "StackTrace: "; private static final String NO_USER_HTML = "/noUserFail/"; protected static List ignoreDueToFE = new Vector<>(); @@ -280,7 +279,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 arg2.doFilter(wrapper, arg1); return; } catch (NoSuchAlgorithmException e) { - logger.error(STACKTRACE, e); + logger.error(Constants.STACKTRACE, e); } } } From ffd64eacf6e084b5e74f24a3fc432bd37c985ce8 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 8 Jan 2021 03:43:33 +0000 Subject: [PATCH 0719/1906] UPDATE ::: Assuming csv/tsv/txt/etc. ltype are all processed and compared the same way for header checks. Only binding on excel as having 1 format (accounting for sheets) compared to all other formats. git-svn-id: svn://107.170.10.188:8080/Monolith/dev@41984 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: db8626f6855ab81b672f800de5176358e1411cc8 --- src/prerna/upload/FileUploader.java | 96 ++++++++++++++--------------- 1 file changed, 47 insertions(+), 49 deletions(-) diff --git a/src/prerna/upload/FileUploader.java b/src/prerna/upload/FileUploader.java index 5e5c26695..c6d4a95ca 100644 --- a/src/prerna/upload/FileUploader.java +++ b/src/prerna/upload/FileUploader.java @@ -63,60 +63,16 @@ public Response checkUserDefinedHeaders(MultivaluedMap form) { // since its a useless additional key but then I wouldn't need to have the bifurcation in // formats here and bifurcation in formats in the ImportOptions object as well String type = form.getFirst("uploadType").toUpperCase(); - + String headersToCheckString = form.getFirst("userHeaders"); // grab the checker HeadersException headerChecker = HeadersException.getInstance(); - - if(type.equals("CSV")) { - Map> invalidHeadersMap = new Hashtable<>(); - - // the key is for each file name - // the list are the headers inside that file - Map userDefinedHeadersMap = gson.fromJson(form.getFirst("userHeaders"), new TypeToken>() {}.getType()); - - for(String fileName : userDefinedHeadersMap.keySet()) { - String[] userHeaders = userDefinedHeadersMap.get(fileName); - - // now we need to check all of these headers - // now we need to check all of these headers - for(int colIdx = 0; colIdx < userHeaders.length; colIdx++) { - String userHeader = userHeaders[colIdx]; - Map badHeaderMap = new Hashtable<>(); - if(headerChecker.isIllegalHeader(userHeader)) { - badHeaderMap.put(userHeader, "This header name is a reserved word"); - } else if(headerChecker.containsIllegalCharacter(userHeader)) { - badHeaderMap.put(userHeader, "Header names cannot contain +%@;"); - } else if(headerChecker.isDuplicated(userHeader, userHeaders, colIdx)) { - badHeaderMap.put(userHeader, "Cannot have duplicate header names"); - } - - // map is filled in only if the header is bad - if(!badHeaderMap.isEmpty()) { - // need to make sure we do not override existing bad headers stored - // within the map - Map invalidHeadersForFile = null; - if(invalidHeadersMap.containsKey(fileName)) { - invalidHeadersForFile = invalidHeadersMap.get(fileName); - } else { - invalidHeadersForFile = new Hashtable<>(); - } - - // now add in the bad header for the file map - invalidHeadersForFile.putAll(badHeaderMap); - // now store it in the overall object - invalidHeadersMap.put(fileName, invalidHeadersForFile); - } - } - } - return WebUtility.getResponse(invalidHeadersMap, 200); - - } else if(type.equals("EXCEL")) { + if(type.equalsIgnoreCase("EXCEL")) { List>> invalidHeadersList = new Vector<>(); // each entry (outer map object) in the list if a workbook // each key in that map object is the sheetName for that given workbook // the list are the headers inside that sheet - List> userDefinedHeadersMap = gson.fromJson(form.getFirst("userHeaders"), new TypeToken>>() {}.getType()); + List> userDefinedHeadersMap = gson.fromJson(headersToCheckString, new TypeToken>>() {}.getType()); // iterate through each workbook for(Map excelWorkbook : userDefinedHeadersMap) { @@ -162,8 +118,50 @@ public Response checkUserDefinedHeaders(MultivaluedMap form) { invalidHeadersList.add(invalidHeadersMap); } return WebUtility.getResponse(invalidHeadersList, 200); - } else { - return WebUtility.getResponse("Format does not conform to checking headers", 400); + } + else + { + Map> invalidHeadersMap = new Hashtable<>(); + + // the key is for each file name + // the list are the headers inside that file + Map userDefinedHeadersMap = gson.fromJson(headersToCheckString, new TypeToken>() {}.getType()); + + for(String fileName : userDefinedHeadersMap.keySet()) { + String[] userHeaders = userDefinedHeadersMap.get(fileName); + + // now we need to check all of these headers + // now we need to check all of these headers + for(int colIdx = 0; colIdx < userHeaders.length; colIdx++) { + String userHeader = userHeaders[colIdx]; + Map badHeaderMap = new Hashtable<>(); + if(headerChecker.isIllegalHeader(userHeader)) { + badHeaderMap.put(userHeader, "This header name is a reserved word"); + } else if(headerChecker.containsIllegalCharacter(userHeader)) { + badHeaderMap.put(userHeader, "Header names cannot contain +%@;"); + } else if(headerChecker.isDuplicated(userHeader, userHeaders, colIdx)) { + badHeaderMap.put(userHeader, "Cannot have duplicate header names"); + } + + // map is filled in only if the header is bad + if(!badHeaderMap.isEmpty()) { + // need to make sure we do not override existing bad headers stored + // within the map + Map invalidHeadersForFile = null; + if(invalidHeadersMap.containsKey(fileName)) { + invalidHeadersForFile = invalidHeadersMap.get(fileName); + } else { + invalidHeadersForFile = new Hashtable<>(); + } + + // now add in the bad header for the file map + invalidHeadersForFile.putAll(badHeaderMap); + // now store it in the overall object + invalidHeadersMap.put(fileName, invalidHeadersForFile); + } + } + } + return WebUtility.getResponse(invalidHeadersMap, 200); } } From ea0d988fbfdc84aadc26b037e5da69499cc8c033 Mon Sep 17 00:00:00 2001 From: kunalppatel9 Date: Mon, 11 Jan 2021 19:48:21 +0000 Subject: [PATCH 0720/1906] UPDATE ::: Adding in call for setting route cookie value on runPixel calls git-svn-id: svn://107.170.10.188:8080/Monolith/dev@42016 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: c954df08f436261bb556d1bdb8abffa5bbfabcd9 --- .../semoss/web/services/local/NameServer.java | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index 69d4600da..323a32b3c 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -41,6 +41,7 @@ import java.util.Map; import java.util.UUID; +import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; @@ -99,6 +100,7 @@ import prerna.util.PlaySheetRDFMapBasedEnum; import prerna.util.Utility; import prerna.util.gson.GsonUtility; +import prerna.web.conf.NoUserInSessionFilter; import prerna.web.services.util.ResponseHashSingleton; import prerna.web.services.util.SemossExecutorSingleton; import prerna.web.services.util.SemossThread; @@ -298,6 +300,20 @@ public Response runPixelSync(@Context HttpServletRequest request) { sessionId = session.getId(); } + // add the route if this is server deployment + String routeCookieName = DIHelper.getInstance().getProperty(Constants.MONOLITH_ROUTE); + if (routeCookieName != null && !routeCookieName.isEmpty()) { + Cookie[] curCookies = request.getCookies(); + if (curCookies != null) { + for (Cookie c : curCookies) { + if (c.getName().equals(routeCookieName)) { + ThreadStore.setRouteId(c.getValue()); + } + } + } + } + + String jobId = ""; String insightId = request.getParameter("insightId"); String expression = request.getParameter("expression"); From e49abc4fd17eaadd6b47f01df808a926cc74d951 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 12 Jan 2021 02:36:08 +0000 Subject: [PATCH 0721/1906] UPDATE ::: Pushing catch for invalid formats and sending 400 error with proper message instead of 500 error git-svn-id: svn://107.170.10.188:8080/Monolith/dev@42031 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 258febb6bfae81c79b42607fb40dd682b991fd52 --- src/prerna/upload/FileUploader.java | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/prerna/upload/FileUploader.java b/src/prerna/upload/FileUploader.java index c6d4a95ca..63a929d29 100644 --- a/src/prerna/upload/FileUploader.java +++ b/src/prerna/upload/FileUploader.java @@ -36,6 +36,7 @@ import prerna.om.ThreadStore; import prerna.poi.main.HeadersException; import prerna.util.AssetUtility; +import prerna.util.Constants; import prerna.util.Utility; import prerna.web.services.util.WebUtility; @@ -72,7 +73,15 @@ public Response checkUserDefinedHeaders(MultivaluedMap form) { // each entry (outer map object) in the list if a workbook // each key in that map object is the sheetName for that given workbook // the list are the headers inside that sheet - List> userDefinedHeadersMap = gson.fromJson(headersToCheckString, new TypeToken>>() {}.getType()); + List> userDefinedHeadersMap = null; + try { + userDefinedHeadersMap = gson.fromJson(headersToCheckString, new TypeToken>>() {}.getType()); + } catch(Exception e) { + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap<>(); + errorMap.put(Constants.ERROR_MESSAGE, "Invalid format passed for user defined headers: " + headersToCheckString); + return WebUtility.getResponse(errorMap, 400); + } // iterate through each workbook for(Map excelWorkbook : userDefinedHeadersMap) { @@ -125,7 +134,15 @@ public Response checkUserDefinedHeaders(MultivaluedMap form) { // the key is for each file name // the list are the headers inside that file - Map userDefinedHeadersMap = gson.fromJson(headersToCheckString, new TypeToken>() {}.getType()); + Map userDefinedHeadersMap = null; + try { + userDefinedHeadersMap = gson.fromJson(headersToCheckString, new TypeToken>() {}.getType()); + } catch(Exception e) { + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap<>(); + errorMap.put(Constants.ERROR_MESSAGE, "Invalid format passed for user defined headers: " + headersToCheckString); + return WebUtility.getResponse(errorMap, 400); + } for(String fileName : userDefinedHeadersMap.keySet()) { String[] userHeaders = userDefinedHeadersMap.get(fileName); From 1628436aa23b0b3ded5b20e7005b823aab8ebe3e Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 14 Jan 2021 03:48:31 +0000 Subject: [PATCH 0722/1906] UPDATE ::: Switching the order of adding to the pixel runner instead of inserting at index 0 - making o(n) logic to be o(1) git-svn-id: svn://107.170.10.188:8080/Monolith/dev@42102 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 440543f79cc40bc5148c5475fb8408ba6b633844 --- src/prerna/semoss/web/services/local/RunInsight.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/prerna/semoss/web/services/local/RunInsight.java b/src/prerna/semoss/web/services/local/RunInsight.java index c5588cf70..37c761bce 100644 --- a/src/prerna/semoss/web/services/local/RunInsight.java +++ b/src/prerna/semoss/web/services/local/RunInsight.java @@ -104,8 +104,8 @@ public Response recreateInsightState(@Context HttpServletRequest request) { e.printStackTrace(); } - PixelRunner pixelRunner = rerunInsight.runPixel(recipe); - // add all the frame headers to the payload + PixelRunner pixelRunner = new PixelRunner(); + // add all the frame headers to the payload first try { VarStore vStore = in.getVarStore(); Set keys = vStore.getFrameKeys(); @@ -115,8 +115,9 @@ public Response recreateInsightState(@Context HttpServletRequest request) { if(type == PixelDataType.FRAME) { try { ITableDataFrame frame = (ITableDataFrame) noun.getValue(); - pixelRunner.addResult(0, "CACHED_FRAME_HEADERS", - new NounMetadata(frame.getFrameHeadersObject(), PixelDataType.CUSTOM_DATA_STRUCTURE, PixelOperationType.FRAME_HEADERS)); + pixelRunner.addResult("CACHED_FRAME_HEADERS", + new NounMetadata(frame.getFrameHeadersObject(), PixelDataType.CUSTOM_DATA_STRUCTURE, + PixelOperationType.FRAME_HEADERS), true); } catch(Exception e) { e.printStackTrace(); // ignore @@ -126,6 +127,8 @@ public Response recreateInsightState(@Context HttpServletRequest request) { } catch (Exception e) { e.printStackTrace(); } + // now rerun the recipe and append to the runner + in.runPixel(pixelRunner, recipe); return Response.status(200).entity(PixelStreamUtility.collectPixelData(pixelRunner)) .header("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0, post-check=0, pre-check=0") From 1a3d373852a07b09e6d602eeea2772583899ffe8 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 15 Jan 2021 14:22:20 +0000 Subject: [PATCH 0723/1906] UPDATE ::: Removing session counter as tomcat has better solution git-svn-id: svn://107.170.10.188:8080/Monolith/dev@42142 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 811dfe40be1a259d2fa98d9f0635d8eee3645bc7 --- WebContent/WEB-INF/web.xml | 3 --- 1 file changed, 3 deletions(-) diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index d4bac48d7..461114e6b 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -423,9 +423,6 @@ prerna.web.conf.UserDBLoader - - prerna.web.conf.SessionCounter - prerna.web.conf.NoUserInSessionTrustedTokenListener From dc6e902549873fc7aa724ce0a16544333cb7a63c Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 15 Jan 2021 14:29:28 +0000 Subject: [PATCH 0724/1906] UPDATE ::: Pushing Michael's patch for modifying how we determine the # of active sessions. Removing legacy implementation git-svn-id: svn://107.170.10.188:8080/Monolith/dev@42143 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: de81d718444369904aa063ce274904d3282000fe --- .../web/services/local/SessionResource.java | 56 ++++++++++++++++--- src/prerna/web/conf/SessionCounter.java | 27 --------- 2 files changed, 47 insertions(+), 36 deletions(-) delete mode 100644 src/prerna/web/conf/SessionCounter.java diff --git a/src/prerna/semoss/web/services/local/SessionResource.java b/src/prerna/semoss/web/services/local/SessionResource.java index 728d27447..ab991c2cf 100644 --- a/src/prerna/semoss/web/services/local/SessionResource.java +++ b/src/prerna/semoss/web/services/local/SessionResource.java @@ -1,6 +1,7 @@ package prerna.semoss.web.services.local; import java.io.IOException; +import java.lang.reflect.Field; import java.util.Date; import java.util.HashMap; import java.util.HashSet; @@ -17,6 +18,10 @@ import javax.ws.rs.core.Context; import javax.ws.rs.core.Response; +import org.apache.catalina.core.ApplicationContext; +import org.apache.catalina.core.ApplicationContextFacade; +import org.apache.catalina.core.StandardContext; +import org.apache.catalina.session.StandardManager; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.owasp.encoder.Encode; @@ -30,16 +35,22 @@ import prerna.util.Utility; import prerna.util.insight.InsightUtility; import prerna.web.conf.DBLoader; -import prerna.web.conf.SessionCounter; import prerna.web.services.util.WebUtility; + @Path("/session") public class SessionResource { + private static final Logger logger = LogManager.getLogger(SessionResource.class); private static final String CANCEL_INVALIDATION = "cancelInvalidation"; - private static final String STACKTRACE = "StackTrace: "; private Object lock = new Object(); - + + /** + * Returns the number of active servers related to a given manager. + * @param request + * @return + */ + @GET @Path("/active") @Produces("application/json;charset=utf-8") @@ -59,16 +70,43 @@ public Response getActiveSessions(@Context HttpServletRequest request) { return WebUtility.getResponse(errorMap, 401); } } - - Map ret = new HashMap<>(); - ret.put("activeSessions", SessionCounter.getActiveSessions()); + + StandardManager manager = getManager(request); + + Map ret = new HashMap<>(); + if(manager != null) { + ret.put("activeSessions", manager.getActiveSessions()); + } else { + ret.put("activeSessions", "Error in getting manager context"); + } return WebUtility.getResponse(ret, 200); } + + /** + * Getting the manager + * @param request + */ + public static StandardManager getManager(@Context HttpServletRequest request) { + ApplicationContextFacade applicationContextFacade = (ApplicationContextFacade) request.getSession().getServletContext(); + try { + Field applicationContextField = applicationContextFacade.getClass().getDeclaredField("context"); + applicationContextField.setAccessible(true); + ApplicationContext appContext = (ApplicationContext) applicationContextField.get(applicationContextFacade); + + Field standardContextField = appContext.getClass().getDeclaredField("context"); + standardContextField.setAccessible(true); + StandardContext standardContext = (StandardContext) standardContextField.get(appContext); + return (StandardManager) standardContext.getManager(); + } catch (IllegalAccessException | IllegalArgumentException | NoSuchFieldException | SecurityException e) { + logger.error(Constants.STACKTRACE, e); + } + + return null; + } /* * End points for cleanup of the thread to account for closing/opening */ - @POST @Path("/cleanSession") @Produces("application/json;charset=utf-8") @@ -107,9 +145,9 @@ public Response cleanSession(@Context HttpServletRequest request) { // wait 10 seconds try { Thread.sleep(10_000); - } catch (InterruptedException e1) { + } catch (InterruptedException e) { Thread.currentThread().interrupt(); - logger.error(STACKTRACE, e1); + logger.error(Constants.STACKTRACE, e); } String output = null; diff --git a/src/prerna/web/conf/SessionCounter.java b/src/prerna/web/conf/SessionCounter.java deleted file mode 100644 index 9f3d656e0..000000000 --- a/src/prerna/web/conf/SessionCounter.java +++ /dev/null @@ -1,27 +0,0 @@ -package prerna.web.conf; - -import java.util.concurrent.atomic.AtomicInteger; - -import javax.servlet.http.HttpSessionEvent; -import javax.servlet.http.HttpSessionListener; - -public class SessionCounter implements HttpSessionListener { - - private static volatile AtomicInteger activeSessions = new AtomicInteger(0); - - /* - * Simple listener to count the number of active sessions - */ - - public void sessionCreated(HttpSessionEvent se) { - activeSessions.incrementAndGet(); - } - - public void sessionDestroyed(HttpSessionEvent se) { - activeSessions.decrementAndGet(); - } - - public static int getActiveSessions() { - return activeSessions.get(); - } -} \ No newline at end of file From 1ebcfdba9ab1afd3baa1dc57b01c7386fb5da1b1 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 15 Jan 2021 16:28:15 +0000 Subject: [PATCH 0725/1906] UPDATE ::: Adding tomcat jar to allow mvn to work as expected git-svn-id: svn://107.170.10.188:8080/Monolith/dev@42146 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 3a3c7b7b374f27bd039b7f5ee7de08b34ce49a5a --- pom.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pom.xml b/pom.xml index 78f2e1c20..b5135ead4 100644 --- a/pom.xml +++ b/pom.xml @@ -291,6 +291,13 @@ system ${env.JAVA_HOME}/lib/tools.jar + + + + org.apache.tomcat + tomcat-catalina + 9.0.41 + org.antlr antlr-complete From 6ffb68ff42100dbffb057533b4d20a7767e0eedc Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 18 Jan 2021 15:05:36 +0000 Subject: [PATCH 0726/1906] UPDATE ::: Switching to proper jdbc pooling package (HikariCP) UPDATE ::: Getting security to work for postgres database by extracting out constants into the queryUtil class UPDATE ::: Closing connections on security classes after executing the prepared statements on updates git-svn-id: svn://107.170.10.188:8080/Monolith/dev@42172 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: f44eadd9000a005190a8a7494711997785185f47 --- pom.xml | 9 ++++++++- src/prerna/web/conf/AdminStartupFilter.java | 5 ++--- src/prerna/web/conf/NoUserExistsFilter.java | 10 +++++++--- src/prerna/web/conf/UserExistsFilter.java | 5 ++--- 4 files changed, 19 insertions(+), 10 deletions(-) diff --git a/pom.xml b/pom.xml index b5135ead4..075b175f5 100644 --- a/pom.xml +++ b/pom.xml @@ -447,6 +447,12 @@ commons-beanutils 1.9.4 + + com.zaxxer + HikariCP + 3.4.5 + + commons-discovery commons-discovery diff --git a/src/prerna/web/conf/AdminStartupFilter.java b/src/prerna/web/conf/AdminStartupFilter.java index a1edfd921..b9de1e507 100644 --- a/src/prerna/web/conf/AdminStartupFilter.java +++ b/src/prerna/web/conf/AdminStartupFilter.java @@ -24,14 +24,13 @@ public class AdminStartupFilter implements Filter { private static final Logger logger = LogManager.getLogger(AdminStartupFilter.class); - private static final String STACKTRACE = "StackTrace: "; private static String initialRedirect; @Override public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { if (AbstractSecurityUtils.securityEnabled()) { IEngine engine = Utility.getEngine(Constants.SECURITY_DB); - String q = "SELECT * FROM USER LIMIT 1"; + String q = "SELECT * FROM SMSS_USER LIMIT 1"; IRawSelectWrapper wrapper = null; try { wrapper = WrapperManager.getInstance().getRawWrapper(engine, q); @@ -48,7 +47,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 } } } catch (Exception e) { - logger.error(STACKTRACE, e); + logger.error(Constants.STACKTRACE, e); } finally { if (wrapper != null) { wrapper.cleanUp(); diff --git a/src/prerna/web/conf/NoUserExistsFilter.java b/src/prerna/web/conf/NoUserExistsFilter.java index 2b752151c..0b50f3721 100644 --- a/src/prerna/web/conf/NoUserExistsFilter.java +++ b/src/prerna/web/conf/NoUserExistsFilter.java @@ -17,6 +17,8 @@ import prerna.auth.utils.AbstractSecurityUtils; import prerna.engine.api.IEngine; import prerna.engine.api.IRawSelectWrapper; +import prerna.query.querystruct.SelectQueryStruct; +import prerna.query.querystruct.selectors.QueryColumnSelector; import prerna.rdf.engine.wrappers.WrapperManager; import prerna.semoss.web.services.config.AdminConfigService; import prerna.util.Constants; @@ -37,10 +39,12 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 if(!NoUserExistsFilter.userDefined) { IEngine engine = Utility.getEngine(Constants.SECURITY_DB); - String q = "SELECT * FROM USER LIMIT 1"; + SelectQueryStruct qs = new SelectQueryStruct(); + qs.addSelector(new QueryColumnSelector("SMSS_USER__ID")); + qs.setLimit(1); IRawSelectWrapper wrapper = null; try { - wrapper = WrapperManager.getInstance().getRawWrapper(engine, q); + wrapper = WrapperManager.getInstance().getRawWrapper(engine, qs); boolean hasUser = wrapper.hasNext(); // no users at all registered, we need to send to the admin page @@ -69,7 +73,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 NoUserExistsFilter.userDefined = true; } } catch (Exception e) { - logger.error("Stacktrace: ",e); + logger.error(Constants.STACKTRACE,e); } finally { if(wrapper != null) { wrapper.cleanUp(); diff --git a/src/prerna/web/conf/UserExistsFilter.java b/src/prerna/web/conf/UserExistsFilter.java index c1cc52104..f6d857e84 100644 --- a/src/prerna/web/conf/UserExistsFilter.java +++ b/src/prerna/web/conf/UserExistsFilter.java @@ -26,7 +26,6 @@ public class UserExistsFilter extends NoUserInSessionFilter { private static final Logger logger = LogManager.getLogger(UserExistsFilter.class); - private static final String STACKTRACE = "StackTrace: "; @Override public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) @@ -56,7 +55,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 } else { // okay, need to make sure the user is a valid one IEngine engine = Utility.getEngine(Constants.SECURITY_DB); - String q = "SELECT * FROM USER WHERE ID='" + user.getAccessToken(user.getLogins().get(0)).getId() + String q = "SELECT * FROM SMSS_USER WHERE ID='" + user.getAccessToken(user.getLogins().get(0)).getId() + "'"; IRawSelectWrapper wrapper = null; try { @@ -73,7 +72,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 ((HttpServletResponse) arg1).sendError(302, "Need to redirect to " + encodedRedirectUrl); } } catch (Exception e) { - logger.error(STACKTRACE, e); + logger.error(Constants.STACKTRACE, e); } finally { if (wrapper != null) { wrapper.cleanUp(); From d3e69a8428e421b6318e74d8590e8c2899ae3592 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 21 Jan 2021 22:54:47 +0000 Subject: [PATCH 0727/1906] BUGFIX ::: Fixing error with SchedulerFilter grabbing the wrong key git-svn-id: svn://107.170.10.188:8080/Monolith/dev@42265 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: aeadaff576576f77364f819fbdc1af5d6ee5369b --- src/prerna/web/conf/SchedulerFilter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prerna/web/conf/SchedulerFilter.java b/src/prerna/web/conf/SchedulerFilter.java index 560445e0b..19947bd45 100644 --- a/src/prerna/web/conf/SchedulerFilter.java +++ b/src/prerna/web/conf/SchedulerFilter.java @@ -30,7 +30,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 HttpServletRequest request = (HttpServletRequest) arg0; String execId = request.getParameter(JobConfigKeys.EXEC_ID); - String jobName = request.getParameter(JobConfigKeys.JOB_NAME); + String jobName = request.getParameter(JobConfigKeys.JOB_ID); String jobGroup = request.getParameter(JobConfigKeys.JOB_GROUP); // make sure the request is valid From 28757c75fd06f1082e24d157f35baf43825d05f2 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 21 Jan 2021 23:40:12 +0000 Subject: [PATCH 0728/1906] UPDATE ::: Fixing minor formatting and variable name git-svn-id: svn://107.170.10.188:8080/Monolith/dev@42269 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: d72b93ad05d76b547a94a798ca75455e632c7772 --- src/prerna/web/conf/SchedulerFilter.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/prerna/web/conf/SchedulerFilter.java b/src/prerna/web/conf/SchedulerFilter.java index 19947bd45..f185caa3d 100644 --- a/src/prerna/web/conf/SchedulerFilter.java +++ b/src/prerna/web/conf/SchedulerFilter.java @@ -30,7 +30,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 HttpServletRequest request = (HttpServletRequest) arg0; String execId = request.getParameter(JobConfigKeys.EXEC_ID); - String jobName = request.getParameter(JobConfigKeys.JOB_ID); + String jobId = request.getParameter(JobConfigKeys.JOB_ID); String jobGroup = request.getParameter(JobConfigKeys.JOB_GROUP); // make sure the request is valid @@ -40,7 +40,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 logger.info("Could not find the scheduler execution id"); return; } - if(!jobInfo[0].equals(jobName) || !jobInfo[1].equals(jobGroup)) { + if(!jobInfo[0].equals(jobId) || !jobInfo[1].equals(jobGroup)) { // error logger.info("Found scheduler execution id but could not match to details"); return; From 55854ee044c0c070d08842739bce7f736e8b59e4 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 25 Jan 2021 15:25:47 +0000 Subject: [PATCH 0729/1906] UPDATE ::: Pushing patch around adding a shared file path UPDATE ::: Fixing error with printing correct error message git-svn-id: svn://107.170.10.188:8080/Monolith/dev@42318 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 913810ed1d7ae8f2704f02202fff49c5b0201186 --- .../config/ServerConfigurationResource.java | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/prerna/semoss/web/services/config/ServerConfigurationResource.java b/src/prerna/semoss/web/services/config/ServerConfigurationResource.java index 22bc77a88..9e088d8ea 100644 --- a/src/prerna/semoss/web/services/config/ServerConfigurationResource.java +++ b/src/prerna/semoss/web/services/config/ServerConfigurationResource.java @@ -108,16 +108,26 @@ private static void loadConfig(HttpSession session) { try { loadConfig.put("file-limit", Integer.parseInt(fileTransferMax)); } catch (Exception e) { - logger.error("Stack Trace: ", e); + logger.error(Constants.STACKTRACE, e); } } - + + // shared file path + String sharedFilePath = DIHelper.getInstance().getProperty(Constants.SHARED_FILE_PATH); + if (sharedFilePath != null) { + try { + loadConfig.put("fileSharedPath", sharedFilePath); + } catch (Exception e) { + logger.error(Constants.STACKTRACE, e); + } + } + // version of the application try { Map versionMap = VersionReactor.getVersionMap(); loadConfig.put("version", versionMap); } catch (Exception e) { - logger.error("Stack Trace: ", e); + logger.error(Constants.STACKTRACE, e); } // send the default frame type From 964cfdc875d89a04857a98b5105480308aa394a3 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 26 Jan 2021 20:57:08 +0000 Subject: [PATCH 0730/1906] UPDATE ::: Allowing whoami to pass through security git-svn-id: svn://107.170.10.188:8080/Monolith/dev@42380 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 911fe9fe72753f9fc40991aceda3e4920b14444a --- src/prerna/web/conf/NoUserInSessionFilter.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/prerna/web/conf/NoUserInSessionFilter.java b/src/prerna/web/conf/NoUserInSessionFilter.java index 2a72bebed..7977ad732 100644 --- a/src/prerna/web/conf/NoUserInSessionFilter.java +++ b/src/prerna/web/conf/NoUserInSessionFilter.java @@ -66,6 +66,7 @@ public class NoUserInSessionFilter implements Filter { ignoreDueToFE.add("auth/loginsAllowed"); ignoreDueToFE.add("auth/login"); ignoreDueToFE.add("auth/createUser"); + ignoreDueToFE.add("auth//whoami"); for (AuthProvider v : AuthProvider.values()) { ignoreDueToFE.add("auth/userinfo/" + v.toString().toLowerCase()); ignoreDueToFE.add("auth/login/" + v.toString().toLowerCase()); From 3bdee179dc930b570cbd75ad161a175c205eebf6 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 26 Jan 2021 21:01:12 +0000 Subject: [PATCH 0731/1906] BUGFIX ::: Had an extra / in the whoami path git-svn-id: svn://107.170.10.188:8080/Monolith/dev@42381 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: e8c218774882503d746e200754238cd202c32165 --- src/prerna/web/conf/NoUserInSessionFilter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prerna/web/conf/NoUserInSessionFilter.java b/src/prerna/web/conf/NoUserInSessionFilter.java index 7977ad732..d4f4036c4 100644 --- a/src/prerna/web/conf/NoUserInSessionFilter.java +++ b/src/prerna/web/conf/NoUserInSessionFilter.java @@ -66,7 +66,7 @@ public class NoUserInSessionFilter implements Filter { ignoreDueToFE.add("auth/loginsAllowed"); ignoreDueToFE.add("auth/login"); ignoreDueToFE.add("auth/createUser"); - ignoreDueToFE.add("auth//whoami"); + ignoreDueToFE.add("auth/whoami"); for (AuthProvider v : AuthProvider.values()) { ignoreDueToFE.add("auth/userinfo/" + v.toString().toLowerCase()); ignoreDueToFE.add("auth/login/" + v.toString().toLowerCase()); From 651836dfa88d4e82de98853f19bf2b76139b82fd Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 27 Jan 2021 19:37:34 +0000 Subject: [PATCH 0732/1906] BUGFIX ::: cleaning up code around writing/editing templates in an app folder BUGFIX ::: fixing error with exports to not accidently process footers/headers sheets from templates git-svn-id: svn://107.170.10.188:8080/Monolith/dev@42406 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 1714537d9c7dfe74f445adb4cb05de0bed18f411 --- src/prerna/upload/FileUploader.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/prerna/upload/FileUploader.java b/src/prerna/upload/FileUploader.java index 63a929d29..50e19e1f0 100644 --- a/src/prerna/upload/FileUploader.java +++ b/src/prerna/upload/FileUploader.java @@ -185,8 +185,10 @@ public Response checkUserDefinedHeaders(MultivaluedMap form) { @POST @Path("baseUpload") - public Response uploadFile(@Context ServletContext context, @Context HttpServletRequest request, @QueryParam("insightId") String insightId, - @QueryParam("path") String relativePath, @QueryParam("appId") String appId) { + public Response baseUpload(@Context ServletContext context, @Context HttpServletRequest request, + @QueryParam("insightId") String insightId, + @QueryParam("path") String relativePath, + @QueryParam("appId") String appId) { Insight in = InsightStore.getInstance().get(insightId); if(in == null) { HashMap errorMap = new HashMap(); @@ -261,7 +263,7 @@ public Response uploadFile(@Context ServletContext context, @Context HttpServlet private List> getBaseUploadData(List fileItems, Insight in, String relativePath, String appId) { // get base asset folder String assetFolder = null; - String fePath = Insight.getInsightRelativeFolderKey(); + String fePath = DIR_SEPARATOR; if (appId != null) { assetFolder = AssetUtility.getAssetBasePath(in, appId, true); } else { @@ -271,7 +273,7 @@ private List> getBaseUploadData(List fileItems, In // add relative path if (relativePath != null) { filePath = assetFolder + DIR_SEPARATOR + relativePath; - fePath += DIR_SEPARATOR + relativePath; + fePath += relativePath; } File fileDir = new File(filePath); if (!fileDir.exists()) { From 246f9688f39a4e198139d7557724878fd9cfe905 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 27 Jan 2021 21:04:08 +0000 Subject: [PATCH 0733/1906] UPDATE ::: Making error message keys consistent with rest of application git-svn-id: svn://107.170.10.188:8080/Monolith/dev@42410 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 608b0c05fcfce085f8c6a2f16e42c2a12d86b2c9 --- .../web/services/local/UserResource.java | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index ad6891645..189276f5e 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -384,14 +384,14 @@ public Response userinfoGoogle(@Context HttpServletRequest request) { String accessString = null; try { if (user == null) { - ret.put("ERROR", "Log into your Google account"); + ret.put(Constants.ERROR_MESSAGE, "Log into your Google account"); return WebUtility.getResponse(ret, 200); } else { AccessToken googleToken = user.getAccessToken(AuthProvider.GOOGLE); accessString = googleToken.getAccess_token(); } } catch (Exception e) { - ret.put("ERROR", "Log into your Google account"); + ret.put(Constants.ERROR_MESSAGE, "Log into your Google account"); return WebUtility.getResponse(ret, 200); } @@ -431,7 +431,7 @@ public Response userinfoOneDrive(@Context HttpServletRequest request) { String accessString = null; try { if (user == null) { - ret.put("ERROR", "Log into your Microsoft account"); + ret.put(Constants.ERROR_MESSAGE, "Log into your Microsoft account"); } else { AccessToken msToken = user.getAccessToken(AuthProvider.MS); accessString = msToken.getAccess_token(); @@ -444,7 +444,7 @@ public Response userinfoOneDrive(@Context HttpServletRequest request) { } return WebUtility.getResponse(ret, 200); } catch (Exception e) { - ret.put("ERROR", "Log into your Microsoft account"); + ret.put(Constants.ERROR_MESSAGE, "Log into your Microsoft account"); return WebUtility.getResponse(ret, 200); } } @@ -464,14 +464,14 @@ public Response userinfoDropbox(@Context HttpServletRequest request) { String accessString = null; try { if (user == null) { - ret.put("ERROR", "Log into your DropBox account"); + ret.put(Constants.ERROR_MESSAGE, "Log into your DropBox account"); return WebUtility.getResponse(ret, 200); } else { AccessToken dropToken = user.getAccessToken(AuthProvider.DROPBOX); accessString = dropToken.getAccess_token(); } } catch (Exception e) { - ret.put("ERROR", "Log into your DropBox account"); + ret.put(Constants.ERROR_MESSAGE, "Log into your DropBox account"); return WebUtility.getResponse(ret, 200); } String url = "https://api.dropboxapi.com/2/users/get_current_account"; @@ -509,14 +509,14 @@ public Response userinfoGithub(@Context HttpServletRequest request) { String accessString = null; try { if (user == null) { - ret.put("ERROR", "Log into your Github account"); + ret.put(Constants.ERROR_MESSAGE, "Log into your Github account"); return WebUtility.getResponse(ret, 200); } else { AccessToken gitToken = user.getAccessToken(AuthProvider.GITHUB); accessString = gitToken.getAccess_token(); } } catch (Exception e) { - ret.put("ERROR", "Log into your Github account"); + ret.put(Constants.ERROR_MESSAGE, "Log into your Github account"); return WebUtility.getResponse(ret, 200); } @@ -1492,7 +1492,7 @@ public Response loginNative(@Context HttpServletRequest request, @Context HttpSe Boolean disableRedirect = Boolean.parseBoolean(request.getParameter("enableRedirect") + ""); if(username == null || password == null || username.isEmpty() || password.isEmpty()) { - ret.put("error", "The user name or password are empty"); + ret.put(Constants.ERROR_MESSAGE, "The user name or password are empty"); return WebUtility.getResponse(ret, 401); } @@ -1519,12 +1519,12 @@ public Response loginNative(@Context HttpServletRequest request, @Context HttpSe setMainPageRedirect(request, response, redirect); } } else { - ret.put("error", "The user name or password are invalid."); + ret.put(Constants.ERROR_MESSAGE, "The user name or password are invalid."); return WebUtility.getResponse(ret, 401); } } catch (Exception e) { logger.error(Constants.STACKTRACE, e); - ret.put("error", "An unexpected error happened. Please try again."); + ret.put(Constants.ERROR_MESSAGE, "An unexpected error happened. Please try again."); return WebUtility.getResponse(ret, 500); } @@ -1562,16 +1562,16 @@ public Response createUser(@Context HttpServletRequest request) { ret.put("username", username); return WebUtility.getResponse(ret, 200); } else { - ret.put("error", "The user name or email aready exists."); + ret.put(Constants.ERROR_MESSAGE, "The user name or email aready exists."); return WebUtility.getResponse(ret, 400); } } catch (IllegalArgumentException iae) { logger.error(Constants.STACKTRACE, iae); - ret.put("error", iae.getMessage()); + ret.put(Constants.ERROR_MESSAGE, iae.getMessage()); return WebUtility.getResponse(ret, 500); } catch (Exception e) { logger.error(Constants.STACKTRACE, e); - ret.put("error", "An unexpected error happened. Please try again."); + ret.put(Constants.ERROR_MESSAGE, "An unexpected error happened. Please try again."); return WebUtility.getResponse(ret, 500); } } @@ -1661,7 +1661,7 @@ public synchronized Response modifyLoginProperties(@PathParam("provider") String } catch (ConfigurationException e1) { logger.error(Constants.STACKTRACE, e1); Hashtable errorRet = new Hashtable<>(); - errorRet.put("error", + errorRet.put(Constants.ERROR_MESSAGE, "An unexpected error happened trying to access the properties. Please try again or reach out to server admin."); return WebUtility.getResponse(errorRet, 500); } @@ -1676,7 +1676,7 @@ public synchronized Response modifyLoginProperties(@PathParam("provider") String } catch (ConfigurationException e1) { logger.error(Constants.STACKTRACE, e1); Hashtable errorRet = new Hashtable<>(); - errorRet.put("error", + errorRet.put(Constants.ERROR_MESSAGE, "An unexpected error happened when saving the new login properties. Please try again or reach out to server admin."); return WebUtility.getResponse(errorRet, 500); } @@ -1863,7 +1863,7 @@ public Response show(@Context HttpServletRequest request, @Context HttpServletRe } } if(output.isEmpty()) { - output.put("error", "null principal"); + output.put(Constants.ERROR_MESSAGE, "null principal"); } } return WebUtility.getResponse(output, 200); From e0d960fd91f6531f5eaa29b83ee5e6eeba312a3f Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 28 Jan 2021 01:23:25 +0000 Subject: [PATCH 0734/1906] UPDATE ::: Commenting out debug logs BUGFIX ::: Fixing error with scheduler not working with r in user r server mode due to null pointer on starting R git-svn-id: svn://107.170.10.188:8080/Monolith/dev@42420 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: edc244a066cff64918573b00e64e127bd5f5f52e --- src/prerna/web/conf/SchedulerFilter.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/prerna/web/conf/SchedulerFilter.java b/src/prerna/web/conf/SchedulerFilter.java index f185caa3d..17e54d3a4 100644 --- a/src/prerna/web/conf/SchedulerFilter.java +++ b/src/prerna/web/conf/SchedulerFilter.java @@ -1,6 +1,7 @@ package prerna.web.conf; import java.io.IOException; +import java.util.UUID; import javax.servlet.Filter; import javax.servlet.FilterChain; @@ -64,7 +65,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 AccessToken token = new AccessToken(); token.setProvider(provider); token.setId(id); - + token.setName("scheduler_" + UUID.randomUUID()); user.setAccessToken(token); } session.setAttribute(Constants.SESSION_USER, user); From f8eed622737d1ff52ebacf537ccfecd4c603d90c Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 28 Jan 2021 15:06:59 +0000 Subject: [PATCH 0735/1906] UPDATE ::: Exposing pivot size restrictions in constants UPDATE ::: Adding is empty check on shared file path value git-svn-id: svn://107.170.10.188:8080/Monolith/dev@42427 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: e78fc1a82cf49149260e55c4c084ecf5496ac68d --- .../semoss/web/services/config/ServerConfigurationResource.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prerna/semoss/web/services/config/ServerConfigurationResource.java b/src/prerna/semoss/web/services/config/ServerConfigurationResource.java index 9e088d8ea..d73990edf 100644 --- a/src/prerna/semoss/web/services/config/ServerConfigurationResource.java +++ b/src/prerna/semoss/web/services/config/ServerConfigurationResource.java @@ -114,7 +114,7 @@ private static void loadConfig(HttpSession session) { // shared file path String sharedFilePath = DIHelper.getInstance().getProperty(Constants.SHARED_FILE_PATH); - if (sharedFilePath != null) { + if (sharedFilePath != null && !sharedFilePath.isEmpty()) { try { loadConfig.put("fileSharedPath", sharedFilePath); } catch (Exception e) { From 43f16df25872d921b4a497b5302c61bff7f4e7e7 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 29 Jan 2021 17:51:00 +0000 Subject: [PATCH 0736/1906] UPDATE ::: Changing the name of the scheduler h2 database utility class to remove the h2 in the name BUGFIX ::: Fixing error with edit scheduled job for using the jobId git-svn-id: svn://107.170.10.188:8080/Monolith/dev@42459 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: da2201be0de112fec4204dbb4ad1a3edaffceb3d --- src/prerna/web/conf/DBLoader.java | 9 ++++----- src/prerna/web/conf/SchedulerFilter.java | 6 +++--- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/prerna/web/conf/DBLoader.java b/src/prerna/web/conf/DBLoader.java index dc505c2cf..4031b9502 100644 --- a/src/prerna/web/conf/DBLoader.java +++ b/src/prerna/web/conf/DBLoader.java @@ -50,8 +50,8 @@ import prerna.om.InsightStore; import prerna.sablecc2.reactor.frame.r.util.PyTranslatorFactory; import prerna.sablecc2.reactor.frame.r.util.RJavaTranslatorFactory; +import prerna.sablecc2.reactor.scheduler.SchedulerDatabaseUtility; import prerna.sablecc2.reactor.scheduler.SchedulerFactorySingleton; -import prerna.sablecc2.reactor.scheduler.SchedulerH2DatabaseUtility; import prerna.sablecc2.reactor.scheduler.legacy.JsonConversionToQuartzJob; import prerna.util.AbstractFileWatcher; import prerna.util.ChromeDriverUtility; @@ -198,14 +198,13 @@ public void contextInitialized(ServletContextEvent arg0) { // Load and run triggerOnLoad jobs if(scheduler != null) { try { - SchedulerH2DatabaseUtility.executeAllTriggerOnLoads(); - // also add legacy json files - JsonConversionToQuartzJob.runUpdateFromLegacyFormat(); + SchedulerDatabaseUtility.executeAllTriggerOnLoads(); + // also add legacy json files + JsonConversionToQuartzJob.runUpdateFromLegacyFormat(); } catch(Exception e) { // ignore } } - } } diff --git a/src/prerna/web/conf/SchedulerFilter.java b/src/prerna/web/conf/SchedulerFilter.java index 17e54d3a4..c6237594c 100644 --- a/src/prerna/web/conf/SchedulerFilter.java +++ b/src/prerna/web/conf/SchedulerFilter.java @@ -19,7 +19,7 @@ import prerna.auth.AuthProvider; import prerna.auth.User; import prerna.rpa.config.JobConfigKeys; -import prerna.sablecc2.reactor.scheduler.SchedulerH2DatabaseUtility; +import prerna.sablecc2.reactor.scheduler.SchedulerDatabaseUtility; import prerna.util.Constants; public class SchedulerFilter implements Filter { @@ -35,7 +35,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 String jobGroup = request.getParameter(JobConfigKeys.JOB_GROUP); // make sure the request is valid - String[] jobInfo = SchedulerH2DatabaseUtility.executionIdExists(execId); + String[] jobInfo = SchedulerDatabaseUtility.executionIdExists(execId); if(jobInfo == null) { // error logger.info("Could not find the scheduler execution id"); @@ -71,7 +71,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 session.setAttribute(Constants.SESSION_USER, user); // clean up the table - SchedulerH2DatabaseUtility.removeExecutionId(execId); + SchedulerDatabaseUtility.removeExecutionId(execId); // continue arg2.doFilter(arg0, arg1); From e5a410336e3ae6e1db124aadb5d72a03de9b185e Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 2 Feb 2021 22:29:21 +0000 Subject: [PATCH 0737/1906] UPDATE ::: Not deleting export files when generated via the scheduler git-svn-id: svn://107.170.10.188:8080/Monolith/dev@42512 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 7d7ac70896198751cfb286e36d6a1e2d2693f245 --- .../semoss/web/services/local/NameServer.java | 16 +++++++++----- .../web/services/local/SchedulerResource.java | 22 +++++++++++++------ 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index 323a32b3c..54d76c00d 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -100,7 +100,6 @@ import prerna.util.PlaySheetRDFMapBasedEnum; import prerna.util.Utility; import prerna.util.gson.GsonUtility; -import prerna.web.conf.NoUserInSessionFilter; import prerna.web.services.util.ResponseHashSingleton; import prerna.web.services.util.SemossExecutorSingleton; import prerna.web.services.util.SemossThread; @@ -317,7 +316,7 @@ public Response runPixelSync(@Context HttpServletRequest request) { String jobId = ""; String insightId = request.getParameter("insightId"); String expression = request.getParameter("expression"); - + // figure out the type of insight // first is temp if (insightId == null || insightId.toString().isEmpty() || insightId.equals("undefined")) { @@ -325,13 +324,15 @@ public Response runPixelSync(@Context HttpServletRequest request) { insight = new Insight(); insight.setBaseURL(getServerURL(request)); insight.setInsightId(insightId); - } else if (insightId.equals("new")) { // need to make a new insight here + } else if (insightId.equals("new")) { + // need to make a new insight here insight = new Insight(); insight.setBaseURL(getServerURL(request)); InsightStore.getInstance().put(insight); insightId = insight.getInsightId(); InsightStore.getInstance().addToSessionHash(sessionId, insightId); - } else {// or just get it from the store + } else { + // or just get it from the store // the session id needs to be checked // you better have a valid id... or else... O_O insight = InsightStore.getInstance().get(insightId); @@ -344,7 +345,12 @@ public Response runPixelSync(@Context HttpServletRequest request) { } // set the user insight.setUser(user); - + // set if we are scheduler mode + Boolean schedulerMode = ThreadStore.isSchedulerMode(); + if(schedulerMode != null) { + insight.setSchedulerMode(schedulerMode); + } + // are we running runPixel in runPixel on the same insight? { String logStr = request.getParameter("dropLogging"); diff --git a/src/prerna/semoss/web/services/local/SchedulerResource.java b/src/prerna/semoss/web/services/local/SchedulerResource.java index 16e12265a..a53e2ef7a 100644 --- a/src/prerna/semoss/web/services/local/SchedulerResource.java +++ b/src/prerna/semoss/web/services/local/SchedulerResource.java @@ -10,6 +10,7 @@ import javax.ws.rs.core.Context; import javax.ws.rs.core.Response; +import prerna.om.ThreadStore; import prerna.rpa.config.JobConfigKeys; import prerna.web.requests.OverrideParametersServletRequest; @@ -33,19 +34,26 @@ public Response executePixel(@Context HttpServletRequest request) { * @return */ private Response runPixel(@Context HttpServletRequest request, String pixel) { - if(pixel.endsWith(";")) { - pixel = pixel + "DropInsight();"; - } else { - pixel = pixel + ";DropInsight();"; - } + // do not need this - will invalidate the session +// if(pixel.endsWith(";")) { +// pixel = pixel + "DropInsight();"; +// } else { +// pixel = pixel + ";DropInsight();"; +// } +// + // set we are scheduler mode + ThreadStore.setSchedulerMode(true); NameServer ns = new NameServer(); OverrideParametersServletRequest requestWrapper = new OverrideParametersServletRequest(request); Map paramMap = new HashMap(); paramMap.put("expression", pixel); requestWrapper.setParameters(paramMap); - return ns.runPixelSync(requestWrapper); + try { + return ns.runPixelSync(requestWrapper); + } finally { + request.getSession().invalidate(); + } } - } From 57b2ae398db058d9531fcef1fb6e167be515510e Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 3 Feb 2021 02:49:24 +0000 Subject: [PATCH 0738/1906] UPDATE ::: Adding new file logic to be able to ignore which files will be deleted or not deleted when the insight/session is removed git-svn-id: svn://107.170.10.188:8080/Monolith/dev@42515 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: a47cdc9574fc3c0908bd090830f1ca1d2986fa9c --- .../web/services/local/DataframeResource.java | 45 +++++++++---------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/src/prerna/semoss/web/services/local/DataframeResource.java b/src/prerna/semoss/web/services/local/DataframeResource.java index eb548a408..62eaddfd9 100644 --- a/src/prerna/semoss/web/services/local/DataframeResource.java +++ b/src/prerna/semoss/web/services/local/DataframeResource.java @@ -5,7 +5,6 @@ import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; -import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; @@ -77,28 +76,28 @@ public Response doMethod(@PathParam("method") String method, MultivaluedMap retMap = new HashMap(); - if(insight.getFilesUsedInInsight() == null || insight.getFilesUsedInInsight().isEmpty()) { - retMap.put("isDbInsight", true); - } else { - retMap.put("isDbInsight", false); - } - return WebUtility.getResponse(retMap, 200); - } - +// @GET +// @Path("/isDbInsight") +// @Produces("application/json") +// public Response isDbInsight(@Context HttpServletRequest request){ +// /* +// * This method is used to determine if the insight has data that has been inserted +// * into the frame that does not currently sit in a full-fledged database. +// * An example of this is when an insight contains data that was added via a csv file. +// * +// * We refer to these insights as nonDbInsights even if they contain data that +// * does contain some information from full dbs +// */ +// +// Map retMap = new HashMap(); +// if(insight.getFilesUsedInInsight() == null || insight.getFilesUsedInInsight().isEmpty()) { +// retMap.put("isDbInsight", true); +// } else { +// retMap.put("isDbInsight", false); +// } +// return WebUtility.getResponse(retMap, 200); +// } +// // /* // * Ideally this should go into the data frame // */ From 358126d139ece32aeeaa83c915f20f60333ebb2e Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 5 Feb 2021 00:30:40 +0000 Subject: [PATCH 0739/1906] UPDATE ::: Making sure the pixel ends with ";" for scheduled jobs git-svn-id: svn://107.170.10.188:8080/Monolith/dev@42561 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 7b3a55d3b3e8fc4ba6b0c4950ee9f907d07fba37 --- src/prerna/semoss/web/services/local/SchedulerResource.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/prerna/semoss/web/services/local/SchedulerResource.java b/src/prerna/semoss/web/services/local/SchedulerResource.java index a53e2ef7a..fd949792a 100644 --- a/src/prerna/semoss/web/services/local/SchedulerResource.java +++ b/src/prerna/semoss/web/services/local/SchedulerResource.java @@ -41,6 +41,10 @@ private Response runPixel(@Context HttpServletRequest request, String pixel) { // pixel = pixel + ";DropInsight();"; // } // + pixel = pixel.trim(); + if(!pixel.endsWith(";")) { + pixel = pixel + ";"; + } // set we are scheduler mode ThreadStore.setSchedulerMode(true); From 8f0fecf0d8fa0b05babecb55e3d26a75d3d7fd37 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 5 Feb 2021 00:37:32 +0000 Subject: [PATCH 0740/1906] UPDATE ::: Improving the log so that we do not keep writing unnecessary session removals for calls that dont generate a session git-svn-id: svn://107.170.10.188:8080/Monolith/dev@42564 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: c8f4d0fa1e5e665d6b91203c22c805c506a73b92 --- src/prerna/web/conf/UserSessionLoader.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/prerna/web/conf/UserSessionLoader.java b/src/prerna/web/conf/UserSessionLoader.java index 87560c90e..ffe56b0a2 100644 --- a/src/prerna/web/conf/UserSessionLoader.java +++ b/src/prerna/web/conf/UserSessionLoader.java @@ -44,7 +44,11 @@ public void sessionDestroyed(HttpSessionEvent sessionEvent) { String sessionId = session.getId(); User thisUser = (User) session.getAttribute(Constants.SESSION_USER); if(thisUser == null) { - logger.info(sessionId + " >>> Unknown user ending session"); + // no need to log a new session that is auto dropped + // this just keeps writting to the log + if(!session.isNew()) { + logger.info(sessionId + " >>> Unknown user ending session"); + } } else { logger.info(sessionId + " >>> User " + User.getSingleLogginName(thisUser) + " ending session"); } From a0f912a0e234e3921c4cf95b6515c32d5f530efa Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 5 Feb 2021 00:38:12 +0000 Subject: [PATCH 0741/1906] UPDATE ::: Cleaning the comment in code for last commit git-svn-id: svn://107.170.10.188:8080/Monolith/dev@42565 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 164c6efbfbfca8cab138163b9f608b3a1fa01c41 --- src/prerna/web/conf/UserSessionLoader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prerna/web/conf/UserSessionLoader.java b/src/prerna/web/conf/UserSessionLoader.java index ffe56b0a2..37259590c 100644 --- a/src/prerna/web/conf/UserSessionLoader.java +++ b/src/prerna/web/conf/UserSessionLoader.java @@ -45,7 +45,7 @@ public void sessionDestroyed(HttpSessionEvent sessionEvent) { User thisUser = (User) session.getAttribute(Constants.SESSION_USER); if(thisUser == null) { // no need to log a new session that is auto dropped - // this just keeps writting to the log + // this just keeps writing to the log if(!session.isNew()) { logger.info(sessionId + " >>> Unknown user ending session"); } From c5e06be031dd00beebf3adf4a09246566b4f6d8f Mon Sep 17 00:00:00 2001 From: kunalppatel9 Date: Fri, 5 Feb 2021 16:18:51 +0000 Subject: [PATCH 0742/1906] BUGFIX ::: fixing import of PyTranslatorFactory git-svn-id: svn://107.170.10.188:8080/Monolith/dev@42579 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 0aa9859f752bd14701f2babb6e30d036e8de378c --- src/prerna/web/conf/DBLoader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prerna/web/conf/DBLoader.java b/src/prerna/web/conf/DBLoader.java index 4031b9502..c578a9cea 100644 --- a/src/prerna/web/conf/DBLoader.java +++ b/src/prerna/web/conf/DBLoader.java @@ -48,7 +48,7 @@ import prerna.nameserver.utility.MasterDatabaseUtility; import prerna.om.Insight; import prerna.om.InsightStore; -import prerna.sablecc2.reactor.frame.r.util.PyTranslatorFactory; +import prerna.sablecc2.reactor.frame.py.PyTranslatorFactory; import prerna.sablecc2.reactor.frame.r.util.RJavaTranslatorFactory; import prerna.sablecc2.reactor.scheduler.SchedulerDatabaseUtility; import prerna.sablecc2.reactor.scheduler.SchedulerFactorySingleton; From 98bbfe15899121c03466b722fe7ceadcde8d4d49 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 15 Feb 2021 17:14:05 +0000 Subject: [PATCH 0743/1906] UPDATE ::: Adding additional log to determine session invalidate BUGFIX ::: Adding correct user table in cac filter git-svn-id: svn://107.170.10.188:8080/Monolith/dev@42666 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 0f4bbf7447e02d8b71a71202aa9f7c4bff43f2d2 --- .../semoss/web/services/local/ResourceUtility.java | 2 +- .../semoss/web/services/local/SessionResource.java | 14 ++++++++++---- src/prerna/web/conf/CACFilter.java | 6 +++--- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/prerna/semoss/web/services/local/ResourceUtility.java b/src/prerna/semoss/web/services/local/ResourceUtility.java index 2933fd8f7..4b0626840 100644 --- a/src/prerna/semoss/web/services/local/ResourceUtility.java +++ b/src/prerna/semoss/web/services/local/ResourceUtility.java @@ -55,7 +55,7 @@ public static String getClientIp(@Context HttpServletRequest request) { * @return */ public static String getLogMessage(HttpServletRequest request, HttpSession session, String userId, String message) { - if(userId.isEmpty()) { + if(userId == null || userId.isEmpty()) { return "IP = " + Utility.cleanLogString(ResourceUtility.getClientIp(request)) + " : Session = " + session.getId() + " : ID = INVALID " + message; } return "IP = " + Utility.cleanLogString(ResourceUtility.getClientIp(request)) + " : Session = " + session.getId() + " : ID = " + userId + " " + message; diff --git a/src/prerna/semoss/web/services/local/SessionResource.java b/src/prerna/semoss/web/services/local/SessionResource.java index ab991c2cf..05e31b90d 100644 --- a/src/prerna/semoss/web/services/local/SessionResource.java +++ b/src/prerna/semoss/web/services/local/SessionResource.java @@ -215,7 +215,16 @@ public void invalidateSession(@Context HttpServletRequest request, @Context Http throws IOException { String redirectUrl = request.getHeader("referer"); response.setStatus(302); - + + HttpSession session = request.getSession(false); + User thisUser = null; + if(session != null) { + thisUser = (User) session.getAttribute(Constants.SESSION_USER); + } + + // log the user logout + logger.info(ResourceUtility.getLogMessage(request, session, User.getSingleLogginName(thisUser), "is being forceably invalidated")); + // redirect to login/logout page if (DBLoader.useLogoutPage()) { logger.info("Session ended. Redirect to logout page"); @@ -255,12 +264,9 @@ public void invalidateSession(@Context HttpServletRequest request, @Context Http response.sendError(302, "Need to redirect to " + encodedRedirectUrl); } - HttpSession session = request.getSession(false); if (session != null) { logger.info("User is no longer logged in"); logger.info("Removing user object from session"); - session.removeAttribute(Constants.SESSION_USER); - session.invalidate(); } } diff --git a/src/prerna/web/conf/CACFilter.java b/src/prerna/web/conf/CACFilter.java index 6ccdbc436..813b7eb25 100644 --- a/src/prerna/web/conf/CACFilter.java +++ b/src/prerna/web/conf/CACFilter.java @@ -246,7 +246,7 @@ private void setInitParams(ServletRequest arg0) { if(updateUserStr != null) { CACFilter.updateUser = Boolean.parseBoolean(updateUserStr); } else { - // Default value is true + // Default value is false CACFilter.updateUser = false; } @@ -314,7 +314,7 @@ private void updateCacUsersStorage(String previousId, String newId) { RDBMSNativeEngine securityDb = (RDBMSNativeEngine) Utility.getEngine(Constants.SECURITY_DB); // let us not try to run this multiple times... - String requireUpdateQuery = "SELECT * FROM USER WHERE ID='" + cleanOldId +"'"; + String requireUpdateQuery = "SELECT * FROM SMSS_USER WHERE ID='" + cleanOldId +"'"; IRawSelectWrapper wrapper = null; try { wrapper = WrapperManager.getInstance().getRawWrapper(securityDb, requireUpdateQuery); @@ -323,7 +323,7 @@ private void updateCacUsersStorage(String previousId, String newId) { // from id to email if(wrapper.hasNext()) { // need to update all the places the user id is used - String updateQuery = "UPDATE USER SET ID='" + cleanNewId +"' WHERE ID='" + cleanOldId + "'"; + String updateQuery = "UPDATE SMSS_USER SET ID='" + cleanNewId +"' WHERE ID='" + cleanOldId + "'"; try { securityDb.insertData(updateQuery); } catch (SQLException e) { From 2777a141fb5b4b1fb288dc8883bfdf5119787894 Mon Sep 17 00:00:00 2001 From: kunalppatel9 Date: Mon, 15 Feb 2021 23:02:16 +0000 Subject: [PATCH 0744/1906] UPDATE ::: adding jars for zookeeper and curator git-svn-id: svn://107.170.10.188:8080/Monolith/dev@42672 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 2e87e4081f976c0bf8324e702181d3a6ec152d97 --- pom.xml | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/pom.xml b/pom.xml index 075b175f5..104f13ff2 100644 --- a/pom.xml +++ b/pom.xml @@ -1935,5 +1935,29 @@ commons-exec 1.3 + + + org.apache.curator + curator-framework + 5.1.0 + + + + org.apache.curator + curator-client + 5.1.0 + + + + org.apache.curator + curator-recipes + 5.1.0 + + + + org.apache.zookeeper + zookeeper + 3.6.2 + \ No newline at end of file From 20a921e62ff7824ede52daa00446a371d4a5e4c3 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 16 Feb 2021 21:54:10 +0000 Subject: [PATCH 0745/1906] UPDATE ::: Adding a check to ensure the session id still exists that sits within the mapper git-svn-id: svn://107.170.10.188:8080/Monolith/dev@42685 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 8b1f23ea13c01ce2fd6a2263a6e3f67273b5fba9 --- .../NoUserInSessionTrustedTokenFilter.java | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java b/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java index 46223dc55..054a33bd5 100644 --- a/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java +++ b/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java @@ -18,6 +18,7 @@ import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; +import org.apache.catalina.session.StandardManager; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -27,6 +28,7 @@ import prerna.auth.utils.AbstractSecurityUtils; import prerna.auth.utils.SecurityQueryUtils; import prerna.cluster.util.ClusterUtil; +import prerna.semoss.web.services.local.SessionResource; import prerna.util.Constants; import prerna.util.Utility; @@ -76,7 +78,19 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 // if the token exists String userId = req.getParameter(tokenName); if(userId != null) { - if(!sessionMapper.containsKey(userId)) { + boolean redirectToExistingSession = false; + String redirectSessionId = sessionMapper.get(userId); + if(redirectSessionId != null) { + // validate that the session exists within tomcats session manager + StandardManager manager = SessionResource.getManager((HttpServletRequest) arg0); + if(manager.getSession(redirectSessionId) != null) { + redirectToExistingSession = true; + } else { + // remove from the session mapper + sessionMapper.remove(userId); + } + } + if(!redirectToExistingSession) { // grab the ip address String ipAddress = req.getHeader("X-FORWARDED-FOR"); if (ipAddress == null) { @@ -121,8 +135,9 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 ((HttpServletResponse) arg1).addHeader("Set-Cookie", setCookieString); } } else { - // this is the class where you redirect - String redirectSessionId = (String) sessionMapper.get(userId); + // this is the case where you redirect + // we have also validated that the session id is active + // add the session id cookie // Cookie k = new Cookie(DBLoader.getSessionIdKey(), redirectSessionId); // k.setHttpOnly(true); From b433d8f6e789c2b72b44f13c60a09586057c7cb2 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 17 Feb 2021 02:03:38 +0000 Subject: [PATCH 0746/1906] BUGFIX ::: Forgot to push BE monolith class during previous type change fix git-svn-id: svn://107.170.10.188:8080/Monolith/dev@42696 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 7239eb5de44116aa547ff3900c2aab2addd25862 --- src/prerna/semoss/web/services/local/RunInsight.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/prerna/semoss/web/services/local/RunInsight.java b/src/prerna/semoss/web/services/local/RunInsight.java index 37c761bce..5eb1b7119 100644 --- a/src/prerna/semoss/web/services/local/RunInsight.java +++ b/src/prerna/semoss/web/services/local/RunInsight.java @@ -5,7 +5,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Set; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.POST; @@ -108,7 +107,7 @@ public Response recreateInsightState(@Context HttpServletRequest request) { // add all the frame headers to the payload first try { VarStore vStore = in.getVarStore(); - Set keys = vStore.getFrameKeys(); + List keys = vStore.getFrameKeys(); for(String k : keys) { NounMetadata noun = vStore.get(k); PixelDataType type = noun.getNounType(); From 0d2e8b79b11f6b417711ac484622f0d3d0548883 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 17 Feb 2021 15:22:16 +0000 Subject: [PATCH 0747/1906] BUGFIX ::: Adding null pointer check in case of no session git-svn-id: svn://107.170.10.188:8080/Monolith/dev@42704 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 4dcffa9bfff178ba1532ec2641ad7572eb43ee84 --- src/prerna/semoss/web/services/local/ResourceUtility.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/prerna/semoss/web/services/local/ResourceUtility.java b/src/prerna/semoss/web/services/local/ResourceUtility.java index 4b0626840..e5f85814c 100644 --- a/src/prerna/semoss/web/services/local/ResourceUtility.java +++ b/src/prerna/semoss/web/services/local/ResourceUtility.java @@ -55,10 +55,14 @@ public static String getClientIp(@Context HttpServletRequest request) { * @return */ public static String getLogMessage(HttpServletRequest request, HttpSession session, String userId, String message) { + String sessionId = "NO SESSION"; + if(session != null) { + sessionId = session.getId(); + } if(userId == null || userId.isEmpty()) { - return "IP = " + Utility.cleanLogString(ResourceUtility.getClientIp(request)) + " : Session = " + session.getId() + " : ID = INVALID " + message; + return "IP = " + Utility.cleanLogString(ResourceUtility.getClientIp(request)) + " : Session = " + sessionId + " : USERID = INVALID " + message; } - return "IP = " + Utility.cleanLogString(ResourceUtility.getClientIp(request)) + " : Session = " + session.getId() + " : ID = " + userId + " " + message; + return "IP = " + Utility.cleanLogString(ResourceUtility.getClientIp(request)) + " : Session = " + sessionId + " : USERID = " + userId + " " + message; } } From da12927bb1ef5d0ddbcae5358e3851db0398b834 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 17 Feb 2021 18:20:30 +0000 Subject: [PATCH 0748/1906] UPDATE ::: Sending sessionTimeRemaining to debug logout issues git-svn-id: svn://107.170.10.188:8080/Monolith/dev@42707 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 446237dde17277d06e32ad10b09b3d79acf54864 --- .../config/ServerConfigurationResource.java | 6 ++++-- .../semoss/web/services/local/NameServer.java | 13 ++++++++----- .../semoss/web/services/local/RunInsight.java | 2 +- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/prerna/semoss/web/services/config/ServerConfigurationResource.java b/src/prerna/semoss/web/services/config/ServerConfigurationResource.java index d73990edf..5e19cf0c3 100644 --- a/src/prerna/semoss/web/services/config/ServerConfigurationResource.java +++ b/src/prerna/semoss/web/services/config/ServerConfigurationResource.java @@ -72,8 +72,6 @@ private static Map getConfig(@Context HttpServletRequest request private static void loadConfig(HttpSession session) { Map loadConfig = new HashMap<>(); - // session timeout - loadConfig.put("timeout", (double) session.getMaxInactiveInterval() / 60); // r enabled boolean useR = true; @@ -168,6 +166,10 @@ private static Map getConfiguration(HttpSession session, User us Map myConfiguration = new HashMap<>(); myConfiguration.putAll(config); + // session timeout + // in case we have different timeout for the admin + // we have this grab for this session what the timeout value is + myConfiguration.put("timeout", (double) session.getMaxInactiveInterval() / 60); // append values that can change without restarting the server // logins allowed myConfiguration.put("loginsAllowed", UserResource.getLoginsAllowed()); diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index 54d76c00d..40c3a3f29 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -359,8 +359,11 @@ public Response runPixelSync(@Context HttpServletRequest request) { } } - return runPixelJob(user, insight, expression, jobId, insightId, sessionId, dropLogging); - + int secondsForExpiration = session.getMaxInactiveInterval(); + long curTime = System.currentTimeMillis(); + long lastTime = session.getLastAccessedTime(); + long sessionTimeRemaining = (long) secondsForExpiration - (long) ( (curTime - lastTime) /1000 ); + return runPixelJob(user, insight, expression, jobId, insightId, sessionId, dropLogging, sessionTimeRemaining); } @POST @@ -423,7 +426,7 @@ public Response getPixelPipelinePlan(@Context HttpServletRequest request) { * @return */ private Response runPixelJob(User user, Insight insight, String expression, String jobId, - String insightId, String sessionId, boolean dropLogging) { + String insightId, String sessionId, boolean dropLogging, long sessionTimeRemaining) { JobManager manager = JobManager.getManager(); JobThread jt = manager.makeJob(insightId); jobId = jt.getJobId(); @@ -443,9 +446,9 @@ private Response runPixelJob(User user, Insight insight, String expression, Stri jt.setInsight(insight); jt.run(); PixelRunner pixelRunner = jt.getRunner(); - + try { - return Response.status(200).entity(PixelStreamUtility.collectPixelData(pixelRunner)) + return Response.status(200).entity(PixelStreamUtility.collectPixelData(pixelRunner, sessionTimeRemaining)) .header("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0, post-check=0, pre-check=0") .header("Pragma", "no-cache") .build(); diff --git a/src/prerna/semoss/web/services/local/RunInsight.java b/src/prerna/semoss/web/services/local/RunInsight.java index 5eb1b7119..64e800d03 100644 --- a/src/prerna/semoss/web/services/local/RunInsight.java +++ b/src/prerna/semoss/web/services/local/RunInsight.java @@ -129,7 +129,7 @@ public Response recreateInsightState(@Context HttpServletRequest request) { // now rerun the recipe and append to the runner in.runPixel(pixelRunner, recipe); - return Response.status(200).entity(PixelStreamUtility.collectPixelData(pixelRunner)) + return Response.status(200).entity(PixelStreamUtility.collectPixelData(pixelRunner, null)) .header("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0, post-check=0, pre-check=0") .header("Pragma", "no-cache") .build(); From ddc3ff4ceffd0017c22e895e6e69820551632298 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Sat, 27 Feb 2021 03:40:44 +0000 Subject: [PATCH 0749/1906] UPDATE ::: Closing the one-time insights as well in case they are being used and resulting in insights that are never dropped UPDATE ::: try/catch in case error occurs in dropping an insight to proceed and try all the other drop routines git-svn-id: svn://107.170.10.188:8080/Monolith/dev@42842 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: ce9e2e6a9aeca53703d3986b67e767e0cc03dc68 --- src/prerna/semoss/web/services/local/NameServer.java | 6 ++++++ src/prerna/web/conf/UserSessionLoader.java | 8 ++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index 40c3a3f29..02c521818 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -100,6 +100,7 @@ import prerna.util.PlaySheetRDFMapBasedEnum; import prerna.util.Utility; import prerna.util.gson.GsonUtility; +import prerna.util.insight.InsightUtility; import prerna.web.services.util.ResponseHashSingleton; import prerna.web.services.util.SemossExecutorSingleton; import prerna.web.services.util.SemossThread; @@ -324,6 +325,7 @@ public Response runPixelSync(@Context HttpServletRequest request) { insight = new Insight(); insight.setBaseURL(getServerURL(request)); insight.setInsightId(insightId); + insight.setTemporaryInsight(true); } else if (insightId.equals("new")) { // need to make a new insight here insight = new Insight(); @@ -462,6 +464,10 @@ private Response runPixelJob(User user, Insight insight, String expression, Stri jt.setStatus(JobStatus.COMPLETE); manager.removeJob(jobId); } + // are we going to immediately drop the insight + if(insight.isTemporaryInsight()) { + InsightUtility.dropInsight(insight); + } } } diff --git a/src/prerna/web/conf/UserSessionLoader.java b/src/prerna/web/conf/UserSessionLoader.java index 37259590c..e0e86e617 100644 --- a/src/prerna/web/conf/UserSessionLoader.java +++ b/src/prerna/web/conf/UserSessionLoader.java @@ -66,8 +66,12 @@ public void sessionDestroyed(HttpSessionEvent sessionEvent) { continue; } logger.info(sessionId + " >>> Trying to drop insight " + insightId); - InsightUtility.dropInsight(insight); - logger.info(sessionId + " >>> Dropped insight " + insightId); + try { + InsightUtility.dropInsight(insight); + logger.info(sessionId + " >>> Dropped insight " + insightId); + } catch(Exception e) { + logger.error(Constants.STACKTRACE, e); + } } logger.info(sessionId + " >>> Successfully removed insight information from session"); From 9710067fd996b27eea1d1e23a595e6ba67a023e3 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 2 Mar 2021 16:01:57 +0000 Subject: [PATCH 0750/1906] UPDATE ::: Cannot close the temp insights in the finally block as it will close streams. Have to store them in the insight store so we can close them when the session ends git-svn-id: svn://107.170.10.188:8080/Monolith/dev@42861 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 5cfead55aed135a8bfefb6f03814b4c54d4a2540 --- src/prerna/semoss/web/services/local/NameServer.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index 02c521818..5c5adf1d8 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -100,7 +100,6 @@ import prerna.util.PlaySheetRDFMapBasedEnum; import prerna.util.Utility; import prerna.util.gson.GsonUtility; -import prerna.util.insight.InsightUtility; import prerna.web.services.util.ResponseHashSingleton; import prerna.web.services.util.SemossExecutorSingleton; import prerna.web.services.util.SemossThread; @@ -321,11 +320,15 @@ public Response runPixelSync(@Context HttpServletRequest request) { // figure out the type of insight // first is temp if (insightId == null || insightId.toString().isEmpty() || insightId.equals("undefined")) { - insightId = "TempInsightNotStored_" + UUID.randomUUID().toString(); + insightId = "TempInsight_" + UUID.randomUUID().toString(); insight = new Insight(); insight.setBaseURL(getServerURL(request)); insight.setInsightId(insightId); insight.setTemporaryInsight(true); + // we will still store this + // so that when the session ends + // we clean it up + InsightStore.getInstance().addToSessionHash(sessionId, insightId); } else if (insightId.equals("new")) { // need to make a new insight here insight = new Insight(); @@ -464,10 +467,6 @@ private Response runPixelJob(User user, Insight insight, String expression, Stri jt.setStatus(JobStatus.COMPLETE); manager.removeJob(jobId); } - // are we going to immediately drop the insight - if(insight.isTemporaryInsight()) { - InsightUtility.dropInsight(insight); - } } } From 995df85d4b611b03efdc319bec1aff1f403f656e Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 3 Mar 2021 22:05:26 +0000 Subject: [PATCH 0751/1906] UPDATE ::: Pushing logic to allow for OpenInsight the extra parameter useExistingIfOpen="true" which would be useful on iframes when the user is doing lots of toggling and we dont want the insights to reload every time git-svn-id: svn://107.170.10.188:8080/Monolith/dev@42899 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: be6fbb3d9138c0f1713b3a8c176eea30277da32e --- .../semoss/web/services/local/RunInsight.java | 84 +------------------ 1 file changed, 1 insertion(+), 83 deletions(-) diff --git a/src/prerna/semoss/web/services/local/RunInsight.java b/src/prerna/semoss/web/services/local/RunInsight.java index 64e800d03..b94ee3c6e 100644 --- a/src/prerna/semoss/web/services/local/RunInsight.java +++ b/src/prerna/semoss/web/services/local/RunInsight.java @@ -1,9 +1,6 @@ package prerna.semoss.web.services.local; -import java.io.IOException; -import java.io.StringWriter; import java.util.HashMap; -import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; @@ -16,23 +13,9 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import com.google.gson.stream.JsonWriter; - -import prerna.algorithm.api.ITableDataFrame; import prerna.om.Insight; -import prerna.om.InsightPanel; -import prerna.om.InsightSheet; -import prerna.om.ThreadStore; import prerna.sablecc2.PixelRunner; import prerna.sablecc2.PixelStreamUtility; -import prerna.sablecc2.PixelUtility; -import prerna.sablecc2.om.PixelDataType; -import prerna.sablecc2.om.PixelOperationType; -import prerna.sablecc2.om.VarStore; -import prerna.sablecc2.om.nounmeta.NounMetadata; -import prerna.sablecc2.reactor.job.JobReactor; -import prerna.util.gson.InsightPanelAdapter; -import prerna.util.gson.InsightSheetAdapter; import prerna.util.insight.InsightUtility; import prerna.web.requests.OverrideParametersServletRequest; @@ -63,72 +46,7 @@ public Response getInsightData(@Context HttpServletRequest request) { @Path("/getInsightState") @Produces("application/json") public Response recreateInsightState(@Context HttpServletRequest request) { - List recipe = PixelUtility.getCachedInsightRecipe(in); - - Insight rerunInsight = new Insight(); - rerunInsight.setVarStore(in.getVarStore()); - rerunInsight.setUser(in.getUser()); - InsightUtility.transferDefaultVars(in, rerunInsight); - - // set in thread - ThreadStore.setInsightId(in.getInsightId()); - ThreadStore.setSessionId(in.getVarStore().get(JobReactor.SESSION_KEY).getValue() + ""); - ThreadStore.setUser(in.getUser()); - - try { - // add a copy of all the insight sheets - Map sheets = in.getInsightSheets(); - for(String sheetId : sheets.keySet()) { - InsightSheetAdapter adapter = new InsightSheetAdapter(); - StringWriter writer = new StringWriter(); - JsonWriter jWriter = new JsonWriter(writer); - adapter.write(jWriter, sheets.get(sheetId)); - String sheetStr = writer.toString(); - InsightSheet sheetClone = adapter.fromJson(sheetStr); - rerunInsight.addNewInsightSheet(sheetClone); - } - - // add a copy of all the insight panels - Map panels = in.getInsightPanels(); - for(String panelId : panels.keySet()) { - InsightPanelAdapter adapter = new InsightPanelAdapter(); - StringWriter writer = new StringWriter(); - JsonWriter jWriter = new JsonWriter(writer); - adapter.write(jWriter, panels.get(panelId)); - String panelStr = writer.toString(); - InsightPanel panelClone = adapter.fromJson(panelStr); - rerunInsight.addNewInsightPanel(panelClone); - } - } catch (IOException e) { - e.printStackTrace(); - } - - PixelRunner pixelRunner = new PixelRunner(); - // add all the frame headers to the payload first - try { - VarStore vStore = in.getVarStore(); - List keys = vStore.getFrameKeys(); - for(String k : keys) { - NounMetadata noun = vStore.get(k); - PixelDataType type = noun.getNounType(); - if(type == PixelDataType.FRAME) { - try { - ITableDataFrame frame = (ITableDataFrame) noun.getValue(); - pixelRunner.addResult("CACHED_FRAME_HEADERS", - new NounMetadata(frame.getFrameHeadersObject(), PixelDataType.CUSTOM_DATA_STRUCTURE, - PixelOperationType.FRAME_HEADERS), true); - } catch(Exception e) { - e.printStackTrace(); - // ignore - } - } - } - } catch (Exception e) { - e.printStackTrace(); - } - // now rerun the recipe and append to the runner - in.runPixel(pixelRunner, recipe); - + PixelRunner pixelRunner = InsightUtility.recreateInsightState(in); return Response.status(200).entity(PixelStreamUtility.collectPixelData(pixelRunner, null)) .header("Cache-Control", "no-store, no-cache, must-revalidate, max-age=0, post-check=0, pre-check=0") .header("Pragma", "no-cache") From 8b22f0b0eefe422a8749fc8def7baf1ab94fa85f Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 9 Mar 2021 22:45:14 +0000 Subject: [PATCH 0752/1906] UPDATE ::: Adding new html webcontent page to start to throw errors if too many users are signed in git-svn-id: svn://107.170.10.188:8080/Monolith/dev@42965 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 33c0f7e898dc74fb6a75ff5708dbd0c62a5cc99d --- WebContent/sessionCounterFail/index.html | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 WebContent/sessionCounterFail/index.html diff --git a/WebContent/sessionCounterFail/index.html b/WebContent/sessionCounterFail/index.html new file mode 100644 index 000000000..1bf39df0b --- /dev/null +++ b/WebContent/sessionCounterFail/index.html @@ -0,0 +1,3 @@ + +

Too many users are on the box at the same time. Please try again later.

+ \ No newline at end of file From d94a80e64d9ec4b3a3cd7b856a7af9b5c0ef3684 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 9 Mar 2021 22:48:32 +0000 Subject: [PATCH 0753/1906] UPDATE ::: Adding initial class for limiting the # of the sessions allowed on the server git-svn-id: svn://107.170.10.188:8080/Monolith/dev@42966 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 216d8e429154dd1f58b3db6937a0db76003ea836 --- .../conf/SessionCounterExceededFilter.java | 99 +++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 src/prerna/web/conf/SessionCounterExceededFilter.java diff --git a/src/prerna/web/conf/SessionCounterExceededFilter.java b/src/prerna/web/conf/SessionCounterExceededFilter.java new file mode 100644 index 000000000..eb5742e7d --- /dev/null +++ b/src/prerna/web/conf/SessionCounterExceededFilter.java @@ -0,0 +1,99 @@ +package prerna.web.conf; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.apache.catalina.session.StandardManager; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import prerna.auth.User; +import prerna.semoss.web.services.local.SessionResource; +import prerna.util.Constants; +import prerna.util.Utility; + +public class SessionCounterExceededFilter implements Filter { + + private static final Logger logger = LogManager.getLogger(SessionCounterExceededFilter.class); + + private static final String FAIL_HTML = "/sessionCounterFail/"; + + private static final String SESSION_LIMIT = "sessionLimit"; + private static Integer sessionLimit = null; + + private static FilterConfig filterConfig; + + @Override + public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { + setInitParams(arg0); + + ServletContext context = arg0.getServletContext(); + HttpSession session = ((HttpServletRequest)arg0).getSession(false); + User user = null; + if(session != null) { + user = (User) session.getAttribute(Constants.SESSION_USER); + } + + if(user == null && sessionLimit != null && sessionLimit > 0) { + StandardManager manager = SessionResource.getManager((HttpServletRequest) arg0); + if(manager != null) { + int currentSessions = manager.getActiveSessions(); + + if(currentSessions+1 > sessionLimit) { + // too many users + // this will be the deployment name of the app + String contextPath = context.getContextPath(); + + // this will be the full path of the request + // like http://localhost:8080/Monolith_Dev/api/engine/runPixel + String fullUrl = Utility.cleanHttpResponse(((HttpServletRequest) arg0).getRequestURL().toString()); + + if(!fullUrl.endsWith(FAIL_HTML)) { + // we redirect to the index.html page where we have pushed the admin page + String redirectUrl = fullUrl.substring(0, fullUrl.indexOf(contextPath) + contextPath.length()) + FAIL_HTML; + ((HttpServletResponse) arg1).setHeader("redirect", redirectUrl); + ((HttpServletResponse) arg1).sendError(302, "Need to redirect to " + redirectUrl); + return; + } + } + } + } + + arg2.doFilter(arg0, arg1); + } + + @Override + public void destroy() { + // TODO Auto-generated method stub + + } + + @Override + public void init(FilterConfig arg0) throws ServletException { + SessionCounterExceededFilter.filterConfig = arg0; + } + + private void setInitParams(ServletRequest arg0) { + if(SessionCounterExceededFilter.sessionLimit == null) { + String sessionLimitString = SessionCounterExceededFilter.filterConfig.getInitParameter(SESSION_LIMIT); + if(sessionLimitString != null) { + try { + SessionCounterExceededFilter.sessionLimit = (int) Double.parseDouble(sessionLimitString); + } catch(Exception e) { + logger.error(Constants.STACKTRACE, e); + } + } + } + } + +} From 35e54abbf02a38746299a68974280320c5a53ca7 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 10 Mar 2021 23:47:12 +0000 Subject: [PATCH 0754/1906] UPDATE ::: Removing references to removed file due to compilation errors git-svn-id: svn://107.170.10.188:8080/Monolith/dev@42989 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: c89180ada866fb748668fe6d4eb075d356f8d79d --- src/prerna/web/conf/UserSessionLoader.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/prerna/web/conf/UserSessionLoader.java b/src/prerna/web/conf/UserSessionLoader.java index e0e86e617..9d135537b 100644 --- a/src/prerna/web/conf/UserSessionLoader.java +++ b/src/prerna/web/conf/UserSessionLoader.java @@ -17,7 +17,6 @@ import prerna.auth.SyncUserAppsThread; import prerna.auth.User; import prerna.cache.ICache; -import prerna.ds.py.FilePyTranslator; import prerna.ds.py.PyTranslator; import prerna.ds.py.PyUtils; import prerna.ds.py.TCPPyTranslator; @@ -118,8 +117,6 @@ public Void call() throws Exception { if (pyt instanceof prerna.ds.py.PyTranslator) PyUtils.getInstance().killPyThread(pyt.getPy()); - if (pyt instanceof FilePyTranslator && thisUser != null) - PyUtils.getInstance().killTempTupleSpace(thisUser); if (pyt instanceof TCPPyTranslator) { NettyClient nc = thisUser.getPyServe(); String dir = thisUser.pyTupleSpace; From 3afdf2378decbe3cc17ce757e7f82b0ed42a4682 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 11 Mar 2021 22:42:58 +0000 Subject: [PATCH 0755/1906] UPDATE ::: Adding session counter filter git-svn-id: svn://107.170.10.188:8080/Monolith/dev@43008 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: f719939d1febd800040f296f4b0c86afe42fa818 --- WebContent/WEB-INF/web.xml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index 461114e6b..e0365023b 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -92,6 +92,23 @@ /api/*
+ + + SessionCounterExceededFilter + prerna.web.conf.SessionCounterExceededFilter + + sessionLimit + + -1 + + + + SessionCounterExceededFilter + /* + + SchedulerFilter From 0d55e9711f423bd06bf018e5a55ea95c758e6d09 Mon Sep 17 00:00:00 2001 From: pkapaleeswaran Date: Fri, 12 Mar 2021 17:06:04 +0000 Subject: [PATCH 0756/1906] Updates to accomodate the TCP Server git-svn-id: svn://107.170.10.188:8080/Monolith/dev@43018 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: d55a97aa9ea2282d996716de5b3b945bab591ccd --- src/prerna/web/conf/DBLoader.java | 4 ++-- src/prerna/web/conf/UserSessionLoader.java | 8 ++++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/prerna/web/conf/DBLoader.java b/src/prerna/web/conf/DBLoader.java index c578a9cea..903fae262 100644 --- a/src/prerna/web/conf/DBLoader.java +++ b/src/prerna/web/conf/DBLoader.java @@ -48,7 +48,7 @@ import prerna.nameserver.utility.MasterDatabaseUtility; import prerna.om.Insight; import prerna.om.InsightStore; -import prerna.sablecc2.reactor.frame.py.PyTranslatorFactory; +import prerna.sablecc2.reactor.frame.py.PySingleton; import prerna.sablecc2.reactor.frame.r.util.RJavaTranslatorFactory; import prerna.sablecc2.reactor.scheduler.SchedulerDatabaseUtility; import prerna.sablecc2.reactor.scheduler.SchedulerFactorySingleton; @@ -293,7 +293,7 @@ public void contextDestroyed(ServletContextEvent arg0) { // close r try { RJavaTranslatorFactory.stopRConnection(); - PyTranslatorFactory.stopPy(); + PySingleton.stopPy(); } catch (Exception e) { logger.log(SHUTDOWN, Constants.STACKTRACE, e); } diff --git a/src/prerna/web/conf/UserSessionLoader.java b/src/prerna/web/conf/UserSessionLoader.java index 9d135537b..c5650d010 100644 --- a/src/prerna/web/conf/UserSessionLoader.java +++ b/src/prerna/web/conf/UserSessionLoader.java @@ -23,7 +23,7 @@ import prerna.engine.impl.r.IRUserConnection; import prerna.om.Insight; import prerna.om.InsightStore; -import prerna.pyserve.NettyClient; +import prerna.tcp.client.Client; import prerna.util.Constants; import prerna.util.DIHelper; import prerna.util.insight.InsightUtility; @@ -41,6 +41,9 @@ public void sessionCreated(HttpSessionEvent sessionEvent) { public void sessionDestroyed(HttpSessionEvent sessionEvent) { HttpSession session = sessionEvent.getSession(); String sessionId = session.getId(); + + + User thisUser = (User) session.getAttribute(Constants.SESSION_USER); if(thisUser == null) { // no need to log a new session that is auto dropped @@ -118,12 +121,13 @@ public Void call() throws Exception { if (pyt instanceof prerna.ds.py.PyTranslator) PyUtils.getInstance().killPyThread(pyt.getPy()); if (pyt instanceof TCPPyTranslator) { - NettyClient nc = thisUser.getPyServe(); + Client nc = thisUser.getTCPServer(); String dir = thisUser.pyTupleSpace; nc.stopPyServe(dir); } } } } + } \ No newline at end of file From 1746749169faaf1d06a55f68de2b4b7c0eaaf6ec Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 17 Mar 2021 19:08:42 +0000 Subject: [PATCH 0757/1906] UPDATE ::: Defining the application path + adding empty resource for saml verification git-svn-id: svn://107.170.10.188:8080/Monolith/dev@43080 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: a665fa0fe8a6b6a4d5188845c8c399745b16a8ae --- .../semoss/web/app/AdminApplication.java | 2 + .../semoss/web/app/MonolithApplication.java | 2 + .../semoss/web/app/SamlApplication.java | 51 +++++++++++++++++++ .../web/services/local/SessionResource.java | 1 - .../services/saml/SamlVerifierResource.java | 20 ++++++++ 5 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 src/prerna/semoss/web/app/SamlApplication.java create mode 100644 src/prerna/semoss/web/services/saml/SamlVerifierResource.java diff --git a/src/prerna/semoss/web/app/AdminApplication.java b/src/prerna/semoss/web/app/AdminApplication.java index acde501fb..fcc3b9ad1 100644 --- a/src/prerna/semoss/web/app/AdminApplication.java +++ b/src/prerna/semoss/web/app/AdminApplication.java @@ -30,10 +30,12 @@ import java.util.HashSet; import java.util.Set; +import javax.ws.rs.ApplicationPath; import javax.ws.rs.core.Application; import prerna.semoss.web.services.config.AdminConfigService; +@ApplicationPath("/admin") public class AdminApplication extends Application { private Set singletons = new HashSet(); diff --git a/src/prerna/semoss/web/app/MonolithApplication.java b/src/prerna/semoss/web/app/MonolithApplication.java index cadf9a855..07bd54e38 100644 --- a/src/prerna/semoss/web/app/MonolithApplication.java +++ b/src/prerna/semoss/web/app/MonolithApplication.java @@ -30,6 +30,7 @@ import java.util.HashSet; import java.util.Set; +import javax.ws.rs.ApplicationPath; import javax.ws.rs.core.Application; import prerna.cluster.RawSelectWrapperService; @@ -52,6 +53,7 @@ import prerna.upload.FileUploader; import prerna.upload.ImageUploader; +@ApplicationPath("/api") public class MonolithApplication extends Application { private Set singletons = new HashSet(); diff --git a/src/prerna/semoss/web/app/SamlApplication.java b/src/prerna/semoss/web/app/SamlApplication.java new file mode 100644 index 000000000..850cee689 --- /dev/null +++ b/src/prerna/semoss/web/app/SamlApplication.java @@ -0,0 +1,51 @@ +/******************************************************************************* + * Copyright 2015 Defense Health Agency (DHA) + * + * If your use of this software does not include any GPLv2 components: + * Licensed 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. + * ---------------------------------------------------------------------------- + * If your use of this software includes any GPLv2 components: + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + *******************************************************************************/ +package prerna.semoss.web.app; + +import java.util.HashSet; +import java.util.Set; + +import javax.ws.rs.ApplicationPath; +import javax.ws.rs.core.Application; + +import prerna.semoss.web.services.saml.SamlVerifierResource; + +@ApplicationPath("/saml") +public class SamlApplication extends Application { + + private Set singletons = new HashSet(); + + public SamlApplication() { + singletons.add(new SamlVerifierResource()); + } + + @Override + public Set getSingletons() { + return singletons; + } +} diff --git a/src/prerna/semoss/web/services/local/SessionResource.java b/src/prerna/semoss/web/services/local/SessionResource.java index 05e31b90d..2f71a07b4 100644 --- a/src/prerna/semoss/web/services/local/SessionResource.java +++ b/src/prerna/semoss/web/services/local/SessionResource.java @@ -37,7 +37,6 @@ import prerna.web.conf.DBLoader; import prerna.web.services.util.WebUtility; - @Path("/session") public class SessionResource { diff --git a/src/prerna/semoss/web/services/saml/SamlVerifierResource.java b/src/prerna/semoss/web/services/saml/SamlVerifierResource.java new file mode 100644 index 000000000..3a3d99383 --- /dev/null +++ b/src/prerna/semoss/web/services/saml/SamlVerifierResource.java @@ -0,0 +1,20 @@ +package prerna.semoss.web.services.saml; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Response; + +import prerna.web.services.util.WebUtility; + +@Path("/config") +public class SamlVerifierResource { + + @GET + @Path("/test") + @Produces("application/json") + public Response test() { + return WebUtility.getResponse("success", 200); + } + +} From e4c1843934e31f934c93aea95d887eaf140064db Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 17 Mar 2021 19:09:58 +0000 Subject: [PATCH 0758/1906] UPDATE ::: Adding saml application servlet into web.xml git-svn-id: svn://107.170.10.188:8080/Monolith/dev@43081 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: e9a349a51af39fbfeff4f9f316ed4feca79d582d --- WebContent/WEB-INF/web.xml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index e0365023b..9089d1118 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -374,11 +374,31 @@ javax.ws.rs.Application prerna.semoss.web.app.AdminApplication + + resteasy.servlet.mapping.prefix + /adminconfig + AdminApplication /adminconfig/* + + SamlApplication + org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher + + javax.ws.rs.Application + prerna.semoss.web.app.SamlApplication + + + resteasy.servlet.mapping.prefix + /saml + + + + SamlApplication + /saml/* + From cca5213522f4384540a1acf77b19310ba2d8600d Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 18 Mar 2021 14:45:26 +0000 Subject: [PATCH 0759/1906] UPDATE ::: Pushing new rest endpoints for setting app/insights as favorites for a user git-svn-id: svn://107.170.10.188:8080/Monolith/dev@43093 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 17c614d04904a2e5994ca7ca9a70cf3f71a0c51c --- .../local/auth/AppAuthorizationResource.java | 46 ++++++++++++ .../auth/InsightAuthorizationResource.java | 71 ++++++++++++++++--- 2 files changed, 107 insertions(+), 10 deletions(-) diff --git a/src/prerna/semoss/web/services/local/auth/AppAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/AppAuthorizationResource.java index c8dc97616..902186a69 100644 --- a/src/prerna/semoss/web/services/local/auth/AppAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/AppAuthorizationResource.java @@ -364,6 +364,52 @@ public Response setAppVisibility(@Context HttpServletRequest request, Multivalue return WebUtility.getResponse(true, 200); } + /** + * Set the app as favorited by the user + * @param request + * @param form + * @return + */ + @POST + @Produces("application/json") + @Path("setAppFavorite") + public Response setAppFavorite(@Context HttpServletRequest request, MultivaluedMap form) { + User user = null; + try { + user = ResourceUtility.getUser(request); + } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "invalid user session trying to access authorization resources")); + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put("error", "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + + String appId = form.getFirst("appId"); + boolean isFavorite = Boolean.parseBoolean(form.getFirst("isFavorite")); + String logFavorited = isFavorite ? " favorited " : " not favorited"; + + try { + SecurityUpdateUtils.setDbFavorite(user, appId, isFavorite); + } catch(IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to set the app " + appId + logFavorited + " without having proper access")); + logger.error(Constants.STACKTRACE, e); + Map errorRet = new HashMap(); + errorRet.put("error", e.getMessage()); + return WebUtility.getResponse(errorRet, 400); + } catch (Exception e){ + logger.error(Constants.STACKTRACE, e); + Map errorRet = new HashMap(); + errorRet.put("error", "An unexpected error happened. Please try again."); + return WebUtility.getResponse(errorRet, 500); + } + + // log the operation + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has set the app " + appId + logFavorited)); + + return WebUtility.getResponse(true, 200); + } + /** * Get users with no access to a given app * @param request diff --git a/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java index 4b3b48b16..71b4793fc 100644 --- a/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java @@ -21,12 +21,8 @@ import prerna.auth.User; import prerna.auth.utils.SecurityAppUtils; import prerna.auth.utils.SecurityInsightUtils; -import prerna.cluster.util.ClusterUtil; -import prerna.engine.api.IEngine; -import prerna.engine.impl.InsightAdministrator; import prerna.semoss.web.services.local.ResourceUtility; import prerna.util.Constants; -import prerna.util.Utility; import prerna.web.services.util.WebUtility; @Path("/auth/insight") @@ -287,7 +283,7 @@ public Response removeInsightUserPermission(@Context HttpServletRequest request, } /** - * Remove user permission for an insight + * Set the insight global * @param request * @param form * @return @@ -315,13 +311,19 @@ public Response setInsightGlobal(@Context HttpServletRequest request, Multivalue try { SecurityInsightUtils.setInsightGlobalWithinApp(user, appId, insightId, isPublic); + /* + * BELOW COMMENTED OUT IS INVALID LOGIC + * WE DO NOT WANT TO MAKE IT HIDDEN IN INSIGHTS DB + * THAT WILL RESULT IN IT NOT BEING LOADED TO SECURITY AT ALL + */ + // also update in the app itself // so it is properly synchronized with the security db - ClusterUtil.reactorPullInsightsDB(appId); - IEngine app = Utility.getEngine(appId); - InsightAdministrator admin = new InsightAdministrator(app.getInsightDatabase()); - admin.updateInsightGlobal(insightId, !isPublic); - ClusterUtil.reactorPushInsightDB(appId); +// ClusterUtil.reactorPullInsightsDB(appId); +// IEngine app = Utility.getEngine(appId); +// InsightAdministrator admin = new InsightAdministrator(app.getInsightDatabase()); +// admin.updateInsightGlobal(insightId, !isPublic); +// ClusterUtil.reactorPushInsightDB(appId); } catch (IllegalAccessException e) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to set the insight " + insightId + " in app " + appId + logPublic + " without having proper access")); @@ -343,6 +345,55 @@ public Response setInsightGlobal(@Context HttpServletRequest request, Multivalue ret.put("success", true); return WebUtility.getResponse(ret, 200); } + + /** + * Set the insight as favorited by the user + * @param request + * @param form + * @return + */ + @POST + @Produces("application/json") + @Path("setInsightFavorite") + public Response setInsightFavorite(@Context HttpServletRequest request, MultivaluedMap form) { + User user = null; + try { + user = ResourceUtility.getUser(request); + } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "invalid user session trying to access authorization resources")); + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + + String appId = form.getFirst("appId"); + String insightId = form.getFirst("insightId"); + boolean isFavorite = Boolean.parseBoolean(form.getFirst("isFavorite")); + String logFavorited = isFavorite ? " favorited " : " not favorited"; + + try { + SecurityInsightUtils.setInsightFavorite(user, appId, insightId, isFavorite); + } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to set the insight " + insightId + " in app " + appId + logFavorited + " without having proper access")); + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } catch (Exception e) { + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 400); + } + + // log the operation + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has set the insight " + insightId + " in app " + appId + logFavorited)); + + Map ret = new HashMap(); + ret.put("success", true); + return WebUtility.getResponse(ret, 200); + } /** * Get the users with no access to a given insight From 3b5056dea2a963f3e8ca61b2f6a2f927ef15f57d Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 22 Mar 2021 18:11:57 +0000 Subject: [PATCH 0760/1906] UPDATE ::: Adding logic to send only favorites for MyApps and GetInsights reactors. git-svn-id: svn://107.170.10.188:8080/Monolith/dev@43117 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 2ffe8198826a2c98da5c66baa3a3b05964cba4a9 --- src/prerna/semoss/web/services/local/NameServer.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index 5c5adf1d8..123378562 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -887,7 +887,7 @@ public StreamingOutput printEngines(@Context HttpServletRequest request) { if (user == null) { return WebUtility.getSO("Not properly authenticated"); } - engines = SecurityQueryUtils.getUserDatabaseList(user); + engines = SecurityQueryUtils.getUserDatabaseList(user, false); user.setEngines(engines); } else { engines = SecurityQueryUtils.getAllDatabaseList(); @@ -1116,7 +1116,7 @@ public StreamingOutput getSearchInsightsResults(MultivaluedMap f // filter insights based on what the user has access to HttpSession session = request.getSession(false); User user = ((User) session.getAttribute(Constants.SESSION_USER)); - queryResults = SecurityInsightUtils.searchUserInsights(user, appIds, searchString, tags, limit, offset); + queryResults = SecurityInsightUtils.searchUserInsights(user, appIds, searchString, tags, false, limit, offset); } else { queryResults = SecurityInsightUtils.searchInsights(appIds, searchString, tags, limit, offset); } From 8bff94ffb413c31ec76a2598af8e1790710d312c Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 22 Mar 2021 18:24:34 +0000 Subject: [PATCH 0761/1906] BUGFIX ::: Fixing error where paths were not listed properly for setting initial admin git-svn-id: svn://107.170.10.188:8080/Monolith/dev@43118 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: a1e838540691254ffc89ad82036a4b666facc36a --- src/prerna/semoss/web/app/AdminApplication.java | 2 +- src/prerna/semoss/web/services/config/AdminConfigService.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/prerna/semoss/web/app/AdminApplication.java b/src/prerna/semoss/web/app/AdminApplication.java index fcc3b9ad1..859542df4 100644 --- a/src/prerna/semoss/web/app/AdminApplication.java +++ b/src/prerna/semoss/web/app/AdminApplication.java @@ -35,7 +35,7 @@ import prerna.semoss.web.services.config.AdminConfigService; -@ApplicationPath("/admin") +@ApplicationPath("/adminconfig") public class AdminApplication extends Application { private Set singletons = new HashSet(); diff --git a/src/prerna/semoss/web/services/config/AdminConfigService.java b/src/prerna/semoss/web/services/config/AdminConfigService.java index b1967342d..fa413e602 100644 --- a/src/prerna/semoss/web/services/config/AdminConfigService.java +++ b/src/prerna/semoss/web/services/config/AdminConfigService.java @@ -22,7 +22,7 @@ import prerna.web.conf.AdminStartupFilter; import prerna.web.services.util.WebUtility; -@Path("/adminconfig") +@Path("/") public class AdminConfigService { private static final Gson GSON = new Gson(); public static final String ADMIN_REDIRECT_KEY = "ADMIN_REDIRECT_KEY"; From 505933350ea84b099b5966214165858b31b0316c Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 22 Mar 2021 21:11:46 +0000 Subject: [PATCH 0762/1906] UPDATE ::: Allowing sort by the date in the reactor git-svn-id: svn://107.170.10.188:8080/Monolith/dev@43125 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 48dc6c91df51f8d012a68774eb1d1c6825caae3f --- src/prerna/semoss/web/services/local/NameServer.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index 123378562..ee3d92027 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -1116,9 +1116,9 @@ public StreamingOutput getSearchInsightsResults(MultivaluedMap f // filter insights based on what the user has access to HttpSession session = request.getSession(false); User user = ((User) session.getAttribute(Constants.SESSION_USER)); - queryResults = SecurityInsightUtils.searchUserInsights(user, appIds, searchString, tags, false, limit, offset); + queryResults = SecurityInsightUtils.searchUserInsights(user, appIds, searchString, tags, false, null, limit, offset); } else { - queryResults = SecurityInsightUtils.searchInsights(appIds, searchString, tags, limit, offset); + queryResults = SecurityInsightUtils.searchInsights(appIds, searchString, tags, null, limit, offset); } return WebUtility.getSO(queryResults); From 60621873640e25dcccc191b3f5819388a372d642 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 30 Mar 2021 03:17:27 +0000 Subject: [PATCH 0763/1906] UPDATE ::: Requiring expression and auto-ending with semicolon git-svn-id: svn://107.170.10.188:8080/Monolith/dev@43248 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 8682b995877cbb718b0ee5a7241c9330fcb73231 --- src/prerna/semoss/web/services/local/NameServer.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index ee3d92027..c7cea4d68 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -312,10 +312,18 @@ public Response runPixelSync(@Context HttpServletRequest request) { } } - String jobId = ""; String insightId = request.getParameter("insightId"); String expression = request.getParameter("expression"); + if(expression == null || (expression = expression.trim()).isEmpty()) { + Map errorMap = new HashMap<>(); + errorMap.put(Constants.ERROR_MESSAGE, "Must pass in 'expression' key containing the pixel to execute"); + errorMap.put(ERROR_TYPE, INSIGHT_NOT_FOUND); + return WebUtility.getResponse(errorMap, 400); + } + if(!expression.endsWith(";")) { + expression = expression + ";"; + } // figure out the type of insight // first is temp From 058876b4587abd50d42487767e2eca6a25f267e1 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 30 Mar 2021 03:37:44 +0000 Subject: [PATCH 0764/1906] UPDATE ::: Adding safeguard for trying to get the route id when dealing with multiple containers git-svn-id: svn://107.170.10.188:8080/Monolith/dev@43249 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 4492b1715409af0e065ce82b08ed267ace8e3900 --- src/prerna/semoss/web/services/local/NameServer.java | 2 ++ src/prerna/web/conf/UserSessionLoader.java | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index c7cea4d68..c46c1bd1f 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -95,6 +95,7 @@ import prerna.sablecc2.comm.JobThread; import prerna.semoss.web.services.remote.CentralNameServer; import prerna.semoss.web.services.remote.EngineRemoteResource; +import prerna.util.ChromeDriverUtility; import prerna.util.Constants; import prerna.util.DIHelper; import prerna.util.PlaySheetRDFMapBasedEnum; @@ -307,6 +308,7 @@ public Response runPixelSync(@Context HttpServletRequest request) { for (Cookie c : curCookies) { if (c.getName().equals(routeCookieName)) { ThreadStore.setRouteId(c.getValue()); + ChromeDriverUtility.setRouteCookieValue(c.getValue()); } } } diff --git a/src/prerna/web/conf/UserSessionLoader.java b/src/prerna/web/conf/UserSessionLoader.java index c5650d010..8dd1e097f 100644 --- a/src/prerna/web/conf/UserSessionLoader.java +++ b/src/prerna/web/conf/UserSessionLoader.java @@ -42,8 +42,6 @@ public void sessionDestroyed(HttpSessionEvent sessionEvent) { HttpSession session = sessionEvent.getSession(); String sessionId = session.getId(); - - User thisUser = (User) session.getAttribute(Constants.SESSION_USER); if(thisUser == null) { // no need to log a new session that is auto dropped From 619d4b6408ba0567cffae4a07f63ccf364869e59 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 30 Mar 2021 03:43:11 +0000 Subject: [PATCH 0765/1906] UPDATE ::: Pushing logs for seeing cookies in the request git-svn-id: svn://107.170.10.188:8080/Monolith/dev@43252 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: d44707c6d3a7e4c37ff746a03d4238ccc02e732d --- src/prerna/semoss/web/services/local/NameServer.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index c46c1bd1f..04ea57e1a 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -306,6 +306,7 @@ public Response runPixelSync(@Context HttpServletRequest request) { Cookie[] curCookies = request.getCookies(); if (curCookies != null) { for (Cookie c : curCookies) { + logger.info(">>>>> Request cookie " + c.getName() + " with value " + c.getValue()); if (c.getName().equals(routeCookieName)) { ThreadStore.setRouteId(c.getValue()); ChromeDriverUtility.setRouteCookieValue(c.getValue()); From b1bf75fada632b74d192a9720ce5a3dfe6993a3f Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 30 Mar 2021 15:45:42 +0000 Subject: [PATCH 0766/1906] UPDATE ::: Minor code cleanup git-svn-id: svn://107.170.10.188:8080/Monolith/dev@43264 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 91b7ea8bf7ba053d448b3c079c943ab2d8061c3e --- src/prerna/web/services/util/WebUtility.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/prerna/web/services/util/WebUtility.java b/src/prerna/web/services/util/WebUtility.java index 52aafab3d..76fa37bca 100644 --- a/src/prerna/web/services/util/WebUtility.java +++ b/src/prerna/web/services/util/WebUtility.java @@ -49,6 +49,7 @@ import com.google.gson.Gson; +import prerna.util.Constants; import prerna.util.gson.GsonUtility; /** @@ -57,8 +58,7 @@ */ public class WebUtility { - private static final String CLASS_NAME = WebUtility.class.getName(); - private static final Logger LOGGER = LogManager.getLogger(CLASS_NAME); + private static final Logger logger = LogManager.getLogger(WebUtility.class); private static final FastDateFormat expiresDateFormat= FastDateFormat.getInstance("EEE, dd MMM yyyy HH:mm:ss zzz", TimeZone.getTimeZone("GMT")); @@ -89,7 +89,7 @@ public void write(OutputStream outputStream) throws IOException, WebApplicationE } }}; } catch (UnsupportedEncodingException e) { - LOGGER.error("Failed to write object to stream. Stacktrace: ", e); + logger.error(Constants.STACKTRACE, e); } } @@ -129,7 +129,7 @@ public static Response getResponse(Object vec, int status, List addHea } return builder.build(); } catch (UnsupportedEncodingException e) { - LOGGER.error("Stacktrace: ", e); + logger.error(Constants.STACKTRACE, e); } return Response.status(200).entity(WebUtility.getSO(vec)).build(); } @@ -199,7 +199,7 @@ public void write(OutputStream outputStream) throws IOException, WebApplicationE } }}; } catch (Exception e) { - LOGGER.error("Failed to write object to stream. Stacktrace: ",e); + logger.error(Constants.STACKTRACE, e); } return null; From f3b049f207d98011546f0020012d09e2c68934fe Mon Sep 17 00:00:00 2001 From: kunalppatel9 Date: Wed, 31 Mar 2021 15:19:42 +0000 Subject: [PATCH 0767/1906] BUGFIX ::: Fortify - Applying Utility.normalizePath on paths that are passed in git-svn-id: svn://107.170.10.188:8080/Monolith/dev@43283 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 33e9696600c97f0a7e8f0b129d2713db2a71c1aa --- src/prerna/upload/ImageUploader.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/prerna/upload/ImageUploader.java b/src/prerna/upload/ImageUploader.java index a032c7740..3650fbe46 100644 --- a/src/prerna/upload/ImageUploader.java +++ b/src/prerna/upload/ImageUploader.java @@ -456,7 +456,7 @@ public Response deleteInsightImage(@Context HttpServletRequest request) throws S // and the image file // we want to write it into the app location String imageDir = filePath + DIR_SEPARATOR + SmssUtilities.getUniqueName(appName, appId) + DIR_SEPARATOR + "version" + DIR_SEPARATOR + insightId; - File f = new File(imageDir); + File f = new File(Utility.normalizePath(imageDir)); if (f.exists()) { // find all the existing image files // and delete them From 6b4e79f101b94b0940309f4cd07a3699195a31d2 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Sat, 3 Apr 2021 14:51:09 +0000 Subject: [PATCH 0768/1906] UPDATE ::: Minor cleanup to use Constants final method instead of creating own git-svn-id: svn://107.170.10.188:8080/Monolith/dev@43310 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 6b2f2e8f0f29561f1886a2d90426e1d36e902007 --- .../cluster/RawSelectWrapperService.java | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/prerna/cluster/RawSelectWrapperService.java b/src/prerna/cluster/RawSelectWrapperService.java index 5bcc719a0..23729120d 100644 --- a/src/prerna/cluster/RawSelectWrapperService.java +++ b/src/prerna/cluster/RawSelectWrapperService.java @@ -20,13 +20,13 @@ import prerna.engine.api.IRawSelectWrapper; import prerna.rdf.engine.wrappers.WrapperManager; import prerna.sablecc2.om.execptions.SemossPixelException; +import prerna.util.Constants; import prerna.util.Utility; import prerna.web.services.util.WebUtility; @Path("/cluster") public class RawSelectWrapperService implements IRawSelectWrapper { - private static final String STACKTRACE = "StackTrace: "; private static final Logger logger = LogManager.getLogger(RawSelectWrapperService.class); public static final String APP_ID = "appId"; @@ -151,7 +151,7 @@ public Response execute(@Context HttpServletRequest request) { wrapper = getRawSelectWrapper(appId, wrapperId, query); wrapper.execute(); } catch (Exception e) { - logger.error(STACKTRACE,e); + logger.error(Constants.STACKTRACE,e); ret.put("errorMessage", e.getMessage()); return WebUtility.getResponse(ret, 400); } @@ -196,7 +196,7 @@ public Response setQuery(@Context HttpServletRequest request) { wrapper = getRawSelectWrapper(appId, wrapperId, query); wrapper.setQuery(query); } catch (Exception e) { - logger.error(STACKTRACE,e); + logger.error(Constants.STACKTRACE,e); } // Set return values @@ -237,7 +237,7 @@ public Response cleanUp(@Context HttpServletRequest request) { try { wrapper = getRawSelectWrapper(appId, wrapperId); } catch (Exception e) { - logger.error(STACKTRACE,e); + logger.error(Constants.STACKTRACE,e); } finally { if(wrapper != null) { wrapper.cleanUp(); @@ -286,7 +286,7 @@ public Response setEngine(@Context HttpServletRequest request) { IEngine engine = getEngine(appId); wrapper.setEngine(engine); } catch (Exception e) { - logger.error(STACKTRACE,e); + logger.error(Constants.STACKTRACE,e); } // Set return values @@ -324,7 +324,7 @@ public Response hasNext(@Context HttpServletRequest request) { wrapper = getRawSelectWrapper(appId, wrapperId); hasNext = wrapper.hasNext(); } catch (Exception e) { - logger.error(STACKTRACE,e); + logger.error(Constants.STACKTRACE,e); } // Set return values @@ -357,7 +357,7 @@ public Response next(@Context HttpServletRequest request) { wrapper = getRawSelectWrapper(appId, wrapperId); nextRow = wrapper.next(); } catch (Exception e) { - logger.error(STACKTRACE,e); + logger.error(Constants.STACKTRACE,e); } // Set return values @@ -390,7 +390,7 @@ public Response getHeaders(@Context HttpServletRequest request) { wrapper = getRawSelectWrapper(appId, wrapperId); headers = wrapper.getHeaders(); } catch (Exception e) { - logger.error(STACKTRACE,e); + logger.error(Constants.STACKTRACE,e); } // Set return values @@ -423,7 +423,7 @@ public Response getTypes(@Context HttpServletRequest request) { wrapper = getRawSelectWrapper(appId, wrapperId); types = wrapper.getTypes(); } catch (Exception e) { - logger.error(STACKTRACE,e); + logger.error(Constants.STACKTRACE,e); } // Set return values @@ -456,7 +456,7 @@ public Response getNumRecords(@Context HttpServletRequest request) { wrapper = getRawSelectWrapper(appId, wrapperId); numRecords = wrapper.getNumRecords(); } catch (Exception e) { - logger.error(STACKTRACE,e); + logger.error(Constants.STACKTRACE,e); Hashtable ret = new Hashtable<>(); ret.put("errorMessage", e.getMessage()); return WebUtility.getResponse(ret, 400); @@ -528,7 +528,7 @@ public Response reset(@Context HttpServletRequest request) { wrapper = getRawSelectWrapper(appId, wrapperId); wrapper.reset(); } catch (Exception e) { - logger.error(STACKTRACE,e); + logger.error(Constants.STACKTRACE,e); ret.put("errorMessage", e.getMessage()); return WebUtility.getResponse(ret, 400); } From 717552585ba5235a179310cfe8338d42d12d5052 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Sat, 3 Apr 2021 23:43:19 +0000 Subject: [PATCH 0769/1906] UPDATE ::: Not performing unnecessary debug calls if logger is not set at level git-svn-id: svn://107.170.10.188:8080/Monolith/dev@43319 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 1eb7218ffa6e58175e20dad256245f32874c158a --- .../web/services/local/UserResource.java | 166 ++++++++++++------ 1 file changed, 117 insertions(+), 49 deletions(-) diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index 189276f5e..abe05bc34 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -570,8 +570,10 @@ public Response loginSF(@Context HttpServletRequest request, @Context HttpServle String clientSecret = socialData.getProperty(prefix + "secret_key"); String redirectUri = socialData.getProperty(prefix + "redirect_uri"); - logger.debug(">> " + Utility.cleanLogString(request.getQueryString())); - + if(logger.isDebugEnabled()) { + logger.debug(">> " + Utility.cleanLogString(request.getQueryString())); + } + Hashtable params = new Hashtable(); params.put("client_id", clientId); params.put("grant_type", "authorization_code"); @@ -591,7 +593,9 @@ public Response loginSF(@Context HttpServletRequest request, @Context HttpServle accessToken.setProvider(AuthProvider.SF); addAccessToken(accessToken, request); - logger.debug("Access Token is.. " + accessToken.getAccess_token()); + if(logger.isDebugEnabled()) { + logger.debug("Access Token is.. " + accessToken.getAccess_token()); + } } } @@ -617,7 +621,9 @@ private String getSFRedirect(HttpServletRequest request) throws UnsupportedEncod + "&response_type=code" + "&redirect_uri=" + redirectUri + "&scope=" + URLEncoder.encode("api", "UTF-8"); - logger.debug("Sending redirect.. " + Utility.cleanLogString(redirectUrl)); + if(logger.isDebugEnabled()) { + logger.debug("Sending redirect.. " + Utility.cleanLogString(redirectUrl)); + } return redirectUrl; } @@ -646,8 +652,10 @@ public Response loginSurveyMonkey(@Context HttpServletRequest request, @Context String clientSecret = socialData.getProperty(prefix + "secret_key"); String redirectUri = socialData.getProperty(prefix + "redirect_uri"); - logger.debug(">> " + Utility.cleanLogString(request.getQueryString())); - + if(logger.isDebugEnabled()) { + logger.debug(">> " + Utility.cleanLogString(request.getQueryString())); + } + Hashtable params = new Hashtable(); params.put("client_id", clientId); params.put("grant_type", "authorization_code"); @@ -668,7 +676,9 @@ public Response loginSurveyMonkey(@Context HttpServletRequest request, @Context MonkeyProfile.fillAccessToken(accessToken, null); addAccessToken(accessToken, request); - logger.debug("Access Token is.. " + accessToken.getAccess_token()); + if(logger.isDebugEnabled()) { + logger.debug("Access Token is.. " + accessToken.getAccess_token()); + } } } @@ -693,7 +703,9 @@ private String getSurveyMonkeyRedirect(HttpServletRequest request) throws Unsupp String redirectUrl = "https://api.surveymonkey.com/oauth/authorize?" + "client_id=" + clientId + "&response_type=code" + "&redirect_uri=" + redirectUri; - logger.debug("Sending redirect.. " + Utility.cleanLogString(redirectUrl)); + if(logger.isDebugEnabled()) { + logger.debug("Sending redirect.. " + Utility.cleanLogString(redirectUrl)); + } return redirectUrl; } @@ -723,8 +735,10 @@ public Response loginGithub(@Context HttpServletRequest request, @Context HttpSe String clientSecret = socialData.getProperty(prefix + "secret_key"); String redirectUri = socialData.getProperty(prefix + "redirect_uri"); - logger.debug(">> " + Utility.cleanLogString(request.getQueryString())); - + if(logger.isDebugEnabled()) { + logger.debug(">> " + Utility.cleanLogString(request.getQueryString())); + } + Hashtable params = new Hashtable(); params.put("client_id", clientId); params.put("redirect_uri", redirectUri); @@ -753,7 +767,9 @@ public Response loginGithub(@Context HttpServletRequest request, @Context HttpSe accessToken.setUsername(myGit.getLogin()); addAccessToken(accessToken, request); - logger.debug("Access Token is.. " + accessToken.getAccess_token()); + if(logger.isDebugEnabled()) { + logger.debug("Access Token is.. " + accessToken.getAccess_token()); + } } } @@ -781,7 +797,9 @@ private String getGithubRedirect(HttpServletRequest request) throws UnsupportedE + redirectUri + "&state=" + UUID.randomUUID().toString() + "&allow_signup=true" + "&scope=" + URLEncoder.encode(scope, "UTF-8"); - logger.debug("Sending redirect.. " + Utility.cleanLogString(redirectUrl)); + if(logger.isDebugEnabled()) { + logger.debug("Sending redirect.. " + Utility.cleanLogString(redirectUrl)); + } return redirectUrl; } @@ -813,8 +831,10 @@ public Response loginMS(@Context HttpServletRequest request, @Context HttpServle String scope = socialData.getProperty(prefix + "scope"); String token_url = socialData.getProperty(prefix + "token_url"); - logger.debug(">> " + Utility.cleanLogString(request.getQueryString())); - + if(logger.isDebugEnabled()) { + logger.debug(">> " + Utility.cleanLogString(request.getQueryString())); + } + Hashtable params = new Hashtable(); params.put("client_id", clientId); params.put("scope", scope); @@ -840,7 +860,9 @@ public Response loginMS(@Context HttpServletRequest request, @Context HttpServle MSProfile.fillAccessToken(accessToken, null); addAccessToken(accessToken, request); - logger.debug("Access Token is.. " + accessToken.getAccess_token()); + if(logger.isDebugEnabled()) { + logger.debug("Access Token is.. " + accessToken.getAccess_token()); + } } } @@ -874,8 +896,10 @@ private String getMSRedirect(HttpServletRequest request) throws UnsupportedEncod + clientId + "&response_type=code" + "&redirect_uri=" + URLEncoder.encode(redirectUri, "UTF-8") + "&response_mode=query" + "&scope=" + URLEncoder.encode(scope) + "&state=" + state; - logger.debug("Sending redirect.. " + Utility.cleanLogString(redirectUrl)); - + if(logger.isDebugEnabled()) { + logger.debug("Sending redirect.. " + Utility.cleanLogString(redirectUrl)); + } + return redirectUrl; } @@ -907,8 +931,10 @@ public Response loginSiteminder(@Context HttpServletRequest request, @Context Ht String scope = socialData.getProperty(prefix + "scope"); String token_url = socialData.getProperty(prefix + "token_url"); - logger.debug(">> " + Utility.cleanLogString(request.getQueryString())); - + if(logger.isDebugEnabled()) { + logger.debug(">> " + Utility.cleanLogString(request.getQueryString())); + } + Hashtable params = new Hashtable(); params.put("client_id", clientId); params.put("scope", scope); @@ -932,7 +958,9 @@ public Response loginSiteminder(@Context HttpServletRequest request, @Context Ht MSProfile.fillAccessToken(accessToken, null); addAccessToken(accessToken, request); - logger.debug("Access Token is.. " + accessToken.getAccess_token()); + if(logger.isDebugEnabled()) { + logger.debug("Access Token is.. " + accessToken.getAccess_token()); + } } } @@ -966,8 +994,10 @@ private String getSiteminderRedirect(HttpServletRequest request) throws Unsuppor + clientId + "&response_type=code" + "&redirect_uri=" + URLEncoder.encode(redirectUri, "UTF-8") + "&response_mode=query" + "&scope=" + URLEncoder.encode(scope) + "&state=" + state; - logger.debug("Sending redirect.. " + Utility.cleanLogString(redirectUrl)); - + if(logger.isDebugEnabled()) { + logger.debug("Sending redirect.. " + Utility.cleanLogString(redirectUrl)); + } + return redirectUrl; } @@ -996,8 +1026,10 @@ public Response loginDropBox(@Context HttpServletRequest request, @Context HttpS String clientSecret = socialData.getProperty(prefix + "secret_key"); String redirectUri = socialData.getProperty(prefix + "redirect_uri"); - logger.debug(">> " + Utility.cleanLogString(request.getQueryString())); - + if(logger.isDebugEnabled()) { + logger.debug(">> " + Utility.cleanLogString(request.getQueryString())); + } + Hashtable params = new Hashtable(); params.put("client_id", clientId); params.put("redirect_uri", redirectUri); @@ -1017,7 +1049,9 @@ public Response loginDropBox(@Context HttpServletRequest request, @Context HttpS accessToken.setProvider(AuthProvider.DROPBOX); addAccessToken(accessToken, request); - logger.debug("Access Token is.. " + accessToken.getAccess_token()); + if(logger.isDebugEnabled()) { + logger.debug("Access Token is.. " + accessToken.getAccess_token()); + } } } @@ -1044,7 +1078,10 @@ private String getDBRedirect(HttpServletRequest request) throws UnsupportedEncod + "&response_type=code" + "&redirect_uri=" + URLEncoder.encode(redirectUri, "UTF-8") + "&require_role=" + role + "&disable_signup=false"; - logger.debug("Sending redirect.. " + Utility.cleanLogString(redirectUrl)); + if(logger.isDebugEnabled()) { + logger.debug("Sending redirect.. " + Utility.cleanLogString(redirectUrl)); + } + return redirectUrl; } @@ -1074,7 +1111,10 @@ public Response loginGoogle(@Context HttpServletRequest request, @Context HttpSe String clientSecret = socialData.getProperty(prefix + "secret_key"); String redirectUri = socialData.getProperty(prefix + "redirect_uri"); - logger.debug(">> " + Utility.cleanLogString(request.getQueryString())); + if(logger.isDebugEnabled()) { + logger.debug(">> " + Utility.cleanLogString(request.getQueryString())); + } + // I need to decode the return code from google since the default param's are // encoded on the post of getAccessToken String codeDecode = URLDecoder.decode(outputs[0]); @@ -1103,8 +1143,10 @@ public Response loginGoogle(@Context HttpServletRequest request, @Context HttpSe addAccessToken(accessToken, request); // Shows how to make a google credential from an access token - logger.debug("Access Token is.. " + accessToken.getAccess_token()); - + if(logger.isDebugEnabled()) { + logger.debug("Access Token is.. " + accessToken.getAccess_token()); + } + // this is just for testing... // but i will get yelled at if i remove it so here it is... // TODO: adding this todo to easily locate it @@ -1137,7 +1179,9 @@ private String getGoogleRedirect(HttpServletRequest request) throws UnsupportedE + "&response_type=code" + "&redirect_uri=" + URLEncoder.encode(redirectUri, "UTF-8") + "&access_type=" + accessType + "&scope=" + URLEncoder.encode(scope, "UTF-8") + "&state=" + state; - logger.debug("Sending redirect.. " + Utility.cleanLogString(redirectUrl)); + if(logger.isDebugEnabled()) { + logger.debug("Sending redirect.. " + Utility.cleanLogString(redirectUrl)); + } return redirectUrl; } @@ -1222,8 +1266,10 @@ public Response loginProducthunt(@Context HttpServletRequest request, @Context H String clientSecret = socialData.getProperty(prefix + "secret_key"); String redirectUri = socialData.getProperty(prefix + "redirect_uri"); - logger.debug(">> " + Utility.cleanLogString(request.getQueryString())); - + if(logger.isDebugEnabled()) { + logger.debug(">> " + Utility.cleanLogString(request.getQueryString())); + } + Hashtable params = new Hashtable(); params.put("client_id", clientId); @@ -1244,7 +1290,9 @@ public Response loginProducthunt(@Context HttpServletRequest request, @Context H accessToken.setProvider(AuthProvider.PRODUCT_HUNT); addAccessToken(accessToken, request); - logger.debug("Access Token is.. " + accessToken.getAccess_token()); + if(logger.isDebugEnabled()) { + logger.debug("Access Token is.. " + accessToken.getAccess_token()); + } } } @@ -1271,7 +1319,10 @@ private String getProducthuntRedirect(HttpServletRequest request) throws Unsuppo + "&response_type=code" + "&redirect_uri=" + URLEncoder.encode(redirectUri, "UTF-8") + "&scope=" + URLEncoder.encode(scope, "UTF-8"); - logger.debug("Sending redirect.. " + Utility.cleanLogString(redirectUrl)); + if(logger.isDebugEnabled()) { + logger.debug("Sending redirect.. " + Utility.cleanLogString(redirectUrl)); + } + return redirectUrl; } @@ -1300,8 +1351,10 @@ public Response loginIn(@Context HttpServletRequest request, @Context HttpServle String clientSecret = socialData.getProperty(prefix + "secret_key"); String redirectUri = socialData.getProperty(prefix + "redirect_uri"); - logger.debug(">> " + Utility.cleanLogString(request.getQueryString())); - + if(logger.isDebugEnabled()) { + logger.debug(">> " + Utility.cleanLogString(request.getQueryString())); + } + Hashtable params = new Hashtable(); params.put("client_id", clientId); params.put("redirect_uri", redirectUri); @@ -1320,7 +1373,10 @@ public Response loginIn(@Context HttpServletRequest request, @Context HttpServle } accessToken.setProvider(AuthProvider.IN); addAccessToken(accessToken, request); - logger.debug("Access Token is.. " + accessToken.getAccess_token()); + + if(logger.isDebugEnabled()) { + logger.debug("Access Token is.. " + accessToken.getAccess_token()); + } } } @@ -1345,8 +1401,11 @@ private String getInRedirect(HttpServletRequest request) throws UnsupportedEncod String redirectUrl = "https://www.linkedin.com/oauth/v2/authorization?" + "client_id=" + clientId + "&redirect_uri=" + redirectUri + "&state=" + UUID.randomUUID().toString() + "&response_type=code" + "&scope=" + URLEncoder.encode(scope, "UTF-8"); - - logger.debug("Sending redirect.. " + Utility.cleanLogString(redirectUrl)); + + if(logger.isDebugEnabled()) { + logger.debug("Sending redirect.. " + Utility.cleanLogString(redirectUrl)); + } + return redirectUrl; } @@ -1375,15 +1434,15 @@ public Response loginTwitter(@Context HttpServletRequest request, @Context HttpS if (userObj == null || userObj.getAccessToken(AuthProvider.GITHUB) == null) { String[] outputs = AbstractHttpHelper.getCodes(queryString); - String prefix = "git_"; - String clientId = socialData.getProperty(prefix + "client_id"); String clientSecret = socialData.getProperty(prefix + "secret_key"); String redirectUri = socialData.getProperty(prefix + "redirect_uri"); - logger.debug(">> " + Utility.cleanLogString(request.getQueryString())); - + if(logger.isDebugEnabled()) { + logger.debug(">> " + Utility.cleanLogString(request.getQueryString())); + } + Hashtable params = new Hashtable(); params.put("client_id", clientId); params.put("redirect_uri", redirectUri); @@ -1404,7 +1463,9 @@ public Response loginTwitter(@Context HttpServletRequest request, @Context HttpS accessToken.setProvider(AuthProvider.GITHUB); addAccessToken(accessToken, request); - logger.debug("Access Token is.. " + accessToken.getAccess_token()); + if(logger.isDebugEnabled()) { + logger.debug("Access Token is.. " + accessToken.getAccess_token()); + } } } @@ -1448,8 +1509,10 @@ private String getTwitterRedirect(HttpServletRequest request) throws Unsupported + "&oauth_callback=" + redirectUri + "&oauth_nonce=" + nonce + "&oauth_timestamp=" + timestamp + "&scope=" + URLEncoder.encode(scope, "UTF-8"); - logger.debug("Sending redirect.. " + Utility.cleanLogString(redirectUrl)); - + if(logger.isDebugEnabled()) { + logger.debug("Sending redirect.. " + Utility.cleanLogString(redirectUrl)); + } + return redirectUrl; } @@ -1780,8 +1843,10 @@ public StreamingOutput manCookie(@Context HttpServletRequest request, @Context H k.setPath(request.getContextPath()); response.addCookie(k); - logger.debug("Session id set to " + sessionId); - + if(logger.isDebugEnabled()) { + logger.debug("Session id set to " + sessionId); + } + InsightToken token = new InsightToken(); Hashtable outputHash = new Hashtable(); try { @@ -1818,7 +1883,10 @@ public StreamingOutput manCookie(@Context HttpServletRequest request, @Context H } } - logger.debug("Redirect URL " + Utility.cleanLogString(redir)); + if(logger.isDebugEnabled()) { + logger.debug("Redirect URL " + Utility.cleanLogString(redir)); + } + outputHash.put("PARAM", redir); // also tell the system that this session is not fully validated so if someone // comes without secret on this session From 7cf3b7a46351d17123cae6cb5ae775df8d0d1c15 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 7 Apr 2021 18:38:13 +0000 Subject: [PATCH 0770/1906] UPDATE ::: Sending file name in quotes to allow for different characters git-svn-id: svn://107.170.10.188:8080/Monolith/dev@43362 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 03099a8eeb819ff9718740bc84ac4864033f14c5 --- src/prerna/semoss/web/services/local/NameServer.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index 04ea57e1a..bf8701667 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -241,11 +241,9 @@ public Response downloadFile(@QueryParam("insightId") String insightId, @QueryPa return WebUtility.getResponse(errorMap, 400); } - // TODO: put file name cleanup - // cannot have things like "," in the name for the attachment String exportName = FilenameUtils.getName(filePath); return Response.status(200).entity(exportFile) - .header("Content-Disposition", "attachment; filename=" + exportName).build(); + .header("Content-Disposition", "attachment; filename=\"" + exportName + "\"").build(); } /////////////////////////////////////////////// From 6faa767d0b1c811b53989a2f077a9ea4e34c8626 Mon Sep 17 00:00:00 2001 From: kunalppatel9 Date: Tue, 13 Apr 2021 20:40:04 +0000 Subject: [PATCH 0771/1906] UPDATE ::: adding generic oauth provider with login/{provider} and userinfo/{provider] git-svn-id: svn://107.170.10.188:8080/Monolith/dev@43398 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 48e42af60ccb3826806d312732f4654d8324339d --- .../web/services/local/UserResource.java | 200 ++++++++++++++++-- 1 file changed, 185 insertions(+), 15 deletions(-) diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index abe05bc34..5d6bdb411 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -36,7 +36,9 @@ import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.Principal; +import java.util.Arrays; import java.util.HashMap; +import java.util.HashSet; import java.util.Hashtable; import java.util.List; import java.util.Map; @@ -45,6 +47,7 @@ import java.util.TreeMap; import java.util.UUID; import java.util.Vector; +import java.util.stream.Collectors; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; @@ -85,6 +88,7 @@ import prerna.auth.utils.SecurityAdminUtils; import prerna.auth.utils.SecurityUpdateUtils; import prerna.cluster.util.ClusterUtil; +import prerna.io.connector.GenericProfile; import prerna.io.connector.IConnectorIOp; import prerna.io.connector.google.GoogleEntityResolver; import prerna.io.connector.google.GoogleFileRetriever; @@ -156,23 +160,37 @@ public static String getLoginRedirect() { } private static void setLoginsAllowed() { - boolean nativeLogin = Boolean.parseBoolean(socialData.getProperty("native_login")); - boolean githubLogin = Boolean.parseBoolean(socialData.getProperty("github_login")); - boolean googleLogin = Boolean.parseBoolean(socialData.getProperty("google_login")); - boolean onedriveLogin = Boolean.parseBoolean(socialData.getProperty("ms_login")); - boolean siteminderLogin = Boolean.parseBoolean(socialData.getProperty("siteminder_login")); - boolean dropboxLogin = Boolean.parseBoolean(socialData.getProperty("dropbox_login")); - boolean cacLogin = Boolean.parseBoolean(socialData.getProperty("cac_login")); - boolean registration = Boolean.parseBoolean(socialData.getProperty("native_registration")); + UserResource.loginsAllowedMap = new HashMap<>(); - UserResource.loginsAllowedMap.put("native", nativeLogin); - UserResource.loginsAllowedMap.put("google", googleLogin); - UserResource.loginsAllowedMap.put("github", githubLogin); - UserResource.loginsAllowedMap.put("ms", onedriveLogin); - UserResource.loginsAllowedMap.put("siteminder", siteminderLogin); - UserResource.loginsAllowedMap.put("dropbox", dropboxLogin); - UserResource.loginsAllowedMap.put("cac", cacLogin); + + //define the default provider set + HashSet defaultProviders = new HashSet(Arrays.asList("native", "github", "google", + "ms","siteminder", "dropbox", "cac")); + + //get all _login props + Set loginProps = socialData.stringPropertyNames().stream().filter(str->str.endsWith("_login")).collect(Collectors.toSet()); + for( String prop : loginProps) { + //prop ex. ms_login + + //get provider from prop by split on _ + String provider = prop.split("_")[0]; + + UserResource.loginsAllowedMap.put(provider, Boolean.parseBoolean(socialData.getProperty(prop))); + + //remove the provider from the defaultProvider list + defaultProviders.remove(provider); + } + + //for loop through the defaultProviders list to make sure we set the rest to false + for(String provider: defaultProviders) { + UserResource.loginsAllowedMap.put(provider, false); + } + + //get if registration is allowed + boolean registration = Boolean.parseBoolean(socialData.getProperty("native_registration")); UserResource.loginsAllowedMap.put("registration", registration); + + } public static Map getLoginsAllowed() { @@ -533,6 +551,48 @@ public Response userinfoGithub(@Context HttpServletRequest request) { } return WebUtility.getResponse(ret, 200); } + + /** + * Gets user info for Generic Providers + */ + @GET + @Produces("application/json") + @Path("/userinfo/{provider}") + public Response userinfoGeneric(@PathParam("provider") String provider, @Context HttpServletRequest request) { + + + AuthProvider providerEnum = AuthProvider.getProviderFromString(provider.toUpperCase()); + + Map ret = new Hashtable<>(); + User user = (User) request.getSession().getAttribute(Constants.SESSION_USER); + String prefix = provider+"_"; + String userInfoURL = socialData.getProperty(prefix + "userinfo_url"); + //"name","id","email" + String beanProps = socialData.getProperty(prefix + "beanProps"); + String jsonPattern = socialData.getProperty(prefix + "jsonPattern"); + + String[] beanPropsArr = beanProps.split(",", -1); + + String accessString = null; + try { + if (user == null) { + ret.put(Constants.ERROR_MESSAGE, "Log into your " + providerEnum.toString() + " account"); + } else { + AccessToken genericToken = user.getAccessToken(providerEnum); + accessString = genericToken.getAccess_token(); + //String url = "https://graph.microsoft.com/v1.0/me/"; + String output = AbstractHttpHelper.makeGetCall(userInfoURL, accessString, null, true); + AccessToken accessToken2 = (AccessToken) BeanFiller.fillFromJson(output, jsonPattern, beanPropsArr, + new AccessToken()); + String name = accessToken2.getName(); + ret.put("name", name); + } + return WebUtility.getResponse(ret, 200); + } catch (Exception e) { + ret.put(Constants.ERROR_MESSAGE, "Log into your " + providerEnum.toString() + " account"); + return WebUtility.getResponse(ret, 200); + } + } ////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////// @@ -1516,6 +1576,116 @@ private String getTwitterRedirect(HttpServletRequest request) throws Unsupported return redirectUrl; } + + + /** + * Logs user in through generic provider + */ + @GET + @Produces("application/json") + @Path("/login/{provider}") + public Response loginGeneric(@PathParam("provider") String provider, @Context HttpServletRequest request, @Context HttpServletResponse response) + throws IOException { + /* + * Try to log in the user + * If they are not logged in + * Redirect the FE + */ + + AuthProvider providerEnum = AuthProvider.getProviderFromString(provider.toUpperCase()); + + User userObj = (User) request.getSession().getAttribute(Constants.SESSION_USER); + String queryString = request.getQueryString(); + if (queryString != null && queryString.contains("code=")) { + if (userObj == null || ((User) userObj).getAccessToken(providerEnum) == null) { + String[] outputs = AbstractHttpHelper.getCodes(queryString); + + String prefix = provider+"_"; + String clientId = socialData.getProperty(prefix + "client_id"); + String clientSecret = socialData.getProperty(prefix + "secret_key"); + String redirectUri = socialData.getProperty(prefix + "redirect_uri"); + //String tenant = socialData.getProperty(prefix + "tenant"); + + //removing scope for now as it isn't needed in token call usually + //String scope = socialData.getProperty(prefix + "scope"); + String token_url = socialData.getProperty(prefix + "token_url"); + + if(logger.isDebugEnabled()) { + logger.debug(">> " + Utility.cleanLogString(request.getQueryString())); + } + + Hashtable params = new Hashtable(); + params.put("client_id", clientId); + // params.put("scope", scope); + params.put("redirect_uri", redirectUri); + params.put("code", outputs[0]); + params.put("grant_type", "authorization_code"); + params.put("client_secret", clientSecret); + + + if(Strings.isNullOrEmpty(token_url)){ + throw new IllegalArgumentException("Token URL can not be null or empty"); + } + + AccessToken accessToken = AbstractHttpHelper.getAccessToken(token_url, params, true, true); + if (accessToken == null) { + // not authenticated + response.setStatus(302); + response.sendRedirect(getMSRedirect(request)); + return null; + } + + String userInfoURL = socialData.getProperty(prefix + "userinfo_url"); + //"name","id","email" + String beanProps = socialData.getProperty(prefix + "beanProps"); + String jsonPattern = socialData.getProperty(prefix + "jsonPattern"); + + accessToken.setProvider(providerEnum); + GenericProfile.fillAccessToken(accessToken,userInfoURL, beanProps, jsonPattern, null); + addAccessToken(accessToken, request); + + if(logger.isDebugEnabled()) { + logger.debug("Access Token is.. " + accessToken.getAccess_token()); + } + } + } + + // grab the user again + userObj = (User) request.getSession().getAttribute(Constants.SESSION_USER); + if (userObj == null || userObj.getAccessToken(providerEnum) == null) { + // not authenticated + response.setStatus(302); + response.sendRedirect(getGenericRedirect(provider, request)); + return null; + } + + setMainPageRedirect(request, response); + return null; + } + + private String getGenericRedirect(String provider, HttpServletRequest request) throws UnsupportedEncodingException { + String prefix = provider+"_"; + String clientId = socialData.getProperty(prefix + "client_id"); + String redirectUri = socialData.getProperty(prefix + "redirect_uri"); + //String tenant = socialData.getProperty(prefix + "tenant"); + String scope = socialData.getProperty(prefix + "scope"); // need to set this up and reuse + String auth_url = socialData.getProperty(prefix + "auth_url"); + + String state = UUID.randomUUID().toString(); + + if(Strings.isNullOrEmpty(auth_url)){ + throw new IllegalArgumentException("Authorize URL can not be null or empty"); + } + String redirectUrl = auth_url + "?" + "client_id=" + + clientId + "&response_type=code" + "&redirect_uri=" + URLEncoder.encode(redirectUri, "UTF-8") + + "&response_mode=query" + "&scope=" + URLEncoder.encode(scope) + "&state=" + state; + + if(logger.isDebugEnabled()) { + logger.debug("Sending redirect.. " + Utility.cleanLogString(redirectUrl)); + } + + return redirectUrl; + } // public static String calculateRFC2104HMAC(String data, String key) throws SignatureException, NoSuchAlgorithmException, InvalidKeyException { // SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), "HmacSHA1"); // Mac mac = Mac.getInstance("HmacSHA1"); From 74fbae4a37d442a2ad705a5962223e7c5a57cd8b Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 14 Apr 2021 00:02:16 +0000 Subject: [PATCH 0772/1906] UPDATE ::: Allowing an asset file to be considered the image file git-svn-id: svn://107.170.10.188:8080/Monolith/dev@43399 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: ecaea32130251e7f9f31557f89e9f8dec79c12fd --- src/prerna/upload/ImageUploader.java | 47 +++------------------------- 1 file changed, 5 insertions(+), 42 deletions(-) diff --git a/src/prerna/upload/ImageUploader.java b/src/prerna/upload/ImageUploader.java index 3650fbe46..8cfbd37a1 100644 --- a/src/prerna/upload/ImageUploader.java +++ b/src/prerna/upload/ImageUploader.java @@ -1,14 +1,12 @@ package prerna.upload; import java.io.File; -import java.io.FileFilter; import java.io.FilenameFilter; import java.io.IOException; import java.sql.SQLException; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.Vector; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; @@ -36,6 +34,7 @@ import prerna.util.Constants; import prerna.util.DIHelper; import prerna.util.Utility; +import prerna.util.insight.InsightUtility; import prerna.web.services.util.WebUtility; @Path("/images") @@ -137,7 +136,7 @@ public Response uploadAppImage(@Context ServletContext context, @Context HttpSer FilenameFilter appIdFilter = new WildcardFileFilter(appId + "*"); oldImages = f.getParentFile().listFiles(appIdFilter); } else { - oldImages = findImageFile(f.getParentFile()); + oldImages = InsightUtility.findImageFile(f.getParentFile()); } // delete if any exist if (oldImages != null) { @@ -230,7 +229,7 @@ public Response deleteAppImage(@Context HttpServletRequest request) throws SQLEx FilenameFilter appIdFilter = new WildcardFileFilter(appId + "*"); oldImages = f.listFiles(appIdFilter); } else { - oldImages = findImageFile(f); + oldImages = InsightUtility.findImageFile(f); } // delete if any exist if (oldImages != null) { @@ -367,7 +366,7 @@ public Response uploadInsightImage(@Context ServletContext context, @Context Htt } // find all the existing image files // and delete them - File[] oldImages = findImageFile(f); + File[] oldImages = InsightUtility.findImageFile(f); // delete if any exist if (oldImages != null) { for (File oldI : oldImages) { @@ -460,7 +459,7 @@ public Response deleteInsightImage(@Context HttpServletRequest request) throws S if (f.exists()) { // find all the existing image files // and delete them - File[] oldImages = findImageFile(f); + File[] oldImages = InsightUtility.findImageFile(f); // delete if any exist if (oldImages != null) { for (File oldI : oldImages) { @@ -481,41 +480,5 @@ public Response deleteInsightImage(@Context HttpServletRequest request) throws S returnMap.put("message", "Successfully deleted insight image"); return WebUtility.getResponse(returnMap, 200); } - - /** - * Find an image in the directory - * - * @param baseDir - * @return - */ - public static File[] findImageFile(String baseDir) { - List extensions = new Vector<>(); - extensions.add("image.png"); - extensions.add("image.jpeg"); - extensions.add("image.jpg"); - extensions.add("image.gif"); - extensions.add("image.svg"); - FileFilter imageExtensionFilter = new WildcardFileFilter(extensions); - File baseFolder = new File(baseDir); - - return baseFolder.listFiles(imageExtensionFilter); - } - /** - * Find an image in the directory - * - * @param baseDir - * @return - */ - public static File[] findImageFile(File baseFolder) { - List extensions = new Vector<>(); - extensions.add("image.png"); - extensions.add("image.jpeg"); - extensions.add("image.jpg"); - extensions.add("image.gif"); - extensions.add("image.svg"); - FileFilter imageExtensionFilter = new WildcardFileFilter(extensions); - - return baseFolder.listFiles(imageExtensionFilter); - } } From fc17b68f6e7f56dd439bc7f9e0b285e9e6b90f04 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 14 Apr 2021 13:09:37 +0000 Subject: [PATCH 0773/1906] UPDATE ::: Removing saml resource as it is done as a base servlet git-svn-id: svn://107.170.10.188:8080/Monolith/dev@43402 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 32e47b4dee1648463f98feb4d622f50184c17719 --- WebContent/WEB-INF/web.xml | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index 9089d1118..8c4ea48b2 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -383,22 +383,6 @@ AdminApplication /adminconfig/* - - SamlApplication - org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher - - javax.ws.rs.Application - prerna.semoss.web.app.SamlApplication - - - resteasy.servlet.mapping.prefix - /saml - - - - SamlApplication - /saml/* - From 899881ee9f56be462e94b057211ed646e6b7945f Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 14 Apr 2021 13:16:47 +0000 Subject: [PATCH 0774/1906] UPDATE ::: Pushing SAML base code commented out until we are done with the maven dependency deduplication git-svn-id: svn://107.170.10.188:8080/Monolith/dev@43403 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: d39d11976b69b527a5a08ce5861c5281d73b6bf0 --- .../semoss/web/app/SamlApplication.java | 51 --- .../web/services/saml/IdpSSOServlet.java | 55 ++++ .../web/services/saml/SPSSOServlet.java | 174 +++++++++++ .../services/saml/SamlVerifierResource.java | 20 -- .../services/saml/SamlVerifierServlet.java | 155 ++++++++++ src/prerna/web/conf/SSOFilter.java | 87 ++++++ src/prerna/web/conf/util/SSOUtil.java | 291 ++++++++++++++++++ 7 files changed, 762 insertions(+), 71 deletions(-) delete mode 100644 src/prerna/semoss/web/app/SamlApplication.java create mode 100644 src/prerna/semoss/web/services/saml/IdpSSOServlet.java create mode 100644 src/prerna/semoss/web/services/saml/SPSSOServlet.java delete mode 100644 src/prerna/semoss/web/services/saml/SamlVerifierResource.java create mode 100644 src/prerna/semoss/web/services/saml/SamlVerifierServlet.java create mode 100644 src/prerna/web/conf/SSOFilter.java create mode 100644 src/prerna/web/conf/util/SSOUtil.java diff --git a/src/prerna/semoss/web/app/SamlApplication.java b/src/prerna/semoss/web/app/SamlApplication.java deleted file mode 100644 index 850cee689..000000000 --- a/src/prerna/semoss/web/app/SamlApplication.java +++ /dev/null @@ -1,51 +0,0 @@ -/******************************************************************************* - * Copyright 2015 Defense Health Agency (DHA) - * - * If your use of this software does not include any GPLv2 components: - * Licensed 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. - * ---------------------------------------------------------------------------- - * If your use of this software includes any GPLv2 components: - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - *******************************************************************************/ -package prerna.semoss.web.app; - -import java.util.HashSet; -import java.util.Set; - -import javax.ws.rs.ApplicationPath; -import javax.ws.rs.core.Application; - -import prerna.semoss.web.services.saml.SamlVerifierResource; - -@ApplicationPath("/saml") -public class SamlApplication extends Application { - - private Set singletons = new HashSet(); - - public SamlApplication() { - singletons.add(new SamlVerifierResource()); - } - - @Override - public Set getSingletons() { - return singletons; - } -} diff --git a/src/prerna/semoss/web/services/saml/IdpSSOServlet.java b/src/prerna/semoss/web/services/saml/IdpSSOServlet.java new file mode 100644 index 000000000..fb6541be9 --- /dev/null +++ b/src/prerna/semoss/web/services/saml/IdpSSOServlet.java @@ -0,0 +1,55 @@ +//package prerna.semoss.web.services.saml; +// +//import java.io.IOException; +//import java.util.Map; +// +//import javax.servlet.ServletException; +//import javax.servlet.annotation.WebServlet; +//import javax.servlet.http.HttpServlet; +//import javax.servlet.http.HttpServletRequest; +//import javax.servlet.http.HttpServletResponse; +// +//import org.apache.logging.log4j.LogManager; +//import org.apache.logging.log4j.Logger; +// +//import prerna.web.conf.util.SSOUtil; +// +///** +// * Servlet implementation class for IDP Initiated SAML +// */ +//@WebServlet("/IdpSSOServlet") +//public class IdpSSOServlet extends HttpServlet { +// +// private static final long serialVersionUID = 1L; +// private static final Logger logger = LogManager.getLogger(IdpSSOServlet.class); +// +// public IdpSSOServlet() { +// super(); +// } +// +// /** +// * The below doGet is called from the SSOFilter via the samlLogin/index.html page. +// * Once called, it gets all the required openAM params from the SSOUtil class and +// * does a redirect to the IDP. +// */ +// protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { +// logger.info("Starting IDP initiated SSO."); +// SSOUtil util = SSOUtil.getInstance(); +// util.setSSODeployURI((request).getRequestURI()); +// util.configureSSO(request, response); +// Map map = util.getSSOMap(); +// String idpBaseUrl = map.get("idpBaseUrl"); +// String idpMetaAlias = map.get("idpMetaAlias"); +// String spEntityID = map.get("spEntityID"); +// String idpRequest = new StringBuilder(idpBaseUrl). +// append("/idpssoinit?NameIDFormat=urn:oasis:names:tc:SAML:2.0:nameid-format:transient&metaAlias="). +// append(idpMetaAlias). +// append("&spEntityID="). +// append(spEntityID). +// append("&binding=urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"). +// toString(); +// logger.info("Redirect request created and redirecting to IDP now. IDPRequest - " + idpRequest); +// response.sendRedirect(idpRequest); +// } +// +//} diff --git a/src/prerna/semoss/web/services/saml/SPSSOServlet.java b/src/prerna/semoss/web/services/saml/SPSSOServlet.java new file mode 100644 index 000000000..6f9d6ca94 --- /dev/null +++ b/src/prerna/semoss/web/services/saml/SPSSOServlet.java @@ -0,0 +1,174 @@ +//package prerna.semoss.web.services.saml; +// +//import java.io.IOException; +//import java.util.ArrayList; +//import java.util.List; +//import java.util.Map; +// +//import javax.servlet.ServletException; +//import javax.servlet.annotation.WebServlet; +//import javax.servlet.http.HttpServlet; +//import javax.servlet.http.HttpServletRequest; +//import javax.servlet.http.HttpServletResponse; +// +//import org.forgerock.guice.core.InjectorHolder; +//import org.forgerock.openam.audit.AuditEventFactory; +//import org.forgerock.openam.audit.AuditEventPublisher; +//import org.forgerock.openam.saml2.audit.SAML2Auditor; +// +//import com.sun.identity.saml.common.SAMLUtils; +//import com.sun.identity.saml2.common.SAML2Constants; +//import com.sun.identity.saml2.common.SAML2Exception; +//import com.sun.identity.saml2.common.SAML2Utils; +//import com.sun.identity.saml2.meta.SAML2MetaManager; +//import com.sun.identity.saml2.profile.SPCache; +//import com.sun.identity.saml2.profile.SPSSOFederate; +// +//import prerna.web.conf.util.SSOUtil; +// +///** +// * Servlet implementation class for SP Initiated SAML +// */ +//@WebServlet("/SPSSOServlet") +//public class SPSSOServlet extends HttpServlet { +// private static final long serialVersionUID = 1L; +// +// public SPSSOServlet() { +// super(); +// } +// +// /** +// * The below doGet is called from the SSOFilter via the samlLogin/index.html page. +// * Once called, it gets all the required openAM params from the SSOUtil class and +// * does a call to the IDP with the SAML assertions. +// */ +// protected void doGet(HttpServletRequest request, HttpServletResponse response) +// throws ServletException, IOException { +// SSOUtil util = SSOUtil.getInstance(); +// if (!util.isConfigured()) { +// util.setSSODeployURI((request).getRequestURI()); +// util.configureSSO(request, response); +// } +// initiateSSO(request, response); +// } +// +// public void initiateSSO(HttpServletRequest request, HttpServletResponse response) { +// AuditEventPublisher aep = InjectorHolder.getInstance(AuditEventPublisher.class); +// AuditEventFactory aef = InjectorHolder.getInstance(AuditEventFactory.class); +// SAML2Auditor saml2Auditor = new SAML2Auditor(aep, aef, request); +// +// saml2Auditor.setMethod("fedletSSOInit"); +// saml2Auditor.setSessionTrackingId(request.getSession().getId()); +// saml2Auditor.auditAccessAttempt(); +// +// // Retreive the Request Query Parameters +// // metaAlias and idpEntiyID are the required query parameters +// // metaAlias - Service Provider Entity Id +// // idpEntityID - Identity Provider Identifier +// // Query parameters supported will be documented. +// String idpEntityID = null; +// String metaAlias = null; +// Map paramsMap = null; +// try { +// String reqID = request.getParameter("requestID"); +// if (reqID != null) { +// // get the preferred idp +// idpEntityID = SAML2Utils.getPreferredIDP(request); +// paramsMap = (Map) SPCache.reqParamHash.get(reqID); +// metaAlias = (String) paramsMap.get("metaAlias"); +// SPCache.reqParamHash.remove(reqID); +// } else { +// // this is an original request check +// // get the metaAlias ,idpEntityID +// // if idpEntityID is null redirect to IDP Discovery +// // Service to retrieve. +// metaAlias = request.getParameter("metaAlias"); +// if ((metaAlias == null) || (metaAlias.length() == 0)) { +// SAML2MetaManager manager = new SAML2MetaManager(); +// List spMetaAliases = manager.getAllHostedServiceProviderMetaAliases("/"); +// if ((spMetaAliases != null) && !spMetaAliases.isEmpty()) { +// // get first one +// metaAlias = (String) spMetaAliases.get(0); +// } +// if ((metaAlias == null) || (metaAlias.length() == 0)) { +// saml2Auditor.auditAccessFailure(String.valueOf(HttpServletResponse.SC_BAD_REQUEST), +// SAML2Utils.bundle.getString("nullSPEntityID")); +// SAMLUtils.sendError(request, response, HttpServletResponse.SC_BAD_REQUEST, "nullSPEntityID", +// SAML2Utils.bundle.getString("nullSPEntityID")); +// +// return; +// } +// } +// +// idpEntityID = request.getParameter("idpEntityID"); +// paramsMap = SAML2Utils.getParamsMap(request); +// // always use transient +// List list = new ArrayList(); +// list.add(SAML2Constants.NAMEID_TRANSIENT_FORMAT); +// paramsMap.put(SAML2Constants.NAMEID_POLICY_FORMAT, list); +// if (paramsMap.get(SAML2Constants.BINDING) == null) { +// // use POST binding +// list = new ArrayList(); +// list.add(SAML2Constants.HTTP_POST); +// paramsMap.put(SAML2Constants.BINDING, list); +// } +// +// if ((idpEntityID == null) || (idpEntityID.length() == 0)) { +// // get reader url +// String readerURL = SAML2Utils.getReaderURL(metaAlias); +// if (readerURL != null) { +// String rID = SAML2Utils.generateID(); +// String redirectURL = SAML2Utils.getRedirectURL(readerURL, rID, request); +// if (redirectURL != null) { +// paramsMap.put("metaAlias", metaAlias); +// SPCache.reqParamHash.put(rID, paramsMap); +// response.sendRedirect(redirectURL); +// return; +// } +// } +// } +// } +// +// if ((idpEntityID == null) || (idpEntityID.length() == 0)) { +// SAML2MetaManager manager = new SAML2MetaManager(); +// List idpEntities = manager.getAllRemoteIdentityProviderEntities("/"); +// if ((idpEntities == null) || idpEntities.isEmpty()) { +// saml2Auditor.auditAccessFailure(String.valueOf(HttpServletResponse.SC_BAD_REQUEST), +// SAML2Utils.bundle.getString("idpNotFound")); +// SAMLUtils.sendError(request, response, HttpServletResponse.SC_BAD_REQUEST, "idpNotFound", +// SAML2Utils.bundle.getString("idpNotFound")); +// return; +// } else if (idpEntities.size() == 1) { +// // only one IDP, just use it +// idpEntityID = (String) idpEntities.get(0); +// } else { +// // multiple IDP configured in fedlet +// saml2Auditor.auditAccessFailure(String.valueOf(HttpServletResponse.SC_BAD_REQUEST), +// SAML2Utils.bundle.getString("nullIDPEntityID")); +// SAMLUtils.sendError(request, response, HttpServletResponse.SC_BAD_REQUEST, "nullIDPEntityID", +// SAML2Utils.bundle.getString("nullIDPEntityID")); +// return; +// } +// } +// SPSSOFederate.initiateAuthnRequest(request, response, metaAlias, idpEntityID, paramsMap, saml2Auditor); +// saml2Auditor.auditAccessSuccess(); +// System.out.println("IDP call initiated successfully. Waiting for IDP callback."); +// } catch (SAML2Exception sse) { +// SAML2Utils.debug.error("Error sending AuthnRequest ", sse); +// saml2Auditor.auditAccessFailure(String.valueOf(HttpServletResponse.SC_BAD_REQUEST), +// SAML2Utils.bundle.getString("requestProcessingError")); +// SAMLUtils.sendError(request, response, HttpServletResponse.SC_BAD_REQUEST, "requestProcessingError", +// SAML2Utils.bundle.getString("requestProcessingError") + " " + sse.getMessage()); +// return; +// } catch (Exception e) { +// SAML2Utils.debug.error("Error processing Request ", e); +// saml2Auditor.auditAccessFailure(String.valueOf(HttpServletResponse.SC_BAD_REQUEST), +// SAML2Utils.bundle.getString("requestProcessingError")); +// SAMLUtils.sendError(request, response, HttpServletResponse.SC_BAD_REQUEST, "requestProcessingError", +// SAML2Utils.bundle.getString("requestProcessingError") + " " + e.getMessage()); +// return; +// } +// +// } +// +//} diff --git a/src/prerna/semoss/web/services/saml/SamlVerifierResource.java b/src/prerna/semoss/web/services/saml/SamlVerifierResource.java deleted file mode 100644 index 3a3d99383..000000000 --- a/src/prerna/semoss/web/services/saml/SamlVerifierResource.java +++ /dev/null @@ -1,20 +0,0 @@ -package prerna.semoss.web.services.saml; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.core.Response; - -import prerna.web.services.util.WebUtility; - -@Path("/config") -public class SamlVerifierResource { - - @GET - @Path("/test") - @Produces("application/json") - public Response test() { - return WebUtility.getResponse("success", 200); - } - -} diff --git a/src/prerna/semoss/web/services/saml/SamlVerifierServlet.java b/src/prerna/semoss/web/services/saml/SamlVerifierServlet.java new file mode 100644 index 000000000..7dc1976ec --- /dev/null +++ b/src/prerna/semoss/web/services/saml/SamlVerifierServlet.java @@ -0,0 +1,155 @@ +//package prerna.semoss.web.services.saml; +// +//import java.io.BufferedWriter; +//import java.io.File; +//import java.io.FileWriter; +//import java.io.IOException; +//import java.io.PrintWriter; +//import java.util.List; +//import java.util.Map; +// +//import javax.servlet.ServletException; +//import javax.servlet.annotation.WebServlet; +//import javax.servlet.http.HttpServlet; +//import javax.servlet.http.HttpServletRequest; +//import javax.servlet.http.HttpServletResponse; +//import javax.servlet.http.HttpSession; +// +//import org.apache.commons.lang.StringUtils; +//import org.apache.logging.log4j.LogManager; +//import org.apache.logging.log4j.Logger; +//import org.owasp.encoder.Encode; +// +//import com.sun.identity.plugin.session.SessionException; +//import com.sun.identity.saml.common.SAMLUtils; +//import com.sun.identity.saml2.assertion.Assertion; +//import com.sun.identity.saml2.assertion.Attribute; +//import com.sun.identity.saml2.assertion.AttributeStatement; +//import com.sun.identity.saml2.assertion.NameID; +//import com.sun.identity.saml2.assertion.Subject; +//import com.sun.identity.saml2.common.SAML2Constants; +//import com.sun.identity.saml2.common.SAML2Exception; +//import com.sun.identity.saml2.profile.SPACSUtils; +//import com.sun.identity.saml2.protocol.Response; +// +//import prerna.auth.AccessToken; +//import prerna.auth.AuthProvider; +//import prerna.auth.User; +//import prerna.auth.utils.SecurityUpdateUtils; +//import prerna.util.Constants; +//import prerna.util.DIHelper; +//import prerna.web.conf.AdminStartupFilter; +//import prerna.web.conf.util.SSOUtil; +// +//@WebServlet("/saml/config/fedletapplication") +//public class SamlVerifierServlet extends HttpServlet { +// +// private static final long serialVersionUID = -3853767230988751741L; +// private static final Logger logger = LogManager.getLogger(SamlVerifierServlet.class); +// +// public SamlVerifierServlet() { +// super(); +// } +// +// protected void doPost(HttpServletRequest request, HttpServletResponse response) +// throws ServletException, IOException { +// logger.info("Starting saml verification doPost."); +// verifySamlOutput(request, response); +// logger.info("Ending saml verification doPost."); +// } +// +// public void verifySamlOutput(HttpServletRequest request, HttpServletResponse response) +// throws ServletException, IOException { +// +// logger.info("Connected to IDP. Starting validation of the assertions and other details."); +// // We define a map which will carry all the output from the saml verifications. +// Map map; +// +// // We need to pass a writer to the SAMl API to write Federation related +// // logs. This location is specified in the RDF.props file. Below is a +// // sample file path that we actually need to give. Make sure the Federation +// // file is there inside the debug folder. +// // "C:\\workspace\\Semoss_Dev\\saml\\mesoc\\conf\\debug\\Federation" +// String federationLogPath = ((String) DIHelper.getInstance().getCoreProp().get("SAML_FEDERATION_LOG_PATH")).trim(); +// BufferedWriter out = new BufferedWriter( +// new FileWriter(new File(federationLogPath))); +// +// try { +// // invoke the SAML processing logic. this will do all the +// // necessary processing conforming to SAMLv2 specifications, +// // such as XML signature validation, Audience and Recipient +// // validation etc. +// map = SPACSUtils.processResponseForFedlet(request, response, new PrintWriter(out, true)); +// +// // Check for relay URL in case IDP needs to redirect to specific page in the APP. +// String relayUrl = (String) map.get(SAML2Constants.RELAY_STATE); +// if ((relayUrl != null) && (relayUrl.length() != 0)) { +// // something special for validation to send redirect +// int stringPos = relayUrl.indexOf("sendRedirectForValidationNow=true"); +// if (stringPos != -1) { +// response.sendRedirect(relayUrl); +// } +// } +// +// // Get all the details from the SAML verification. +// // We just use the assertions, but we keep the code +// // below in case the other details might get used in +// // the near/distant future. +// Response samlResp = (Response) map.get(SAML2Constants.RESPONSE); +// Assertion assertion = (Assertion) map.get(SAML2Constants.ASSERTION); +// Subject subject = (Subject) map.get(SAML2Constants.SUBJECT); +// String entityID = (String) map.get(SAML2Constants.IDPENTITYID); +// String spEntityID = (String) map.get(SAML2Constants.SPENTITYID); +// NameID nameId = (NameID) map.get(SAML2Constants.NAMEID); +// String value = nameId.getValue(); +// String format = nameId.getFormat(); +// +// List attrlist = assertion.getAttributeStatements(); +// String userId = null; +// for (AttributeStatement stmt : attrlist) { +// List attributeList = stmt.getAttribute(); +// for (Attribute attr : attributeList) { +// if (attr.getName().equalsIgnoreCase("mail")) { +// logger.debug(" Attrubute name - %s, Attribute value - %s\n", attr.getName(), +// attr.getAttributeValue()); +// String valXml = (String) attr.getAttributeValue().get(0); +// userId = StringUtils.substringBetween(valXml, ">", "<"); +// } +// } +// } +// +// logger.info("Checking if user id is present in the SAML..."); +// +// if (userId == null || userId.isEmpty()) { +// throw new IllegalArgumentException("Did not receive valid userID from IDP. " +// + "Possible cause - user does not have access to IDP and you need to provide access to the user on the IDP side."); +// } +// +// logger.info("User id is good. Creating User/Token and setting it to session."); +// HttpSession session = request.getSession(true); +// AccessToken token = null; +// User user = new User(); +// token = new AccessToken(); +// token.setProvider(AuthProvider.SAML); +// token.setUsername(userId); +// user.setAccessToken(token); +// SecurityUpdateUtils.addOAuthUser(token); +// session.setAttribute(Constants.SESSION_USER, user); +// +// logger.info("Session is created and user all set to get in. Hold on, redirecting... "); +// if (session != null && session.getAttribute(SSOUtil.SAML_REDIRECT_KEY) != null) { +// String originalRedirect = session.getAttribute(SSOUtil.SAML_REDIRECT_KEY) + ""; +// String encodedRedirectUrl = Encode.forHtml(originalRedirect); +// AdminStartupFilter.setSuccessfulRedirectUrl(encodedRedirectUrl); +// response.setHeader("redirect", encodedRedirectUrl); +// response.sendRedirect(encodedRedirectUrl); +// } +// +// } catch (SAML2Exception | IOException | SessionException | ServletException sme) { +// SAMLUtils.sendError(request, response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, +// "failedToProcessSSOResponse", sme.getMessage()); +// } +// +// } +// +//} diff --git a/src/prerna/web/conf/SSOFilter.java b/src/prerna/web/conf/SSOFilter.java new file mode 100644 index 000000000..17ad0ef8b --- /dev/null +++ b/src/prerna/web/conf/SSOFilter.java @@ -0,0 +1,87 @@ +//package prerna.web.conf; +// +//import java.io.IOException; +// +//import javax.servlet.Filter; +//import javax.servlet.FilterChain; +//import javax.servlet.FilterConfig; +//import javax.servlet.ServletException; +//import javax.servlet.ServletRequest; +//import javax.servlet.ServletResponse; +//import javax.servlet.http.HttpServletRequest; +//import javax.servlet.http.HttpServletResponse; +//import javax.servlet.http.HttpSession; +// +//import org.apache.logging.log4j.LogManager; +//import org.apache.logging.log4j.Logger; +// +//import prerna.auth.User; +//import prerna.semoss.web.services.config.AdminConfigService; +//import prerna.util.Constants; +//import prerna.util.Utility; +//import prerna.web.conf.util.SSOUtil; +// +///** +// * Servlet Filter implementation class SamlFilter +// */ +//public class SSOFilter implements Filter { +// +// private static final Logger logger = LogManager.getLogger(SSOFilter.class); +// +// private static final String SAML_LOGIN_HTML = "/samlLogin/"; +// +// /** +// * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain) +// */ +// public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { +// +// HttpSession session = ((HttpServletRequest) request).getSession(false); +// User user = null; +// +// // Check if user is already there in the session. If there, +// // then get the existing user and travel down the chain. +// if (session != null) { +// user = (User) session.getAttribute(Constants.SESSION_USER); +// } +// +// // User has not logged in - redirect to the base page to start the +// // SAML workflow +// if(user == null) { +// logger.info("Starting saml transaction."); +// +// // we need to store information in the session +// // so that we can properly come back to the referer once an admin has been added +// String referer = ((HttpServletRequest) request).getHeader("referer"); +// referer = referer + "#!/login"; +// ((HttpServletRequest) request).getSession(true).setAttribute(SSOUtil.SAML_REDIRECT_KEY, referer); +// +// // this will be the deployment name of the app +// String contextPath = request.getServletContext().getContextPath(); +// +// // this will be the full path of the request +// // like http://localhost:8080/Monolith_Dev/api/engine/runPixel +// String fullUrl = Utility.cleanHttpResponse(((HttpServletRequest) request).getRequestURL().toString()); +// +// // we redirect to the index.html page specifically created for the SAML call. +// String redirectUrl = fullUrl.substring(0, fullUrl.indexOf(contextPath) + contextPath.length()) + SAML_LOGIN_HTML; +// ((HttpServletResponse) response).setHeader("redirect", redirectUrl); +// ((HttpServletResponse) response).sendError(302, "Need to redirect to " + redirectUrl); +// return; +// } +// +// chain.doFilter(request, response); +// } +// +// @Override +// public void destroy() { +// // TODO Auto-generated method stub +// +// } +// +// @Override +// public void init(FilterConfig arg0) throws ServletException { +// // TODO Auto-generated method stub +// +// } +// +//} diff --git a/src/prerna/web/conf/util/SSOUtil.java b/src/prerna/web/conf/util/SSOUtil.java new file mode 100644 index 000000000..7b096857c --- /dev/null +++ b/src/prerna/web/conf/util/SSOUtil.java @@ -0,0 +1,291 @@ +//package prerna.web.conf.util; +// +//import java.io.File; +//import java.io.FileNotFoundException; +//import java.io.IOException; +//import java.io.InputStream; +//import java.util.ArrayList; +//import java.util.HashMap; +//import java.util.Iterator; +//import java.util.List; +//import java.util.Map; +// +//import javax.servlet.ServletException; +//import javax.servlet.http.HttpServletRequest; +//import javax.servlet.http.HttpServletResponse; +// +//import org.apache.logging.log4j.LogManager; +//import org.apache.logging.log4j.Logger; +// +//import com.sun.identity.saml2.common.SAML2Utils; +//import com.sun.identity.saml2.jaxb.metadata.AssertionConsumerServiceElement; +//import com.sun.identity.saml2.jaxb.metadata.IDPSSODescriptorElement; +//import com.sun.identity.saml2.jaxb.metadata.SPSSODescriptorElement; +//import com.sun.identity.saml2.jaxb.metadata.SingleSignOnServiceElement; +//import com.sun.identity.saml2.meta.SAML2MetaException; +//import com.sun.identity.saml2.meta.SAML2MetaManager; +// +//import prerna.util.DIHelper; +// +///** +// * +// * This util class is where we do all the configuration. +// * The entire SAML configuration is created here. The +// * implementation is very much specific to OpenAM. +// * +// */ +// +//public class SSOUtil { +// +// private static final Logger logger = LogManager.getLogger(FileAppender.class); +// private static String fedletHomeDir = ""; +// private static String deployuri = ""; +// private static final Map ssoMap = new HashMap(); +// private static final String HTTP_POST_BINDING = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"; +// private static boolean IS_CONFIGURED = false; +// public boolean is_authenticated = false; +// private static SSOUtil _instance; +// public static String SAML_REDIRECT_KEY = "SAML_REDIRECT_KEY"; +// +// static { +// _instance = new SSOUtil(); +// } +// +// +// private SSOUtil() { +// +// } +// +// /** +// * This method sets up the SAML home directory and other env variables +// * needed for the handshake to happen correctly between the SP and the +// * IDP. +// */ +// +// private void setFedletHomeDir() { +// logger.info("SSO directory setup starting"); +// +// // Nice to have these setup in the env. +// System.setProperty("com.iplanet.am.cookie.name", "iPlanetDirectoryPro"); +// System.setProperty("com.sun.identity.federation.fedCookieName", "fedCookie"); +// +// // this is where we set the SAML home dir by getting the loc from RDF props. +// String confLocation = ((String) DIHelper.getInstance().getCoreProp().get("SAML_PROP_LOC")).trim(); +// logger.info("Directory is set to.. " + confLocation); +// System.getProperties().setProperty("com.sun.identity.fedlet.home", confLocation); +// +// // Check if the deployuri is valid, otherwise throw exception. +// if(deployuri == null || deployuri.isEmpty()) +// throw new IllegalArgumentException("Deploy uri is null or empty. Cannot create SSO config."); +// int slashLoc = deployuri.indexOf("/", 1); +// if (slashLoc != -1) { +// deployuri = deployuri.substring(0, slashLoc); +// } +// +// // Set the saml config location +// fedletHomeDir = confLocation; +// if ((fedletHomeDir == null) || (fedletHomeDir.trim().length() == 0)) { +// if (System.getProperty("user.home").equals(File.separator)) { +// fedletHomeDir = File.separator + "fedlet"; +// } else { +// fedletHomeDir = System.getProperty("user.home") + File.separator + "fedlet"; +// } +// } +// logger.info("SSO directory setup complete."); +// } +// +// /* +// * Set all the properties related to SSO in this method. +// */ +// private void setSSOProperties(HttpServletRequest request, HttpServletResponse response) throws IOException { +// +// // First set the SAML home dir. +// setFedletHomeDir(); +// +// String spEntityID = null; +// String spMetaAlias = null; +// String idpEntityID = null; +// String idpMetaAlias = null; +// try { +// +// File dir = new File(fedletHomeDir); +// File file = new File(fedletHomeDir + File.separator + "FederationConfig.properties"); +// logger.info("Fedlet config being used " + file); +// if (!dir.exists() || !dir.isDirectory()) { +// throw new FileNotFoundException("Configuration directory does not exist."); +// } else if (!file.exists()) { +// throw new FileNotFoundException("Configuration files do not exist."); +// } else { +// SAML2MetaManager manager = new SAML2MetaManager(); +// List spEntities = manager.getAllHostedServiceProviderEntities("/"); +// if ((spEntities != null) && !spEntities.isEmpty()) { +// // get first one +// spEntityID = (String) spEntities.get(0); +// } +// +// List spMetaAliases = manager.getAllHostedServiceProviderMetaAliases("/"); +// if ((spMetaAliases != null) && !spMetaAliases.isEmpty()) { +// // get first one +// spMetaAlias = (String) spMetaAliases.get(0); +// } +// +// List trustedIDPs = new ArrayList(); +// idpEntityID = request.getParameter("idpEntityID"); +// if ((idpEntityID == null) || (idpEntityID.length() == 0)) { +// // find out all trusted IDPs +// List idpEntities = manager.getAllRemoteIdentityProviderEntities("/"); +// if ((idpEntities != null) && !idpEntities.isEmpty()) { +// int numOfIDP = idpEntities.size(); +// for (int j = 0; j < numOfIDP; j++) { +// String idpID = (String) idpEntities.get(j); +// if (manager.isTrustedProvider("/", spEntityID, idpID)) { +// trustedIDPs.add(idpID); +// } +// } +// } +// } +// +// // get the single IDP entity ID +// if (!trustedIDPs.isEmpty()) { +// idpEntityID = (String) trustedIDPs.get(0); +// } +// if ((spEntityID == null) || (idpEntityID == null)) { +// throw new SAML2MetaException( +// "Fedlet or remote Identity Provider metadata is not configured. Please configure SP/IDP first."); +// } else { +// // IDP base URL +// Map idpMap = getIDPBaseUrlAndMetaAlias(idpEntityID, deployuri); +// String idpBaseUrl = (String) idpMap.get("idpBaseUrl"); +// idpMetaAlias = (String) idpMap.get("idpMetaAlias"); +// String fedletBaseUrl = getFedletBaseUrl(spEntityID, deployuri); +// +// // Put everything in the SSOMap. +// ssoMap.put("idpBaseUrl", idpBaseUrl); +// ssoMap.put("fedletBaseUrl", fedletBaseUrl); +// ssoMap.put("idpMetaAlias", idpMetaAlias); +// ssoMap.put("spEntityID", spEntityID); +// ssoMap.put("metaAlias", spMetaAlias); +// ssoMap.put("idpEntityID", idpEntityID); +// ssoMap.put("binding", HTTP_POST_BINDING); +// +// logger.info("Fedlet (SP) Entity ID:" + spEntityID); +// logger.info("IDP Entity ID:" + idpEntityID); +// +// //populateSSOMap(spMetaAlias, idpEntityID, HTTP_POST_BINDING); +// } +// IS_CONFIGURED = true; +// } +// } catch (SAML2MetaException se) { +// se.printStackTrace(); +// response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, se.getMessage()); +// return; +// } +// } +// +// /** +// * This method gets the IDP related details and puts them into the map. +// * +// * @param idpEntityID +// * @param deployuri +// * @return +// */ +// private Map getIDPBaseUrlAndMetaAlias(String idpEntityID, String deployuri) { +// Map returnMap = new HashMap<>(); +// if (idpEntityID == null) { +// return returnMap; +// } +// try { +// // find out IDP meta alias +// SAML2MetaManager manager = new SAML2MetaManager(); +// IDPSSODescriptorElement idp = manager.getIDPSSODescriptor("/", idpEntityID); +// List ssoServiceList = idp.getSingleSignOnService(); +// if ((ssoServiceList != null) && (!ssoServiceList.isEmpty())) { +// Iterator i = ssoServiceList.iterator(); +// while (i.hasNext()) { +// SingleSignOnServiceElement sso = (SingleSignOnServiceElement) i.next(); +// if ((sso != null) && (sso.getBinding() != null)) { +// String ssoURL = sso.getLocation(); +// int loc = ssoURL.indexOf("/metaAlias/"); +// if (loc == -1) { +// continue; +// } else { +// returnMap.put("idpMetaAlias", ssoURL.substring(loc + 10)); +// String tmp = ssoURL.substring(0, loc); +// loc = tmp.lastIndexOf("/"); +// returnMap.put("idpBaseUrl", tmp.substring(0, loc)); +// break; +// } +// } +// } +// } +// } catch (Exception e) { +// SAML2Utils.debug.error("Couldn't get IDP base url:", e); +// } +// return returnMap; +// } +// +// /** +// * Helper method to read the config files and set the base urls saml style. +// * +// * @param spEntityID +// * @param deployuri +// * @return +// */ +// private String getFedletBaseUrl(String spEntityID, String deployuri) { +// if (spEntityID == null) { +// return null; +// } +// String fedletBaseUrl = null; +// try { +// SAML2MetaManager manager = new SAML2MetaManager(); +// SPSSODescriptorElement sp = manager.getSPSSODescriptor("/", spEntityID); +// List acsList = sp.getAssertionConsumerService(); +// if ((acsList != null) && (!acsList.isEmpty())) { +// Iterator j = acsList.iterator(); +// while (j.hasNext()) { +// AssertionConsumerServiceElement acs = (AssertionConsumerServiceElement) j.next(); +// if ((acs != null) && (acs.getBinding() != null)) { +// String acsURL = acs.getLocation(); +// int loc = acsURL.indexOf(deployuri + "/"); +// if (loc == -1) { +// continue; +// } else { +// fedletBaseUrl = acsURL.substring(0, loc + deployuri.length()); +// break; +// } +// } +// } +// } +// } catch (Exception e) { +// SAML2Utils.debug.error("Couldn't get fedlet base url:", e); +// } +// return fedletBaseUrl; +// } +// +// private void populateSSOMap(String spMetaAlias, String idpEntityID, String binding) { +// ssoMap.put("metaAlias", spMetaAlias); +// ssoMap.put("idpEntityID", idpEntityID); +// ssoMap.put("binding", binding); +// } +// +// public Map getSSOMap(){ +// return ssoMap; +// } +// +// public void setSSODeployURI(String uri) { +// deployuri = uri; +// } +// +// public void configureSSO(HttpServletRequest request, HttpServletResponse response) throws IOException { +// setSSOProperties(request, response); +// } +// +// public boolean isConfigured() { +// return IS_CONFIGURED; +// } +// +// public static SSOUtil getInstance() { +// return _instance; +// } +// +//} From 9a5eb8d06617dd129e1e0a448ffa145c7f9be79a Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 14 Apr 2021 14:32:03 +0000 Subject: [PATCH 0775/1906] UPDATE ::: Pushing SAML code and pom requirements git-svn-id: svn://107.170.10.188:8080/Monolith/dev@43404 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: c5ac0867d81cfb5cd3cb6f4398adc6d763ba9b34 --- pom.xml | 14 +- .../web/services/saml/IdpSSOServlet.java | 110 ++-- .../web/services/saml/SPSSOServlet.java | 348 +++++------ .../services/saml/SamlVerifierServlet.java | 310 +++++----- src/prerna/web/conf/util/SSOUtil.java | 580 +++++++++--------- 5 files changed, 686 insertions(+), 676 deletions(-) diff --git a/pom.xml b/pom.xml index 104f13ff2..c41bb7172 100644 --- a/pom.xml +++ b/pom.xml @@ -1044,7 +1044,7 @@ io.netty netty-all - 4.1.51.Final + 4.1.50.Final compile @@ -1959,5 +1959,17 @@ zookeeper 3.6.2 + + org.elasticsearch.plugin + x-pack-sql-jdbc + 7.11.2 + + + + + org.openidentityplatform.openam + openam-federation-library + 14.6.1 + \ No newline at end of file diff --git a/src/prerna/semoss/web/services/saml/IdpSSOServlet.java b/src/prerna/semoss/web/services/saml/IdpSSOServlet.java index fb6541be9..44be1206e 100644 --- a/src/prerna/semoss/web/services/saml/IdpSSOServlet.java +++ b/src/prerna/semoss/web/services/saml/IdpSSOServlet.java @@ -1,55 +1,55 @@ -//package prerna.semoss.web.services.saml; -// -//import java.io.IOException; -//import java.util.Map; -// -//import javax.servlet.ServletException; -//import javax.servlet.annotation.WebServlet; -//import javax.servlet.http.HttpServlet; -//import javax.servlet.http.HttpServletRequest; -//import javax.servlet.http.HttpServletResponse; -// -//import org.apache.logging.log4j.LogManager; -//import org.apache.logging.log4j.Logger; -// -//import prerna.web.conf.util.SSOUtil; -// -///** -// * Servlet implementation class for IDP Initiated SAML -// */ -//@WebServlet("/IdpSSOServlet") -//public class IdpSSOServlet extends HttpServlet { -// -// private static final long serialVersionUID = 1L; -// private static final Logger logger = LogManager.getLogger(IdpSSOServlet.class); -// -// public IdpSSOServlet() { -// super(); -// } -// -// /** -// * The below doGet is called from the SSOFilter via the samlLogin/index.html page. -// * Once called, it gets all the required openAM params from the SSOUtil class and -// * does a redirect to the IDP. -// */ -// protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { -// logger.info("Starting IDP initiated SSO."); -// SSOUtil util = SSOUtil.getInstance(); -// util.setSSODeployURI((request).getRequestURI()); -// util.configureSSO(request, response); -// Map map = util.getSSOMap(); -// String idpBaseUrl = map.get("idpBaseUrl"); -// String idpMetaAlias = map.get("idpMetaAlias"); -// String spEntityID = map.get("spEntityID"); -// String idpRequest = new StringBuilder(idpBaseUrl). -// append("/idpssoinit?NameIDFormat=urn:oasis:names:tc:SAML:2.0:nameid-format:transient&metaAlias="). -// append(idpMetaAlias). -// append("&spEntityID="). -// append(spEntityID). -// append("&binding=urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"). -// toString(); -// logger.info("Redirect request created and redirecting to IDP now. IDPRequest - " + idpRequest); -// response.sendRedirect(idpRequest); -// } -// -//} +package prerna.semoss.web.services.saml; + +import java.io.IOException; +import java.util.Map; + +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import prerna.web.conf.util.SSOUtil; + +/** + * Servlet implementation class for IDP Initiated SAML + */ +@WebServlet("/IdpSSOServlet") +public class IdpSSOServlet extends HttpServlet { + + private static final long serialVersionUID = 1L; + private static final Logger logger = LogManager.getLogger(IdpSSOServlet.class); + + public IdpSSOServlet() { + super(); + } + + /** + * The below doGet is called from the SSOFilter via the samlLogin/index.html page. + * Once called, it gets all the required openAM params from the SSOUtil class and + * does a redirect to the IDP. + */ + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + logger.info("Starting IDP initiated SSO."); + SSOUtil util = SSOUtil.getInstance(); + util.setSSODeployURI((request).getRequestURI()); + util.configureSSO(request, response); + Map map = util.getSSOMap(); + String idpBaseUrl = map.get("idpBaseUrl"); + String idpMetaAlias = map.get("idpMetaAlias"); + String spEntityID = map.get("spEntityID"); + String idpRequest = new StringBuilder(idpBaseUrl). + append("/idpssoinit?NameIDFormat=urn:oasis:names:tc:SAML:2.0:nameid-format:transient&metaAlias="). + append(idpMetaAlias). + append("&spEntityID="). + append(spEntityID). + append("&binding=urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"). + toString(); + logger.info("Redirect request created and redirecting to IDP now. IDPRequest - " + idpRequest); + response.sendRedirect(idpRequest); + } + +} diff --git a/src/prerna/semoss/web/services/saml/SPSSOServlet.java b/src/prerna/semoss/web/services/saml/SPSSOServlet.java index 6f9d6ca94..6610927e3 100644 --- a/src/prerna/semoss/web/services/saml/SPSSOServlet.java +++ b/src/prerna/semoss/web/services/saml/SPSSOServlet.java @@ -1,174 +1,174 @@ -//package prerna.semoss.web.services.saml; -// -//import java.io.IOException; -//import java.util.ArrayList; -//import java.util.List; -//import java.util.Map; -// -//import javax.servlet.ServletException; -//import javax.servlet.annotation.WebServlet; -//import javax.servlet.http.HttpServlet; -//import javax.servlet.http.HttpServletRequest; -//import javax.servlet.http.HttpServletResponse; -// -//import org.forgerock.guice.core.InjectorHolder; -//import org.forgerock.openam.audit.AuditEventFactory; -//import org.forgerock.openam.audit.AuditEventPublisher; -//import org.forgerock.openam.saml2.audit.SAML2Auditor; -// -//import com.sun.identity.saml.common.SAMLUtils; -//import com.sun.identity.saml2.common.SAML2Constants; -//import com.sun.identity.saml2.common.SAML2Exception; -//import com.sun.identity.saml2.common.SAML2Utils; -//import com.sun.identity.saml2.meta.SAML2MetaManager; -//import com.sun.identity.saml2.profile.SPCache; -//import com.sun.identity.saml2.profile.SPSSOFederate; -// -//import prerna.web.conf.util.SSOUtil; -// -///** -// * Servlet implementation class for SP Initiated SAML -// */ -//@WebServlet("/SPSSOServlet") -//public class SPSSOServlet extends HttpServlet { -// private static final long serialVersionUID = 1L; -// -// public SPSSOServlet() { -// super(); -// } -// -// /** -// * The below doGet is called from the SSOFilter via the samlLogin/index.html page. -// * Once called, it gets all the required openAM params from the SSOUtil class and -// * does a call to the IDP with the SAML assertions. -// */ -// protected void doGet(HttpServletRequest request, HttpServletResponse response) -// throws ServletException, IOException { -// SSOUtil util = SSOUtil.getInstance(); -// if (!util.isConfigured()) { -// util.setSSODeployURI((request).getRequestURI()); -// util.configureSSO(request, response); -// } -// initiateSSO(request, response); -// } -// -// public void initiateSSO(HttpServletRequest request, HttpServletResponse response) { -// AuditEventPublisher aep = InjectorHolder.getInstance(AuditEventPublisher.class); -// AuditEventFactory aef = InjectorHolder.getInstance(AuditEventFactory.class); -// SAML2Auditor saml2Auditor = new SAML2Auditor(aep, aef, request); -// -// saml2Auditor.setMethod("fedletSSOInit"); -// saml2Auditor.setSessionTrackingId(request.getSession().getId()); -// saml2Auditor.auditAccessAttempt(); -// -// // Retreive the Request Query Parameters -// // metaAlias and idpEntiyID are the required query parameters -// // metaAlias - Service Provider Entity Id -// // idpEntityID - Identity Provider Identifier -// // Query parameters supported will be documented. -// String idpEntityID = null; -// String metaAlias = null; -// Map paramsMap = null; -// try { -// String reqID = request.getParameter("requestID"); -// if (reqID != null) { -// // get the preferred idp -// idpEntityID = SAML2Utils.getPreferredIDP(request); -// paramsMap = (Map) SPCache.reqParamHash.get(reqID); -// metaAlias = (String) paramsMap.get("metaAlias"); -// SPCache.reqParamHash.remove(reqID); -// } else { -// // this is an original request check -// // get the metaAlias ,idpEntityID -// // if idpEntityID is null redirect to IDP Discovery -// // Service to retrieve. -// metaAlias = request.getParameter("metaAlias"); -// if ((metaAlias == null) || (metaAlias.length() == 0)) { -// SAML2MetaManager manager = new SAML2MetaManager(); -// List spMetaAliases = manager.getAllHostedServiceProviderMetaAliases("/"); -// if ((spMetaAliases != null) && !spMetaAliases.isEmpty()) { -// // get first one -// metaAlias = (String) spMetaAliases.get(0); -// } -// if ((metaAlias == null) || (metaAlias.length() == 0)) { -// saml2Auditor.auditAccessFailure(String.valueOf(HttpServletResponse.SC_BAD_REQUEST), -// SAML2Utils.bundle.getString("nullSPEntityID")); -// SAMLUtils.sendError(request, response, HttpServletResponse.SC_BAD_REQUEST, "nullSPEntityID", -// SAML2Utils.bundle.getString("nullSPEntityID")); -// -// return; -// } -// } -// -// idpEntityID = request.getParameter("idpEntityID"); -// paramsMap = SAML2Utils.getParamsMap(request); -// // always use transient -// List list = new ArrayList(); -// list.add(SAML2Constants.NAMEID_TRANSIENT_FORMAT); -// paramsMap.put(SAML2Constants.NAMEID_POLICY_FORMAT, list); -// if (paramsMap.get(SAML2Constants.BINDING) == null) { -// // use POST binding -// list = new ArrayList(); -// list.add(SAML2Constants.HTTP_POST); -// paramsMap.put(SAML2Constants.BINDING, list); -// } -// -// if ((idpEntityID == null) || (idpEntityID.length() == 0)) { -// // get reader url -// String readerURL = SAML2Utils.getReaderURL(metaAlias); -// if (readerURL != null) { -// String rID = SAML2Utils.generateID(); -// String redirectURL = SAML2Utils.getRedirectURL(readerURL, rID, request); -// if (redirectURL != null) { -// paramsMap.put("metaAlias", metaAlias); -// SPCache.reqParamHash.put(rID, paramsMap); -// response.sendRedirect(redirectURL); -// return; -// } -// } -// } -// } -// -// if ((idpEntityID == null) || (idpEntityID.length() == 0)) { -// SAML2MetaManager manager = new SAML2MetaManager(); -// List idpEntities = manager.getAllRemoteIdentityProviderEntities("/"); -// if ((idpEntities == null) || idpEntities.isEmpty()) { -// saml2Auditor.auditAccessFailure(String.valueOf(HttpServletResponse.SC_BAD_REQUEST), -// SAML2Utils.bundle.getString("idpNotFound")); -// SAMLUtils.sendError(request, response, HttpServletResponse.SC_BAD_REQUEST, "idpNotFound", -// SAML2Utils.bundle.getString("idpNotFound")); -// return; -// } else if (idpEntities.size() == 1) { -// // only one IDP, just use it -// idpEntityID = (String) idpEntities.get(0); -// } else { -// // multiple IDP configured in fedlet -// saml2Auditor.auditAccessFailure(String.valueOf(HttpServletResponse.SC_BAD_REQUEST), -// SAML2Utils.bundle.getString("nullIDPEntityID")); -// SAMLUtils.sendError(request, response, HttpServletResponse.SC_BAD_REQUEST, "nullIDPEntityID", -// SAML2Utils.bundle.getString("nullIDPEntityID")); -// return; -// } -// } -// SPSSOFederate.initiateAuthnRequest(request, response, metaAlias, idpEntityID, paramsMap, saml2Auditor); -// saml2Auditor.auditAccessSuccess(); -// System.out.println("IDP call initiated successfully. Waiting for IDP callback."); -// } catch (SAML2Exception sse) { -// SAML2Utils.debug.error("Error sending AuthnRequest ", sse); -// saml2Auditor.auditAccessFailure(String.valueOf(HttpServletResponse.SC_BAD_REQUEST), -// SAML2Utils.bundle.getString("requestProcessingError")); -// SAMLUtils.sendError(request, response, HttpServletResponse.SC_BAD_REQUEST, "requestProcessingError", -// SAML2Utils.bundle.getString("requestProcessingError") + " " + sse.getMessage()); -// return; -// } catch (Exception e) { -// SAML2Utils.debug.error("Error processing Request ", e); -// saml2Auditor.auditAccessFailure(String.valueOf(HttpServletResponse.SC_BAD_REQUEST), -// SAML2Utils.bundle.getString("requestProcessingError")); -// SAMLUtils.sendError(request, response, HttpServletResponse.SC_BAD_REQUEST, "requestProcessingError", -// SAML2Utils.bundle.getString("requestProcessingError") + " " + e.getMessage()); -// return; -// } -// -// } -// -//} +package prerna.semoss.web.services.saml; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.forgerock.guice.core.InjectorHolder; +import org.forgerock.openam.audit.AuditEventFactory; +import org.forgerock.openam.audit.AuditEventPublisher; +import org.forgerock.openam.saml2.audit.SAML2Auditor; + +import com.sun.identity.saml.common.SAMLUtils; +import com.sun.identity.saml2.common.SAML2Constants; +import com.sun.identity.saml2.common.SAML2Exception; +import com.sun.identity.saml2.common.SAML2Utils; +import com.sun.identity.saml2.meta.SAML2MetaManager; +import com.sun.identity.saml2.profile.SPCache; +import com.sun.identity.saml2.profile.SPSSOFederate; + +import prerna.web.conf.util.SSOUtil; + +/** + * Servlet implementation class for SP Initiated SAML + */ +@WebServlet("/SPSSOServlet") +public class SPSSOServlet extends HttpServlet { + private static final long serialVersionUID = 1L; + + public SPSSOServlet() { + super(); + } + + /** + * The below doGet is called from the SSOFilter via the samlLogin/index.html page. + * Once called, it gets all the required openAM params from the SSOUtil class and + * does a call to the IDP with the SAML assertions. + */ + protected void doGet(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + SSOUtil util = SSOUtil.getInstance(); + if (!util.isConfigured()) { + util.setSSODeployURI((request).getRequestURI()); + util.configureSSO(request, response); + } + initiateSSO(request, response); + } + + public void initiateSSO(HttpServletRequest request, HttpServletResponse response) { + AuditEventPublisher aep = InjectorHolder.getInstance(AuditEventPublisher.class); + AuditEventFactory aef = InjectorHolder.getInstance(AuditEventFactory.class); + SAML2Auditor saml2Auditor = new SAML2Auditor(aep, aef, request); + + saml2Auditor.setMethod("fedletSSOInit"); + saml2Auditor.setSessionTrackingId(request.getSession().getId()); + saml2Auditor.auditAccessAttempt(); + + // Retreive the Request Query Parameters + // metaAlias and idpEntiyID are the required query parameters + // metaAlias - Service Provider Entity Id + // idpEntityID - Identity Provider Identifier + // Query parameters supported will be documented. + String idpEntityID = null; + String metaAlias = null; + Map paramsMap = null; + try { + String reqID = request.getParameter("requestID"); + if (reqID != null) { + // get the preferred idp + idpEntityID = SAML2Utils.getPreferredIDP(request); + paramsMap = (Map) SPCache.reqParamHash.get(reqID); + metaAlias = (String) paramsMap.get("metaAlias"); + SPCache.reqParamHash.remove(reqID); + } else { + // this is an original request check + // get the metaAlias ,idpEntityID + // if idpEntityID is null redirect to IDP Discovery + // Service to retrieve. + metaAlias = request.getParameter("metaAlias"); + if ((metaAlias == null) || (metaAlias.length() == 0)) { + SAML2MetaManager manager = new SAML2MetaManager(); + List spMetaAliases = manager.getAllHostedServiceProviderMetaAliases("/"); + if ((spMetaAliases != null) && !spMetaAliases.isEmpty()) { + // get first one + metaAlias = (String) spMetaAliases.get(0); + } + if ((metaAlias == null) || (metaAlias.length() == 0)) { + saml2Auditor.auditAccessFailure(String.valueOf(HttpServletResponse.SC_BAD_REQUEST), + SAML2Utils.bundle.getString("nullSPEntityID")); + SAMLUtils.sendError(request, response, HttpServletResponse.SC_BAD_REQUEST, "nullSPEntityID", + SAML2Utils.bundle.getString("nullSPEntityID")); + + return; + } + } + + idpEntityID = request.getParameter("idpEntityID"); + paramsMap = SAML2Utils.getParamsMap(request); + // always use transient + List list = new ArrayList(); + list.add(SAML2Constants.NAMEID_TRANSIENT_FORMAT); + paramsMap.put(SAML2Constants.NAMEID_POLICY_FORMAT, list); + if (paramsMap.get(SAML2Constants.BINDING) == null) { + // use POST binding + list = new ArrayList(); + list.add(SAML2Constants.HTTP_POST); + paramsMap.put(SAML2Constants.BINDING, list); + } + + if ((idpEntityID == null) || (idpEntityID.length() == 0)) { + // get reader url + String readerURL = SAML2Utils.getReaderURL(metaAlias); + if (readerURL != null) { + String rID = SAML2Utils.generateID(); + String redirectURL = SAML2Utils.getRedirectURL(readerURL, rID, request); + if (redirectURL != null) { + paramsMap.put("metaAlias", metaAlias); + SPCache.reqParamHash.put(rID, paramsMap); + response.sendRedirect(redirectURL); + return; + } + } + } + } + + if ((idpEntityID == null) || (idpEntityID.length() == 0)) { + SAML2MetaManager manager = new SAML2MetaManager(); + List idpEntities = manager.getAllRemoteIdentityProviderEntities("/"); + if ((idpEntities == null) || idpEntities.isEmpty()) { + saml2Auditor.auditAccessFailure(String.valueOf(HttpServletResponse.SC_BAD_REQUEST), + SAML2Utils.bundle.getString("idpNotFound")); + SAMLUtils.sendError(request, response, HttpServletResponse.SC_BAD_REQUEST, "idpNotFound", + SAML2Utils.bundle.getString("idpNotFound")); + return; + } else if (idpEntities.size() == 1) { + // only one IDP, just use it + idpEntityID = (String) idpEntities.get(0); + } else { + // multiple IDP configured in fedlet + saml2Auditor.auditAccessFailure(String.valueOf(HttpServletResponse.SC_BAD_REQUEST), + SAML2Utils.bundle.getString("nullIDPEntityID")); + SAMLUtils.sendError(request, response, HttpServletResponse.SC_BAD_REQUEST, "nullIDPEntityID", + SAML2Utils.bundle.getString("nullIDPEntityID")); + return; + } + } + SPSSOFederate.initiateAuthnRequest(request, response, metaAlias, idpEntityID, paramsMap, saml2Auditor); + saml2Auditor.auditAccessSuccess(); + System.out.println("IDP call initiated successfully. Waiting for IDP callback."); + } catch (SAML2Exception sse) { + SAML2Utils.debug.error("Error sending AuthnRequest ", sse); + saml2Auditor.auditAccessFailure(String.valueOf(HttpServletResponse.SC_BAD_REQUEST), + SAML2Utils.bundle.getString("requestProcessingError")); + SAMLUtils.sendError(request, response, HttpServletResponse.SC_BAD_REQUEST, "requestProcessingError", + SAML2Utils.bundle.getString("requestProcessingError") + " " + sse.getMessage()); + return; + } catch (Exception e) { + SAML2Utils.debug.error("Error processing Request ", e); + saml2Auditor.auditAccessFailure(String.valueOf(HttpServletResponse.SC_BAD_REQUEST), + SAML2Utils.bundle.getString("requestProcessingError")); + SAMLUtils.sendError(request, response, HttpServletResponse.SC_BAD_REQUEST, "requestProcessingError", + SAML2Utils.bundle.getString("requestProcessingError") + " " + e.getMessage()); + return; + } + + } + +} diff --git a/src/prerna/semoss/web/services/saml/SamlVerifierServlet.java b/src/prerna/semoss/web/services/saml/SamlVerifierServlet.java index 7dc1976ec..7f8198809 100644 --- a/src/prerna/semoss/web/services/saml/SamlVerifierServlet.java +++ b/src/prerna/semoss/web/services/saml/SamlVerifierServlet.java @@ -1,155 +1,155 @@ -//package prerna.semoss.web.services.saml; -// -//import java.io.BufferedWriter; -//import java.io.File; -//import java.io.FileWriter; -//import java.io.IOException; -//import java.io.PrintWriter; -//import java.util.List; -//import java.util.Map; -// -//import javax.servlet.ServletException; -//import javax.servlet.annotation.WebServlet; -//import javax.servlet.http.HttpServlet; -//import javax.servlet.http.HttpServletRequest; -//import javax.servlet.http.HttpServletResponse; -//import javax.servlet.http.HttpSession; -// -//import org.apache.commons.lang.StringUtils; -//import org.apache.logging.log4j.LogManager; -//import org.apache.logging.log4j.Logger; -//import org.owasp.encoder.Encode; -// -//import com.sun.identity.plugin.session.SessionException; -//import com.sun.identity.saml.common.SAMLUtils; -//import com.sun.identity.saml2.assertion.Assertion; -//import com.sun.identity.saml2.assertion.Attribute; -//import com.sun.identity.saml2.assertion.AttributeStatement; -//import com.sun.identity.saml2.assertion.NameID; -//import com.sun.identity.saml2.assertion.Subject; -//import com.sun.identity.saml2.common.SAML2Constants; -//import com.sun.identity.saml2.common.SAML2Exception; -//import com.sun.identity.saml2.profile.SPACSUtils; -//import com.sun.identity.saml2.protocol.Response; -// -//import prerna.auth.AccessToken; -//import prerna.auth.AuthProvider; -//import prerna.auth.User; -//import prerna.auth.utils.SecurityUpdateUtils; -//import prerna.util.Constants; -//import prerna.util.DIHelper; -//import prerna.web.conf.AdminStartupFilter; -//import prerna.web.conf.util.SSOUtil; -// -//@WebServlet("/saml/config/fedletapplication") -//public class SamlVerifierServlet extends HttpServlet { -// -// private static final long serialVersionUID = -3853767230988751741L; -// private static final Logger logger = LogManager.getLogger(SamlVerifierServlet.class); -// -// public SamlVerifierServlet() { -// super(); -// } -// -// protected void doPost(HttpServletRequest request, HttpServletResponse response) -// throws ServletException, IOException { -// logger.info("Starting saml verification doPost."); -// verifySamlOutput(request, response); -// logger.info("Ending saml verification doPost."); -// } -// -// public void verifySamlOutput(HttpServletRequest request, HttpServletResponse response) -// throws ServletException, IOException { -// -// logger.info("Connected to IDP. Starting validation of the assertions and other details."); -// // We define a map which will carry all the output from the saml verifications. -// Map map; -// -// // We need to pass a writer to the SAMl API to write Federation related -// // logs. This location is specified in the RDF.props file. Below is a -// // sample file path that we actually need to give. Make sure the Federation -// // file is there inside the debug folder. -// // "C:\\workspace\\Semoss_Dev\\saml\\mesoc\\conf\\debug\\Federation" -// String federationLogPath = ((String) DIHelper.getInstance().getCoreProp().get("SAML_FEDERATION_LOG_PATH")).trim(); -// BufferedWriter out = new BufferedWriter( -// new FileWriter(new File(federationLogPath))); -// -// try { -// // invoke the SAML processing logic. this will do all the -// // necessary processing conforming to SAMLv2 specifications, -// // such as XML signature validation, Audience and Recipient -// // validation etc. -// map = SPACSUtils.processResponseForFedlet(request, response, new PrintWriter(out, true)); -// -// // Check for relay URL in case IDP needs to redirect to specific page in the APP. -// String relayUrl = (String) map.get(SAML2Constants.RELAY_STATE); -// if ((relayUrl != null) && (relayUrl.length() != 0)) { -// // something special for validation to send redirect -// int stringPos = relayUrl.indexOf("sendRedirectForValidationNow=true"); -// if (stringPos != -1) { -// response.sendRedirect(relayUrl); -// } -// } -// -// // Get all the details from the SAML verification. -// // We just use the assertions, but we keep the code -// // below in case the other details might get used in -// // the near/distant future. -// Response samlResp = (Response) map.get(SAML2Constants.RESPONSE); -// Assertion assertion = (Assertion) map.get(SAML2Constants.ASSERTION); -// Subject subject = (Subject) map.get(SAML2Constants.SUBJECT); -// String entityID = (String) map.get(SAML2Constants.IDPENTITYID); -// String spEntityID = (String) map.get(SAML2Constants.SPENTITYID); -// NameID nameId = (NameID) map.get(SAML2Constants.NAMEID); -// String value = nameId.getValue(); -// String format = nameId.getFormat(); -// -// List attrlist = assertion.getAttributeStatements(); -// String userId = null; -// for (AttributeStatement stmt : attrlist) { -// List attributeList = stmt.getAttribute(); -// for (Attribute attr : attributeList) { -// if (attr.getName().equalsIgnoreCase("mail")) { -// logger.debug(" Attrubute name - %s, Attribute value - %s\n", attr.getName(), -// attr.getAttributeValue()); -// String valXml = (String) attr.getAttributeValue().get(0); -// userId = StringUtils.substringBetween(valXml, ">", "<"); -// } -// } -// } -// -// logger.info("Checking if user id is present in the SAML..."); -// -// if (userId == null || userId.isEmpty()) { -// throw new IllegalArgumentException("Did not receive valid userID from IDP. " -// + "Possible cause - user does not have access to IDP and you need to provide access to the user on the IDP side."); -// } -// -// logger.info("User id is good. Creating User/Token and setting it to session."); -// HttpSession session = request.getSession(true); -// AccessToken token = null; -// User user = new User(); -// token = new AccessToken(); -// token.setProvider(AuthProvider.SAML); -// token.setUsername(userId); -// user.setAccessToken(token); -// SecurityUpdateUtils.addOAuthUser(token); -// session.setAttribute(Constants.SESSION_USER, user); -// -// logger.info("Session is created and user all set to get in. Hold on, redirecting... "); -// if (session != null && session.getAttribute(SSOUtil.SAML_REDIRECT_KEY) != null) { -// String originalRedirect = session.getAttribute(SSOUtil.SAML_REDIRECT_KEY) + ""; -// String encodedRedirectUrl = Encode.forHtml(originalRedirect); -// AdminStartupFilter.setSuccessfulRedirectUrl(encodedRedirectUrl); -// response.setHeader("redirect", encodedRedirectUrl); -// response.sendRedirect(encodedRedirectUrl); -// } -// -// } catch (SAML2Exception | IOException | SessionException | ServletException sme) { -// SAMLUtils.sendError(request, response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, -// "failedToProcessSSOResponse", sme.getMessage()); -// } -// -// } -// -//} +package prerna.semoss.web.services.saml; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.List; +import java.util.Map; + +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.apache.commons.lang.StringUtils; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.owasp.encoder.Encode; + +import com.sun.identity.plugin.session.SessionException; +import com.sun.identity.saml.common.SAMLUtils; +import com.sun.identity.saml2.assertion.Assertion; +import com.sun.identity.saml2.assertion.Attribute; +import com.sun.identity.saml2.assertion.AttributeStatement; +import com.sun.identity.saml2.assertion.NameID; +import com.sun.identity.saml2.assertion.Subject; +import com.sun.identity.saml2.common.SAML2Constants; +import com.sun.identity.saml2.common.SAML2Exception; +import com.sun.identity.saml2.profile.SPACSUtils; +import com.sun.identity.saml2.protocol.Response; + +import prerna.auth.AccessToken; +import prerna.auth.AuthProvider; +import prerna.auth.User; +import prerna.auth.utils.SecurityUpdateUtils; +import prerna.util.Constants; +import prerna.util.DIHelper; +import prerna.web.conf.AdminStartupFilter; +import prerna.web.conf.util.SSOUtil; + +@WebServlet("/saml/config/fedletapplication") +public class SamlVerifierServlet extends HttpServlet { + + private static final long serialVersionUID = -3853767230988751741L; + private static final Logger logger = LogManager.getLogger(SamlVerifierServlet.class); + + public SamlVerifierServlet() { + super(); + } + + protected void doPost(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + logger.info("Starting saml verification doPost."); + verifySamlOutput(request, response); + logger.info("Ending saml verification doPost."); + } + + public void verifySamlOutput(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + + logger.info("Connected to IDP. Starting validation of the assertions and other details."); + // We define a map which will carry all the output from the saml verifications. + Map map; + + // We need to pass a writer to the SAMl API to write Federation related + // logs. This location is specified in the RDF.props file. Below is a + // sample file path that we actually need to give. Make sure the Federation + // file is there inside the debug folder. + // "C:\\workspace\\Semoss_Dev\\saml\\mesoc\\conf\\debug\\Federation" + String federationLogPath = ((String) DIHelper.getInstance().getCoreProp().get("SAML_FEDERATION_LOG_PATH")).trim(); + BufferedWriter out = new BufferedWriter( + new FileWriter(new File(federationLogPath))); + + try { + // invoke the SAML processing logic. this will do all the + // necessary processing conforming to SAMLv2 specifications, + // such as XML signature validation, Audience and Recipient + // validation etc. + map = SPACSUtils.processResponseForFedlet(request, response, new PrintWriter(out, true)); + + // Check for relay URL in case IDP needs to redirect to specific page in the APP. + String relayUrl = (String) map.get(SAML2Constants.RELAY_STATE); + if ((relayUrl != null) && (relayUrl.length() != 0)) { + // something special for validation to send redirect + int stringPos = relayUrl.indexOf("sendRedirectForValidationNow=true"); + if (stringPos != -1) { + response.sendRedirect(relayUrl); + } + } + + // Get all the details from the SAML verification. + // We just use the assertions, but we keep the code + // below in case the other details might get used in + // the near/distant future. + Response samlResp = (Response) map.get(SAML2Constants.RESPONSE); + Assertion assertion = (Assertion) map.get(SAML2Constants.ASSERTION); + Subject subject = (Subject) map.get(SAML2Constants.SUBJECT); + String entityID = (String) map.get(SAML2Constants.IDPENTITYID); + String spEntityID = (String) map.get(SAML2Constants.SPENTITYID); + NameID nameId = (NameID) map.get(SAML2Constants.NAMEID); + String value = nameId.getValue(); + String format = nameId.getFormat(); + + List attrlist = assertion.getAttributeStatements(); + String userId = null; + for (AttributeStatement stmt : attrlist) { + List attributeList = stmt.getAttribute(); + for (Attribute attr : attributeList) { + if (attr.getName().equalsIgnoreCase("mail")) { + logger.debug(" Attrubute name - %s, Attribute value - %s\n", attr.getName(), + attr.getAttributeValue()); + String valXml = (String) attr.getAttributeValue().get(0); + userId = StringUtils.substringBetween(valXml, ">", "<"); + } + } + } + + logger.info("Checking if user id is present in the SAML..."); + + if (userId == null || userId.isEmpty()) { + throw new IllegalArgumentException("Did not receive valid userID from IDP. " + + "Possible cause - user does not have access to IDP and you need to provide access to the user on the IDP side."); + } + + logger.info("User id is good. Creating User/Token and setting it to session."); + HttpSession session = request.getSession(true); + AccessToken token = null; + User user = new User(); + token = new AccessToken(); + token.setProvider(AuthProvider.SAML); + token.setUsername(userId); + user.setAccessToken(token); + SecurityUpdateUtils.addOAuthUser(token); + session.setAttribute(Constants.SESSION_USER, user); + + logger.info("Session is created and user all set to get in. Hold on, redirecting... "); + if (session != null && session.getAttribute(SSOUtil.SAML_REDIRECT_KEY) != null) { + String originalRedirect = session.getAttribute(SSOUtil.SAML_REDIRECT_KEY) + ""; + String encodedRedirectUrl = Encode.forHtml(originalRedirect); + AdminStartupFilter.setSuccessfulRedirectUrl(encodedRedirectUrl); + response.setHeader("redirect", encodedRedirectUrl); + response.sendRedirect(encodedRedirectUrl); + } + + } catch (SAML2Exception | IOException | SessionException | ServletException sme) { + SAMLUtils.sendError(request, response, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, + "failedToProcessSSOResponse", sme.getMessage()); + } + + } + +} diff --git a/src/prerna/web/conf/util/SSOUtil.java b/src/prerna/web/conf/util/SSOUtil.java index 7b096857c..dd7530c10 100644 --- a/src/prerna/web/conf/util/SSOUtil.java +++ b/src/prerna/web/conf/util/SSOUtil.java @@ -1,291 +1,289 @@ -//package prerna.web.conf.util; -// -//import java.io.File; -//import java.io.FileNotFoundException; -//import java.io.IOException; -//import java.io.InputStream; -//import java.util.ArrayList; -//import java.util.HashMap; -//import java.util.Iterator; -//import java.util.List; -//import java.util.Map; -// -//import javax.servlet.ServletException; -//import javax.servlet.http.HttpServletRequest; -//import javax.servlet.http.HttpServletResponse; -// -//import org.apache.logging.log4j.LogManager; -//import org.apache.logging.log4j.Logger; -// -//import com.sun.identity.saml2.common.SAML2Utils; -//import com.sun.identity.saml2.jaxb.metadata.AssertionConsumerServiceElement; -//import com.sun.identity.saml2.jaxb.metadata.IDPSSODescriptorElement; -//import com.sun.identity.saml2.jaxb.metadata.SPSSODescriptorElement; -//import com.sun.identity.saml2.jaxb.metadata.SingleSignOnServiceElement; -//import com.sun.identity.saml2.meta.SAML2MetaException; -//import com.sun.identity.saml2.meta.SAML2MetaManager; -// -//import prerna.util.DIHelper; -// -///** -// * -// * This util class is where we do all the configuration. -// * The entire SAML configuration is created here. The -// * implementation is very much specific to OpenAM. -// * -// */ -// -//public class SSOUtil { -// -// private static final Logger logger = LogManager.getLogger(FileAppender.class); -// private static String fedletHomeDir = ""; -// private static String deployuri = ""; -// private static final Map ssoMap = new HashMap(); -// private static final String HTTP_POST_BINDING = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"; -// private static boolean IS_CONFIGURED = false; -// public boolean is_authenticated = false; -// private static SSOUtil _instance; -// public static String SAML_REDIRECT_KEY = "SAML_REDIRECT_KEY"; -// -// static { -// _instance = new SSOUtil(); -// } -// -// -// private SSOUtil() { -// -// } -// -// /** -// * This method sets up the SAML home directory and other env variables -// * needed for the handshake to happen correctly between the SP and the -// * IDP. -// */ -// -// private void setFedletHomeDir() { -// logger.info("SSO directory setup starting"); -// -// // Nice to have these setup in the env. -// System.setProperty("com.iplanet.am.cookie.name", "iPlanetDirectoryPro"); -// System.setProperty("com.sun.identity.federation.fedCookieName", "fedCookie"); -// -// // this is where we set the SAML home dir by getting the loc from RDF props. -// String confLocation = ((String) DIHelper.getInstance().getCoreProp().get("SAML_PROP_LOC")).trim(); -// logger.info("Directory is set to.. " + confLocation); -// System.getProperties().setProperty("com.sun.identity.fedlet.home", confLocation); -// -// // Check if the deployuri is valid, otherwise throw exception. -// if(deployuri == null || deployuri.isEmpty()) -// throw new IllegalArgumentException("Deploy uri is null or empty. Cannot create SSO config."); -// int slashLoc = deployuri.indexOf("/", 1); -// if (slashLoc != -1) { -// deployuri = deployuri.substring(0, slashLoc); -// } -// -// // Set the saml config location -// fedletHomeDir = confLocation; -// if ((fedletHomeDir == null) || (fedletHomeDir.trim().length() == 0)) { -// if (System.getProperty("user.home").equals(File.separator)) { -// fedletHomeDir = File.separator + "fedlet"; -// } else { -// fedletHomeDir = System.getProperty("user.home") + File.separator + "fedlet"; -// } -// } -// logger.info("SSO directory setup complete."); -// } -// -// /* -// * Set all the properties related to SSO in this method. -// */ -// private void setSSOProperties(HttpServletRequest request, HttpServletResponse response) throws IOException { -// -// // First set the SAML home dir. -// setFedletHomeDir(); -// -// String spEntityID = null; -// String spMetaAlias = null; -// String idpEntityID = null; -// String idpMetaAlias = null; -// try { -// -// File dir = new File(fedletHomeDir); -// File file = new File(fedletHomeDir + File.separator + "FederationConfig.properties"); -// logger.info("Fedlet config being used " + file); -// if (!dir.exists() || !dir.isDirectory()) { -// throw new FileNotFoundException("Configuration directory does not exist."); -// } else if (!file.exists()) { -// throw new FileNotFoundException("Configuration files do not exist."); -// } else { -// SAML2MetaManager manager = new SAML2MetaManager(); -// List spEntities = manager.getAllHostedServiceProviderEntities("/"); -// if ((spEntities != null) && !spEntities.isEmpty()) { -// // get first one -// spEntityID = (String) spEntities.get(0); -// } -// -// List spMetaAliases = manager.getAllHostedServiceProviderMetaAliases("/"); -// if ((spMetaAliases != null) && !spMetaAliases.isEmpty()) { -// // get first one -// spMetaAlias = (String) spMetaAliases.get(0); -// } -// -// List trustedIDPs = new ArrayList(); -// idpEntityID = request.getParameter("idpEntityID"); -// if ((idpEntityID == null) || (idpEntityID.length() == 0)) { -// // find out all trusted IDPs -// List idpEntities = manager.getAllRemoteIdentityProviderEntities("/"); -// if ((idpEntities != null) && !idpEntities.isEmpty()) { -// int numOfIDP = idpEntities.size(); -// for (int j = 0; j < numOfIDP; j++) { -// String idpID = (String) idpEntities.get(j); -// if (manager.isTrustedProvider("/", spEntityID, idpID)) { -// trustedIDPs.add(idpID); -// } -// } -// } -// } -// -// // get the single IDP entity ID -// if (!trustedIDPs.isEmpty()) { -// idpEntityID = (String) trustedIDPs.get(0); -// } -// if ((spEntityID == null) || (idpEntityID == null)) { -// throw new SAML2MetaException( -// "Fedlet or remote Identity Provider metadata is not configured. Please configure SP/IDP first."); -// } else { -// // IDP base URL -// Map idpMap = getIDPBaseUrlAndMetaAlias(idpEntityID, deployuri); -// String idpBaseUrl = (String) idpMap.get("idpBaseUrl"); -// idpMetaAlias = (String) idpMap.get("idpMetaAlias"); -// String fedletBaseUrl = getFedletBaseUrl(spEntityID, deployuri); -// -// // Put everything in the SSOMap. -// ssoMap.put("idpBaseUrl", idpBaseUrl); -// ssoMap.put("fedletBaseUrl", fedletBaseUrl); -// ssoMap.put("idpMetaAlias", idpMetaAlias); -// ssoMap.put("spEntityID", spEntityID); -// ssoMap.put("metaAlias", spMetaAlias); -// ssoMap.put("idpEntityID", idpEntityID); -// ssoMap.put("binding", HTTP_POST_BINDING); -// -// logger.info("Fedlet (SP) Entity ID:" + spEntityID); -// logger.info("IDP Entity ID:" + idpEntityID); -// -// //populateSSOMap(spMetaAlias, idpEntityID, HTTP_POST_BINDING); -// } -// IS_CONFIGURED = true; -// } -// } catch (SAML2MetaException se) { -// se.printStackTrace(); -// response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, se.getMessage()); -// return; -// } -// } -// -// /** -// * This method gets the IDP related details and puts them into the map. -// * -// * @param idpEntityID -// * @param deployuri -// * @return -// */ -// private Map getIDPBaseUrlAndMetaAlias(String idpEntityID, String deployuri) { -// Map returnMap = new HashMap<>(); -// if (idpEntityID == null) { -// return returnMap; -// } -// try { -// // find out IDP meta alias -// SAML2MetaManager manager = new SAML2MetaManager(); -// IDPSSODescriptorElement idp = manager.getIDPSSODescriptor("/", idpEntityID); -// List ssoServiceList = idp.getSingleSignOnService(); -// if ((ssoServiceList != null) && (!ssoServiceList.isEmpty())) { -// Iterator i = ssoServiceList.iterator(); -// while (i.hasNext()) { -// SingleSignOnServiceElement sso = (SingleSignOnServiceElement) i.next(); -// if ((sso != null) && (sso.getBinding() != null)) { -// String ssoURL = sso.getLocation(); -// int loc = ssoURL.indexOf("/metaAlias/"); -// if (loc == -1) { -// continue; -// } else { -// returnMap.put("idpMetaAlias", ssoURL.substring(loc + 10)); -// String tmp = ssoURL.substring(0, loc); -// loc = tmp.lastIndexOf("/"); -// returnMap.put("idpBaseUrl", tmp.substring(0, loc)); -// break; -// } -// } -// } -// } -// } catch (Exception e) { -// SAML2Utils.debug.error("Couldn't get IDP base url:", e); -// } -// return returnMap; -// } -// -// /** -// * Helper method to read the config files and set the base urls saml style. -// * -// * @param spEntityID -// * @param deployuri -// * @return -// */ -// private String getFedletBaseUrl(String spEntityID, String deployuri) { -// if (spEntityID == null) { -// return null; -// } -// String fedletBaseUrl = null; -// try { -// SAML2MetaManager manager = new SAML2MetaManager(); -// SPSSODescriptorElement sp = manager.getSPSSODescriptor("/", spEntityID); -// List acsList = sp.getAssertionConsumerService(); -// if ((acsList != null) && (!acsList.isEmpty())) { -// Iterator j = acsList.iterator(); -// while (j.hasNext()) { -// AssertionConsumerServiceElement acs = (AssertionConsumerServiceElement) j.next(); -// if ((acs != null) && (acs.getBinding() != null)) { -// String acsURL = acs.getLocation(); -// int loc = acsURL.indexOf(deployuri + "/"); -// if (loc == -1) { -// continue; -// } else { -// fedletBaseUrl = acsURL.substring(0, loc + deployuri.length()); -// break; -// } -// } -// } -// } -// } catch (Exception e) { -// SAML2Utils.debug.error("Couldn't get fedlet base url:", e); -// } -// return fedletBaseUrl; -// } -// -// private void populateSSOMap(String spMetaAlias, String idpEntityID, String binding) { -// ssoMap.put("metaAlias", spMetaAlias); -// ssoMap.put("idpEntityID", idpEntityID); -// ssoMap.put("binding", binding); -// } -// -// public Map getSSOMap(){ -// return ssoMap; -// } -// -// public void setSSODeployURI(String uri) { -// deployuri = uri; -// } -// -// public void configureSSO(HttpServletRequest request, HttpServletResponse response) throws IOException { -// setSSOProperties(request, response); -// } -// -// public boolean isConfigured() { -// return IS_CONFIGURED; -// } -// -// public static SSOUtil getInstance() { -// return _instance; -// } -// -//} +package prerna.web.conf.util; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import com.sun.identity.saml2.common.SAML2Utils; +import com.sun.identity.saml2.jaxb.metadata.AssertionConsumerServiceElement; +import com.sun.identity.saml2.jaxb.metadata.IDPSSODescriptorElement; +import com.sun.identity.saml2.jaxb.metadata.SPSSODescriptorElement; +import com.sun.identity.saml2.jaxb.metadata.SingleSignOnServiceElement; +import com.sun.identity.saml2.meta.SAML2MetaException; +import com.sun.identity.saml2.meta.SAML2MetaManager; + +import prerna.util.DIHelper; + +/** + * + * This util class is where we do all the configuration. + * The entire SAML configuration is created here. The + * implementation is very much specific to OpenAM. + * + */ + +public class SSOUtil { + + private static final Logger logger = LogManager.getLogger(FileAppender.class); + private static String fedletHomeDir = ""; + private static String deployuri = ""; + private static final Map ssoMap = new HashMap(); + private static final String HTTP_POST_BINDING = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"; + private static boolean IS_CONFIGURED = false; + public boolean is_authenticated = false; + private static SSOUtil _instance; + public static String SAML_REDIRECT_KEY = "SAML_REDIRECT_KEY"; + + static { + _instance = new SSOUtil(); + } + + + private SSOUtil() { + + } + + /** + * This method sets up the SAML home directory and other env variables + * needed for the handshake to happen correctly between the SP and the + * IDP. + */ + + private void setFedletHomeDir() { + logger.info("SSO directory setup starting"); + + // Nice to have these setup in the env. + System.setProperty("com.iplanet.am.cookie.name", "iPlanetDirectoryPro"); + System.setProperty("com.sun.identity.federation.fedCookieName", "fedCookie"); + + // this is where we set the SAML home dir by getting the loc from RDF props. + String confLocation = ((String) DIHelper.getInstance().getCoreProp().get("SAML_PROP_LOC")).trim(); + logger.info("Directory is set to.. " + confLocation); + System.getProperties().setProperty("com.sun.identity.fedlet.home", confLocation); + + // Check if the deployuri is valid, otherwise throw exception. + if(deployuri == null || deployuri.isEmpty()) + throw new IllegalArgumentException("Deploy uri is null or empty. Cannot create SSO config."); + int slashLoc = deployuri.indexOf("/", 1); + if (slashLoc != -1) { + deployuri = deployuri.substring(0, slashLoc); + } + + // Set the saml config location + fedletHomeDir = confLocation; + if ((fedletHomeDir == null) || (fedletHomeDir.trim().length() == 0)) { + if (System.getProperty("user.home").equals(File.separator)) { + fedletHomeDir = File.separator + "fedlet"; + } else { + fedletHomeDir = System.getProperty("user.home") + File.separator + "fedlet"; + } + } + logger.info("SSO directory setup complete."); + } + + /* + * Set all the properties related to SSO in this method. + */ + private void setSSOProperties(HttpServletRequest request, HttpServletResponse response) throws IOException { + + // First set the SAML home dir. + setFedletHomeDir(); + + String spEntityID = null; + String spMetaAlias = null; + String idpEntityID = null; + String idpMetaAlias = null; + try { + + File dir = new File(fedletHomeDir); + File file = new File(fedletHomeDir + File.separator + "FederationConfig.properties"); + logger.info("Fedlet config being used " + file); + if (!dir.exists() || !dir.isDirectory()) { + throw new FileNotFoundException("Configuration directory does not exist."); + } else if (!file.exists()) { + throw new FileNotFoundException("Configuration files do not exist."); + } else { + SAML2MetaManager manager = new SAML2MetaManager(); + List spEntities = manager.getAllHostedServiceProviderEntities("/"); + if ((spEntities != null) && !spEntities.isEmpty()) { + // get first one + spEntityID = (String) spEntities.get(0); + } + + List spMetaAliases = manager.getAllHostedServiceProviderMetaAliases("/"); + if ((spMetaAliases != null) && !spMetaAliases.isEmpty()) { + // get first one + spMetaAlias = (String) spMetaAliases.get(0); + } + + List trustedIDPs = new ArrayList(); + idpEntityID = request.getParameter("idpEntityID"); + if ((idpEntityID == null) || (idpEntityID.length() == 0)) { + // find out all trusted IDPs + List idpEntities = manager.getAllRemoteIdentityProviderEntities("/"); + if ((idpEntities != null) && !idpEntities.isEmpty()) { + int numOfIDP = idpEntities.size(); + for (int j = 0; j < numOfIDP; j++) { + String idpID = (String) idpEntities.get(j); + if (manager.isTrustedProvider("/", spEntityID, idpID)) { + trustedIDPs.add(idpID); + } + } + } + } + + // get the single IDP entity ID + if (!trustedIDPs.isEmpty()) { + idpEntityID = (String) trustedIDPs.get(0); + } + if ((spEntityID == null) || (idpEntityID == null)) { + throw new SAML2MetaException( + "Fedlet or remote Identity Provider metadata is not configured. Please configure SP/IDP first."); + } else { + // IDP base URL + Map idpMap = getIDPBaseUrlAndMetaAlias(idpEntityID, deployuri); + String idpBaseUrl = (String) idpMap.get("idpBaseUrl"); + idpMetaAlias = (String) idpMap.get("idpMetaAlias"); + String fedletBaseUrl = getFedletBaseUrl(spEntityID, deployuri); + + // Put everything in the SSOMap. + ssoMap.put("idpBaseUrl", idpBaseUrl); + ssoMap.put("fedletBaseUrl", fedletBaseUrl); + ssoMap.put("idpMetaAlias", idpMetaAlias); + ssoMap.put("spEntityID", spEntityID); + ssoMap.put("metaAlias", spMetaAlias); + ssoMap.put("idpEntityID", idpEntityID); + ssoMap.put("binding", HTTP_POST_BINDING); + + logger.info("Fedlet (SP) Entity ID:" + spEntityID); + logger.info("IDP Entity ID:" + idpEntityID); + + //populateSSOMap(spMetaAlias, idpEntityID, HTTP_POST_BINDING); + } + IS_CONFIGURED = true; + } + } catch (SAML2MetaException se) { + se.printStackTrace(); + response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, se.getMessage()); + return; + } + } + + /** + * This method gets the IDP related details and puts them into the map. + * + * @param idpEntityID + * @param deployuri + * @return + */ + private Map getIDPBaseUrlAndMetaAlias(String idpEntityID, String deployuri) { + Map returnMap = new HashMap<>(); + if (idpEntityID == null) { + return returnMap; + } + try { + // find out IDP meta alias + SAML2MetaManager manager = new SAML2MetaManager(); + IDPSSODescriptorElement idp = manager.getIDPSSODescriptor("/", idpEntityID); + List ssoServiceList = idp.getSingleSignOnService(); + if ((ssoServiceList != null) && (!ssoServiceList.isEmpty())) { + Iterator i = ssoServiceList.iterator(); + while (i.hasNext()) { + SingleSignOnServiceElement sso = (SingleSignOnServiceElement) i.next(); + if ((sso != null) && (sso.getBinding() != null)) { + String ssoURL = sso.getLocation(); + int loc = ssoURL.indexOf("/metaAlias/"); + if (loc == -1) { + continue; + } else { + returnMap.put("idpMetaAlias", ssoURL.substring(loc + 10)); + String tmp = ssoURL.substring(0, loc); + loc = tmp.lastIndexOf("/"); + returnMap.put("idpBaseUrl", tmp.substring(0, loc)); + break; + } + } + } + } + } catch (Exception e) { + SAML2Utils.debug.error("Couldn't get IDP base url:", e); + } + return returnMap; + } + + /** + * Helper method to read the config files and set the base urls saml style. + * + * @param spEntityID + * @param deployuri + * @return + */ + private String getFedletBaseUrl(String spEntityID, String deployuri) { + if (spEntityID == null) { + return null; + } + String fedletBaseUrl = null; + try { + SAML2MetaManager manager = new SAML2MetaManager(); + SPSSODescriptorElement sp = manager.getSPSSODescriptor("/", spEntityID); + List acsList = sp.getAssertionConsumerService(); + if ((acsList != null) && (!acsList.isEmpty())) { + Iterator j = acsList.iterator(); + while (j.hasNext()) { + AssertionConsumerServiceElement acs = (AssertionConsumerServiceElement) j.next(); + if ((acs != null) && (acs.getBinding() != null)) { + String acsURL = acs.getLocation(); + int loc = acsURL.indexOf(deployuri + "/"); + if (loc == -1) { + continue; + } else { + fedletBaseUrl = acsURL.substring(0, loc + deployuri.length()); + break; + } + } + } + } + } catch (Exception e) { + SAML2Utils.debug.error("Couldn't get fedlet base url:", e); + } + return fedletBaseUrl; + } + + private void populateSSOMap(String spMetaAlias, String idpEntityID, String binding) { + ssoMap.put("metaAlias", spMetaAlias); + ssoMap.put("idpEntityID", idpEntityID); + ssoMap.put("binding", binding); + } + + public Map getSSOMap(){ + return ssoMap; + } + + public void setSSODeployURI(String uri) { + deployuri = uri; + } + + public void configureSSO(HttpServletRequest request, HttpServletResponse response) throws IOException { + setSSOProperties(request, response); + } + + public boolean isConfigured() { + return IS_CONFIGURED; + } + + public static SSOUtil getInstance() { + return _instance; + } + +} From 87bbff17f9f40a32ceae7d55c72290bb50271f62 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 14 Apr 2021 14:42:20 +0000 Subject: [PATCH 0776/1906] UPDATE ::: Adding classes for SAML openam configuration git-svn-id: svn://107.170.10.188:8080/Monolith/dev@43405 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 5415847ec3964e621661c4d0b17bb9798bae5636 --- WebContent/classes/ESAPI.properties | 452 ++++++++++++++++++ .../services/com.google.inject.Module | 16 + WebContent/classes/debugconfig.properties | 3 + WebContent/classes/debugfiles.properties | 79 +++ .../classes/fmConfigurationService.properties | 41 ++ .../fmConfigurationService_de.properties | 41 ++ .../fmConfigurationService_es.properties | 41 ++ .../fmConfigurationService_fr.properties | 41 ++ .../fmConfigurationService_ja.properties | 41 ++ .../fmConfigurationService_ko.properties | 40 ++ .../fmConfigurationService_zh.properties | 41 ++ .../fmConfigurationService_zh_TW.properties | 40 ++ 12 files changed, 876 insertions(+) create mode 100644 WebContent/classes/ESAPI.properties create mode 100644 WebContent/classes/META-INF/services/com.google.inject.Module create mode 100644 WebContent/classes/debugconfig.properties create mode 100644 WebContent/classes/debugfiles.properties create mode 100644 WebContent/classes/fmConfigurationService.properties create mode 100644 WebContent/classes/fmConfigurationService_de.properties create mode 100644 WebContent/classes/fmConfigurationService_es.properties create mode 100644 WebContent/classes/fmConfigurationService_fr.properties create mode 100644 WebContent/classes/fmConfigurationService_ja.properties create mode 100644 WebContent/classes/fmConfigurationService_ko.properties create mode 100644 WebContent/classes/fmConfigurationService_zh.properties create mode 100644 WebContent/classes/fmConfigurationService_zh_TW.properties diff --git a/WebContent/classes/ESAPI.properties b/WebContent/classes/ESAPI.properties new file mode 100644 index 000000000..397c1a063 --- /dev/null +++ b/WebContent/classes/ESAPI.properties @@ -0,0 +1,452 @@ +# +# OWASP Enterprise Security API (ESAPI) Properties file -- PRODUCTION Version +# +# This file is part of the Open Web Application Security Project (OWASP) +# Enterprise Security API (ESAPI) project. For details, please see +# http://www.owasp.org/index.php/ESAPI. +# +# Copyright (c) 2008,2009 - The OWASP Foundation +# +# DISCUSS: This may cause a major backwards compatibility issue, etc. but +# from a name space perspective, we probably should have prefaced +# all the property names with ESAPI or at least OWASP. Otherwise +# there could be problems is someone loads this properties file into +# the System properties. We could also put this file into the +# esapi.jar file (perhaps as a ResourceBundle) and then allow an external +# ESAPI properties be defined that would overwrite these defaults. +# That keeps the application's properties relatively simple as usually +# they will only want to override a few properties. If looks like we +# already support multiple override levels of this in the +# DefaultSecurityConfiguration class, but I'm suggesting placing the +# defaults in the esapi.jar itself. That way, if the jar is signed, +# we could detect if those properties had been tampered with. (The +# code to check the jar signatures is pretty simple... maybe 70-90 LOC, +# but off course there is an execution penalty (similar to the way +# that the separate sunjce.jar used to be when a class from it was +# first loaded). Thoughts? +############################################################################### +# +# WARNING: Operating system protection should be used to lock down the .esapi +# resources directory and all the files inside and all the directories all the +# way up to the root directory of the file system. Note that if you are using +# file-based implementations, that some files may need to be read-write as they +# get updated dynamically. +# +# Before using, be sure to update the MasterKey and MasterSalt as described below. +# N.B.: If you had stored data that you have previously encrypted with ESAPI 1.4, +# you *must* FIRST decrypt it using ESAPI 1.4 and then (if so desired) +# re-encrypt it with ESAPI 2.0. If you fail to do this, you will NOT be +# able to decrypt your data with ESAPI 2.0. +# +# YOU HAVE BEEN WARNED!!! More details are in the ESAPI 2.0 Release Notes. +# +#=========================================================================== +# ESAPI Configuration +# +# If true, then print all the ESAPI properties set here when they are loaded. +# If false, they are not printed. Useful to reduce output when running JUnit tests. +# If you need to troubleshoot a properties related problem, turning this on may help. +# This is 'false' in the src/test/resources/.esapi version. It is 'true' by +# default for reasons of backward compatibility with earlier ESAPI versions. +ESAPI.printProperties=true + +# ESAPI is designed to be easily extensible. You can use the reference implementation +# or implement your own providers to take advantage of your enterprise's security +# infrastructure. The functions in ESAPI are referenced using the ESAPI locator, like: +# +# String ciphertext = +# ESAPI.encryptor().encrypt("Secret message"); // Deprecated in 2.0 +# CipherText cipherText = +# ESAPI.encryptor().encrypt(new PlainText("Secret message")); // Preferred +# +# Below you can specify the classname for the provider that you wish to use in your +# application. The only requirement is that it implement the appropriate ESAPI interface. +# This allows you to switch security implementations in the future without rewriting the +# entire application. +# +# ExperimentalAccessController requires ESAPI-AccessControlPolicy.xml in .esapi directory +ESAPI.AccessControl=org.owasp.esapi.reference.DefaultAccessController +# FileBasedAuthenticator requires users.txt file in .esapi directory +ESAPI.Authenticator=org.owasp.esapi.reference.FileBasedAuthenticator +ESAPI.Encoder=org.owasp.esapi.reference.DefaultEncoder +ESAPI.Encryptor=org.owasp.esapi.reference.crypto.JavaEncryptor + +ESAPI.Executor=org.owasp.esapi.reference.DefaultExecutor +ESAPI.HTTPUtilities=org.owasp.esapi.reference.DefaultHTTPUtilities +ESAPI.IntrusionDetector=org.owasp.esapi.reference.DefaultIntrusionDetector +# Log4JFactory Requires log4j.xml or log4j.properties in classpath - http://www.laliluna.de/log4j-tutorial.html +ESAPI.Logger=org.owasp.esapi.reference.Log4JLogFactory +#ESAPI.Logger=org.owasp.esapi.reference.JavaLogFactory +ESAPI.Randomizer=org.owasp.esapi.reference.DefaultRandomizer +ESAPI.Validator=org.owasp.esapi.reference.DefaultValidator + +#=========================================================================== +# ESAPI Authenticator +# +Authenticator.AllowedLoginAttempts=3 +Authenticator.MaxOldPasswordHashes=13 +Authenticator.UsernameParameterName=username +Authenticator.PasswordParameterName=password +# RememberTokenDuration (in days) +Authenticator.RememberTokenDuration=14 +# Session Timeouts (in minutes) +Authenticator.IdleTimeoutDuration=20 +Authenticator.AbsoluteTimeoutDuration=120 + +#=========================================================================== +# ESAPI Encoder +# +# ESAPI canonicalizes input before validation to prevent bypassing filters with encoded attacks. +# Failure to canonicalize input is a very common mistake when implementing validation schemes. +# Canonicalization is automatic when using the ESAPI Validator, but you can also use the +# following code to canonicalize data. +# +# ESAPI.Encoder().canonicalize( "%22hello world"" ); +# +# Multiple encoding is when a single encoding format is applied multiple times. Allowing +# multiple encoding is strongly discouraged. +Encoder.AllowMultipleEncoding=false + +# Mixed encoding is when multiple different encoding formats are applied, or when +# multiple formats are nested. Allowing multiple encoding is strongly discouraged. +Encoder.AllowMixedEncoding=false + +# The default list of codecs to apply when canonicalizing untrusted data. The list should include the codecs +# for all downstream interpreters or decoders. For example, if the data is likely to end up in a URL, HTML, or +# inside JavaScript, then the list of codecs below is appropriate. The order of the list is not terribly important. +Encoder.DefaultCodecList=HTMLEntityCodec,PercentCodec,JavaScriptCodec + + +#=========================================================================== +# ESAPI Encryption +# +# The ESAPI Encryptor provides basic cryptographic functions with a simplified API. +# To get started, generate a new key using java -classpath esapi.jar org.owasp.esapi.reference.crypto.JavaEncryptor +# There is not currently any support for key rotation, so be careful when changing your key and salt as it +# will invalidate all signed, encrypted, and hashed data. +# +# WARNING: Not all combinations of algorithms and key lengths are supported. +# If you choose to use a key length greater than 128, you MUST download the +# unlimited strength policy files and install in the lib directory of your JRE/JDK. +# See http://java.sun.com/javase/downloads/index.jsp for more information. +# +# Backward compatibility with ESAPI Java 1.4 is supported by the two deprecated API +# methods, Encryptor.encrypt(String) and Encryptor.decrypt(String). However, whenever +# possible, these methods should be avoided as they use ECB cipher mode, which in almost +# all circumstances a poor choice because of it's weakness. CBC cipher mode is the default +# for the new Encryptor encrypt / decrypt methods for ESAPI Java 2.0. In general, you +# should only use this compatibility setting if you have persistent data encrypted with +# version 1.4 and even then, you should ONLY set this compatibility mode UNTIL +# you have decrypted all of your old encrypted data and then re-encrypted it with +# ESAPI 2.0 using CBC mode. If you have some reason to mix the deprecated 1.4 mode +# with the new 2.0 methods, make sure that you use the same cipher algorithm for both +# (256-bit AES was the default for 1.4; 128-bit is the default for 2.0; see below for +# more details.) Otherwise, you will have to use the new 2.0 encrypt / decrypt methods +# where you can specify a SecretKey. (Note that if you are using the 256-bit AES, +# that requires downloading the special jurisdiction policy files mentioned above.) +# +# ***** IMPORTANT: Do NOT forget to replace these with your own values! ***** +# To calculate these values, you can run: +# java -classpath esapi.jar org.owasp.esapi.reference.crypto.JavaEncryptor +# +Encryptor.MasterKey=tzfztf56ftv +Encryptor.MasterSalt=123456ztrewq + +# Provides the default JCE provider that ESAPI will "prefer" for its symmetric +# encryption and hashing. (That is it will look to this provider first, but it +# will defer to other providers if the requested algorithm is not implemented +# by this provider.) If left unset, ESAPI will just use your Java VM's current +# preferred JCE provider, which is generally set in the file +# "$JAVA_HOME/jre/lib/security/java.security". +# +# The main intent of this is to allow ESAPI symmetric encryption to be +# used with a FIPS 140-2 compliant crypto-module. For details, see the section +# "Using ESAPI Symmetric Encryption with FIPS 140-2 Cryptographic Modules" in +# the ESAPI 2.0 Symmetric Encryption User Guide, at: +# http://owasp-esapi-java.googlecode.com/svn/trunk/documentation/esapi4java-core-2.0-symmetric-crypto-user-guide.html +# However, this property also allows you to easily use an alternate JCE provider +# such as "Bouncy Castle" without having to make changes to "java.security". +# See Javadoc for SecurityProviderLoader for further details. If you wish to use +# a provider that is not known to SecurityProviderLoader, you may specify the +# fully-qualified class name of the JCE provider class that implements +# java.security.Provider. If the name contains a '.', this is interpreted as +# a fully-qualified class name that implements java.security.Provider. +# +# NOTE: Setting this property has the side-effect of changing it in your application +# as well, so if you are using JCE in your application directly rather than +# through ESAPI (you wouldn't do that, would you? ;-), it will change the +# preferred JCE provider there as well. +# +# Default: Keeps the JCE provider set to whatever JVM sets it to. +Encryptor.PreferredJCEProvider= + +# AES is the most widely used and strongest encryption algorithm. This +# should agree with your Encryptor.CipherTransformation property. +# By default, ESAPI Java 1.4 uses "PBEWithMD5AndDES" and which is +# very weak. It is essentially a password-based encryption key, hashed +# with MD5 around 1K times and then encrypted with the weak DES algorithm +# (56-bits) using ECB mode and an unspecified padding (it is +# JCE provider specific, but most likely "NoPadding"). However, 2.0 uses +# "AES/CBC/PKCSPadding". If you want to change these, change them here. +# Warning: This property does not control the default reference implementation for +# ESAPI 2.0 using JavaEncryptor. Also, this property will be dropped +# in the future. +# @deprecated +Encryptor.EncryptionAlgorithm=AES +# For ESAPI Java 2.0 - New encrypt / decrypt methods use this. +Encryptor.CipherTransformation=AES/CBC/PKCS5Padding + +# Applies to ESAPI 2.0 and later only! +# Comma-separated list of cipher modes that provide *BOTH* +# confidentiality *AND* message authenticity. (NIST refers to such cipher +# modes as "combined modes" so that's what we shall call them.) If any of these +# cipher modes are used then no MAC is calculated and stored +# in the CipherText upon encryption. Likewise, if one of these +# cipher modes is used with decryption, no attempt will be made +# to validate the MAC contained in the CipherText object regardless +# of whether it contains one or not. Since the expectation is that +# these cipher modes support support message authenticity already, +# injecting a MAC in the CipherText object would be at best redundant. +# +# Note that as of JDK 1.5, the SunJCE provider does not support *any* +# of these cipher modes. Of these listed, only GCM and CCM are currently +# NIST approved. YMMV for other JCE providers. E.g., Bouncy Castle supports +# GCM and CCM with "NoPadding" mode, but not with "PKCS5Padding" or other +# padding modes. +Encryptor.cipher_modes.combined_modes=GCM,CCM,IAPM,EAX,OCB,CWC + +# Applies to ESAPI 2.0 and later only! +# Additional cipher modes allowed for ESAPI 2.0 encryption. These +# cipher modes are in _addition_ to those specified by the property +# 'Encryptor.cipher_modes.combined_modes'. +# Note: We will add support for streaming modes like CFB & OFB once +# we add support for 'specified' to the property 'Encryptor.ChooseIVMethod' +# (probably in ESAPI 2.1). +# DISCUSS: Better name? +Encryptor.cipher_modes.additional_allowed=CBC + +# 128-bit is almost always sufficient and appears to be more resistant to +# related key attacks than is 256-bit AES. Use '_' to use default key size +# for cipher algorithms (where it makes sense because the algorithm supports +# a variable key size). Key length must agree to what's provided as the +# cipher transformation, otherwise this will be ignored after logging a +# warning. +# +# NOTE: This is what applies BOTH ESAPI 1.4 and 2.0. See warning above about mixing! +Encryptor.EncryptionKeyLength=128 + +# Because 2.0 uses CBC mode by default, it requires an initialization vector (IV). +# (All cipher modes except ECB require an IV.) There are two choices: we can either +# use a fixed IV known to both parties or allow ESAPI to choose a random IV. While +# the IV does not need to be hidden from adversaries, it is important that the +# adversary not be allowed to choose it. Also, random IVs are generally much more +# secure than fixed IVs. (In fact, it is essential that feed-back cipher modes +# such as CFB and OFB use a different IV for each encryption with a given key so +# in such cases, random IVs are much preferred. By default, ESAPI 2.0 uses random +# IVs. If you wish to use 'fixed' IVs, set 'Encryptor.ChooseIVMethod=fixed' and +# uncomment the Encryptor.fixedIV. +# +# Valid values: random|fixed|specified 'specified' not yet implemented; planned for 2.1 +Encryptor.ChooseIVMethod=random +# If you choose to use a fixed IV, then you must place a fixed IV here that +# is known to all others who are sharing your secret key. The format should +# be a hex string that is the same length as the cipher block size for the +# cipher algorithm that you are using. The following is an *example* for AES +# from an AES test vector for AES-128/CBC as described in: +# NIST Special Publication 800-38A (2001 Edition) +# "Recommendation for Block Cipher Modes of Operation". +# (Note that the block size for AES is 16 bytes == 128 bits.) +# +Encryptor.fixedIV=0x000102030405060708090a0b0c0d0e0f + +# Whether or not CipherText should use a message authentication code (MAC) with it. +# This prevents an adversary from altering the IV as well as allowing a more +# fool-proof way of determining the decryption failed because of an incorrect +# key being supplied. This refers to the "separate" MAC calculated and stored +# in CipherText, not part of any MAC that is calculated as a result of a +# "combined mode" cipher mode. +# +# If you are using ESAPI with a FIPS 140-2 cryptographic module, you *must* also +# set this property to false. +Encryptor.CipherText.useMAC=true + +# Whether or not the PlainText object may be overwritten and then marked +# eligible for garbage collection. If not set, this is still treated as 'true'. +Encryptor.PlainText.overwrite=true + +# Do not use DES except in a legacy situations. 56-bit is way too small key size. +#Encryptor.EncryptionKeyLength=56 +#Encryptor.EncryptionAlgorithm=DES + +# TripleDES is considered strong enough for most purposes. +# Note: There is also a 112-bit version of DESede. Using the 168-bit version +# requires downloading the special jurisdiction policy from Sun. +#Encryptor.EncryptionKeyLength=168 +#Encryptor.EncryptionAlgorithm=DESede + +Encryptor.HashAlgorithm=SHA-512 +Encryptor.HashIterations=1024 +Encryptor.DigitalSignatureAlgorithm=SHA1withDSA +Encryptor.DigitalSignatureKeyLength=1024 +Encryptor.RandomAlgorithm=SHA1PRNG +Encryptor.CharacterEncoding=UTF-8 + +# This is the Pseudo Random Function (PRF) that ESAPI's Key Derivation Function +# (KDF) normally uses. Note this is *only* the PRF used for ESAPI's KDF and +# *not* what is used for ESAPI's MAC. (Currently, HmacSHA1 is always used for +# the MAC, mostly to keep the overall size at a minimum.) +# +# Currently supported choices for JDK 1.5 and 1.6 are: +# HmacSHA1 (160 bits), HmacSHA256 (256 bits), HmacSHA384 (384 bits), and +# HmacSHA512 (512 bits). +# Note that HmacMD5 is *not* supported for the PRF used by the KDF even though +# the JDKs support it. See the ESAPI 2.0 Symmetric Encryption User Guide +# further details. +Encryptor.KDF.PRF=HmacSHA256 +#=========================================================================== +# ESAPI HttpUtilties +# +# The HttpUtilities provide basic protections to HTTP requests and responses. Primarily these methods +# protect against malicious data from attackers, such as unprintable characters, escaped characters, +# and other simple attacks. The HttpUtilities also provides utility methods for dealing with cookies, +# headers, and CSRF tokens. +# +# Default file upload location (remember to escape backslashes with \\) +HttpUtilities.UploadDir=C:\\ESAPI\\testUpload +HttpUtilities.UploadTempDir=C:\\temp +# Force flags on cookies, if you use HttpUtilities to set cookies +HttpUtilities.ForceHttpOnlySession=false +HttpUtilities.ForceSecureSession=false +HttpUtilities.ForceHttpOnlyCookies=true +HttpUtilities.ForceSecureCookies=true +# Maximum size of HTTP headers +HttpUtilities.MaxHeaderSize=4096 +# File upload configuration +HttpUtilities.ApprovedUploadExtensions=.zip,.pdf,.doc,.docx,.ppt,.pptx,.tar,.gz,.tgz,.rar,.war,.jar,.ear,.xls,.rtf,.properties,.java,.class,.txt,.xml,.jsp,.jsf,.exe,.dll +HttpUtilities.MaxUploadFileBytes=500000000 +# Using UTF-8 throughout your stack is highly recommended. That includes your database driver, +# container, and any other technologies you may be using. Failure to do this may expose you +# to Unicode transcoding injection attacks. Use of UTF-8 does not hinder internationalization. +HttpUtilities.ResponseContentType=text/html; charset=UTF-8 +# This is the name of the cookie used to represent the HTTP session +# Typically this will be the default "JSESSIONID" +HttpUtilities.HttpSessionIdName=JSESSIONID + + + +#=========================================================================== +# ESAPI Executor +# CHECKME - Not sure what this is used for, but surely it should be made OS independent. +Executor.WorkingDirectory=C:\\Windows\\Temp +Executor.ApprovedExecutables=C:\\Windows\\System32\\cmd.exe,C:\\Windows\\System32\\runas.exe + + +#=========================================================================== +# ESAPI Logging +# Set the application name if these logs are combined with other applications +Logger.ApplicationName=ExampleApplication +# If you use an HTML log viewer that does not properly HTML escape log data, you can set LogEncodingRequired to true +Logger.LogEncodingRequired=false +# Determines whether ESAPI should log the application name. This might be clutter in some single-server/single-app environments. +Logger.LogApplicationName=true +# Determines whether ESAPI should log the server IP and port. This might be clutter in some single-server environments. +Logger.LogServerIP=true +# LogFileName, the name of the logging file. Provide a full directory path (e.g., C:\\ESAPI\\ESAPI_logging_file) if you +# want to place it in a specific directory. +Logger.LogFileName=ESAPI_logging_file +# MaxLogFileSize, the max size (in bytes) of a single log file before it cuts over to a new one (default is 10,000,000) +Logger.MaxLogFileSize=10000000 + + +#=========================================================================== +# ESAPI Intrusion Detection +# +# Each event has a base to which .count, .interval, and .action are added +# The IntrusionException will fire if we receive "count" events within "interval" seconds +# The IntrusionDetector is configurable to take the following actions: log, logout, and disable +# (multiple actions separated by commas are allowed e.g. event.test.actions=log,disable +# +# Custom Events +# Names must start with "event." as the base +# Use IntrusionDetector.addEvent( "test" ) in your code to trigger "event.test" here +# You can also disable intrusion detection completely by changing +# the following parameter to true +# +IntrusionDetector.Disable=false +# +IntrusionDetector.event.test.count=2 +IntrusionDetector.event.test.interval=10 +IntrusionDetector.event.test.actions=disable,log + +# Exception Events +# All EnterpriseSecurityExceptions are registered automatically +# Call IntrusionDetector.getInstance().addException(e) for Exceptions that do not extend EnterpriseSecurityException +# Use the fully qualified classname of the exception as the base + +# any intrusion is an attack +IntrusionDetector.org.owasp.esapi.errors.IntrusionException.count=1 +IntrusionDetector.org.owasp.esapi.errors.IntrusionException.interval=1 +IntrusionDetector.org.owasp.esapi.errors.IntrusionException.actions=log,disable,logout + +# for test purposes +# CHECKME: Shouldn't there be something in the property name itself that designates +# that these are for testing??? +IntrusionDetector.org.owasp.esapi.errors.IntegrityException.count=10 +IntrusionDetector.org.owasp.esapi.errors.IntegrityException.interval=5 +IntrusionDetector.org.owasp.esapi.errors.IntegrityException.actions=log,disable,logout + +# rapid validation errors indicate scans or attacks in progress +# org.owasp.esapi.errors.ValidationException.count=10 +# org.owasp.esapi.errors.ValidationException.interval=10 +# org.owasp.esapi.errors.ValidationException.actions=log,logout + +# sessions jumping between hosts indicates session hijacking +IntrusionDetector.org.owasp.esapi.errors.AuthenticationHostException.count=2 +IntrusionDetector.org.owasp.esapi.errors.AuthenticationHostException.interval=10 +IntrusionDetector.org.owasp.esapi.errors.AuthenticationHostException.actions=log,logout + + +#=========================================================================== +# ESAPI Validation +# +# The ESAPI Validator works on regular expressions with defined names. You can define names +# either here, or you may define application specific patterns in a separate file defined below. +# This allows enterprises to specify both organizational standards as well as application specific +# validation rules. +# +Validator.ConfigurationFile=validation.properties + +# Validators used by ESAPI +Validator.AccountName=^[a-zA-Z0-9]{3,20}$ +Validator.SystemCommand=^[a-zA-Z\\-\\/]{1,64}$ +Validator.RoleName=^[a-z]{1,20}$ + +#the word TEST below should be changed to your application +#name - only relative URL's are supported +Validator.Redirect=^\\/fedlet.*$ + +# Global HTTP Validation Rules +# Values with Base64 encoded data (e.g. encrypted state) will need at least [a-zA-Z0-9\/+=] +Validator.HTTPScheme=^(http|https)$ +Validator.HTTPServerName=^[a-zA-Z0-9_.\\-]*$ +Validator.HTTPParameterName=^[a-zA-Z0-9_]{1,32}$ +Validator.HTTPParameterValue=^[a-zA-Z0-9.\\-\\/+=@_ ]*$ +Validator.HTTPCookieName=^[a-zA-Z0-9\\-_]{1,32}$ +Validator.HTTPCookieValue=^[a-zA-Z0-9\\-\\/+=_ ]*$ +Validator.HTTPHeaderName=^[a-zA-Z0-9\\-_]{1,32}$ +Validator.HTTPHeaderValue=^[a-zA-Z0-9()\\-=\\*\\.\\?;,+\\/:&_ ]*$ +Validator.HTTPContextPath=^\\/?[a-zA-Z0-9.\\-\\/_]*$ +Validator.HTTPServletPath=^[a-zA-Z0-9.\\-\\/_]*$ +Validator.HTTPPath=^[a-zA-Z0-9.\\-_]*$ +Validator.HTTPQueryString=^[a-zA-Z0-9()\\-=\\*\\.\\?;,+\\/:&_ %]*$ +Validator.HTTPURI=^[a-zA-Z0-9()\\-=\\*\\.\\?;,+\\/:&_ ]*$ +Validator.HTTPURL=^.*$ +Validator.HTTPJSESSIONID=^[A-Z0-9]{10,30}$ + +# Validation of file related input +Validator.FileName=^[a-zA-Z0-9!@#$%^&{}\\[\\]()_+\\-=,.~'` ]{1,255}$ +Validator.DirectoryName=^[a-zA-Z0-9:/\\\\!@#$%^&{}\\[\\]()_+\\-=,.~'` ]{1,255}$ + +# Validation of dates. Controls whether or not 'lenient' dates are accepted. +# See DataFormat.setLenient(boolean flag) for further details. +Validator.AcceptLenientDates=false \ No newline at end of file diff --git a/WebContent/classes/META-INF/services/com.google.inject.Module b/WebContent/classes/META-INF/services/com.google.inject.Module new file mode 100644 index 000000000..ff33a735c --- /dev/null +++ b/WebContent/classes/META-INF/services/com.google.inject.Module @@ -0,0 +1,16 @@ +# +# The contents of this file are subject to the terms of the Common Development and +# Distribution License (the License). You may not use this file except in compliance with the +# License. +# +# You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the +# specific language governing permission and limitations under the License. +# +# When distributing Covered Software, include this CDDL Header Notice in each file and include +# the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL +# Header, with the fields enclosed by brackets [] replaced by your own identifying +# information: "Portions copyright [year] [name of copyright owner]". +# +# Copyright 2016 ForgeRock AS. +# +org.forgerock.openam.plugin.configuration.FedletAuditConfigurationGuiceModule \ No newline at end of file diff --git a/WebContent/classes/debugconfig.properties b/WebContent/classes/debugconfig.properties new file mode 100644 index 000000000..3c7d54106 --- /dev/null +++ b/WebContent/classes/debugconfig.properties @@ -0,0 +1,3 @@ +org.forgerock.openam.debug.prefix= +org.forgerock.openam.debug.suffix= +org.forgerock.openam.debug.rotation= diff --git a/WebContent/classes/debugfiles.properties b/WebContent/classes/debugfiles.properties new file mode 100644 index 000000000..a7a12d163 --- /dev/null +++ b/WebContent/classes/debugfiles.properties @@ -0,0 +1,79 @@ +# The contents of this file are subject to the terms of the Common Development and +# Distribution License (the License). You may not use this file except in compliance with the +# License. +# +# You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the +# specific language governing permission and limitations under the License. +# +# When distributing Covered Software, include this CDDL Header Notice in each file and include +# the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL +# Header, with the fields enclosed by brackets [] replaced by your own identifying +# information: "Portions copyright [year] [name of copyright owner]". +# +# Copyright 2016 ForgeRock AS. + +PLLClient=CoreSystem +PossibleLocales=CoreSystem +SystemTimer=CoreSystem +SystemTimerPool=CoreSystem +amAudit=CoreSystem +amBaseURL=CoreSystem +amCLI=Configuration +amClientSchema=Configuration +amComm=CoreSystem +amConfigurator=Configuration +amConsole=Configuration +amCookieUtils=CoreSystem +amDelegation=Configuration +amEventService=Configuration +amFileLookup=CoreSystem +amIdentityServices=CoreSystem +amJAXRPC=CoreSystem +amJSS=CoreSystem +amJSSE=CoreSystem +amLog=CoreSystem +amMonitoring=CoreSystem +amMultiInstall=CoreSystem +amNaming=CoreSystem +amProfile=IdRepo +amRequestUtils=CoreSystem +amResourceLookup=CoreSystem +amRecord=CoreSystem +amSMS=Configuration +amServerProperties=Configuration +amSMSClient=Configuration +amSMSEmbeddedLdap=Configuration +amSMSEvent=Configuration +amSMSFlatFiles=Configuration +amSMSLdap=Configuration +amSMSServerImpl=Configuration +amSecurity=CoreSystem +amSetupServlet=Configuration +amTagLib=CoreSystem +amThreadManager=CoreSystem +amUtil=CoreSystem +amXML=CoreSystem +amXMLHandler=CoreSystem +bundleName=CoreSystem +fmAuthFederation=Authentication +fmCOT=Federation +fmConfiguration=Federation +fmDataStoxreProvider=Federation +libCOT=Federation +libDataStoreProvider=Federation +libEncryption=Federation +libIDFF=Federation +libIDPDiscovery=Federation +libMultipleProtocol=Federation +libPlugins=Federation +libSAML=Federation +libSAML2=Federation +libSAML2Meta=Federation +libWSFederation=Federation +libXACML=Federation +amLogging=CoreSystem +SAML2Decrypt=Federation + +# CAUD loggers +com.zaxxer.hikari.*=CoreSystem +org.forgerock.audit.*=CoreSystem diff --git a/WebContent/classes/fmConfigurationService.properties b/WebContent/classes/fmConfigurationService.properties new file mode 100644 index 000000000..54388ca20 --- /dev/null +++ b/WebContent/classes/fmConfigurationService.properties @@ -0,0 +1,41 @@ +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. +# +# Copyright (c) 2007 Sun Microsystems Inc. All Rights Reserved +# +# The contents of this file are subject to the terms +# of the Common Development and Distribution License +# (the License). You may not use this file except in +# compliance with the License. +# +# You can obtain a copy of the License at +# https://opensso.dev.java.net/public/CDDLv1.0.html or +# opensso/legal/CDDLv1.0.txt +# See the License for the specific language governing +# permission and limitations under the License. +# +# When distributing Covered Code, include this CDDL +# Header Notice in each file and include the License file +# at opensso/legal/CDDLv1.0.txt. +# If applicable, add the following below the CDDL Header, +# with the fields enclosed by brackets [] replaced by +# your own identifying information: +# "Portions Copyrighted [year] [name of copyright owner]" +# +# $Id: fmConfigurationService.properties,v 1.4 2009/10/29 00:01:02 exu Exp $ +# + +componentNameUnsupported=Component "{0}" is not supported. +initFailure=Failed to initialize. +failedGetConfig=Unable to read configuration of component "{0}" for realm "{1}". +configNotExist=Configuration of component "{0}" for realm "{1}" doesn't exist. +failedSetConfig=Unable to set configuration of component "{0}" for realm "{1}". +failedCreateConfig=Unable to create configuration of component "{0}" for realm "{1}". +configExist=Configuration instance "{2}" of component "{0}" for realm "{1}" exists. Delete the entity and reload the meta if required. +failedDeleteConfig=Unable to delete configuration of component "{0}" for realm "{1}". +failedGetConfigNames=Unable to get configuration names of component "{0}" for realm "{1}". +noSubConfig=Configuration of component "{0}" can't have sub configuration. +noOrgConfig=Configuration of component "{0}" can't have organization configuration. +noConfig=Configuration of component "{0}" is not supported. +noConfigCreation=Creation of configuration of component "{0}" is not supported. +noConfigDeletion=Deletion of configuration of component "{0}" is not supported. diff --git a/WebContent/classes/fmConfigurationService_de.properties b/WebContent/classes/fmConfigurationService_de.properties new file mode 100644 index 000000000..0f8fbda50 --- /dev/null +++ b/WebContent/classes/fmConfigurationService_de.properties @@ -0,0 +1,41 @@ +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. +# +# Copyright (c) 2007 Sun Microsystems Inc. All Rights Reserved +# +# The contents of this file are subject to the terms +# of the Common Development and Distribution License +# (the License). You may not use this file except in +# compliance with the License. +# +# You can obtain a copy of the License at +# https://opensso.dev.java.net/public/CDDLv1.0.html or +# opensso/legal/CDDLv1.0.txt +# See the License for the specific language governing +# permission and limitations under the License. +# +# When distributing Covered Code, include this CDDL +# Header Notice in each file and include the License file +# at opensso/legal/CDDLv1.0.txt. +# If applicable, add the following below the CDDL Header, +# with the fields enclosed by brackets [] replaced by +# your own identifying information: +# "Portions Copyrighted [year] [name of copyright owner]" +# +# $Id: fmConfigurationService_de.properties,v 1.11 2009/12/26 03:49:33 cbasha Exp $ +# + +componentNameUnsupported=Komponente "{0}" wird nicht unterst\u00fctzt. +initFailure=Initialisierung fehlgeschlagen. +failedGetConfig=Konfiguration der Komponente "{0}" f\u00fcr Bereich "{1}" kann nicht gelesen werden. +configNotExist=Konfiguration der Komponente "{0}" f\u00fcr Bereich "{1}" ist nicht vorhanden. +failedSetConfig=Konfiguration der Komponente "{0}" f\u00fcr Bereich "{1}" kann nicht eingestellt werden. +failedCreateConfig=Konfiguration der Komponente "{0}" f\u00fcr Bereich "{1}" kann nicht erstellt werden. +configExist=Konfigurationsinstanz "{2}" der Komponente "{0}" f\u00fcr Bereich "{1}" ist vorhanden. L\u00f6schen Sie die Entity und laden Sie die Metadaten neu, falls erforderlich. +failedDeleteConfig=Konfiguration der Komponente "{0}" f\u00fcr Bereich "{1}" kann nicht gel\u00f6scht werden. +failedGetConfigNames=Konfigurationsnamen der Komponente "{0}" f\u00fcr Bereich "{1}" k\u00f6nnen nicht abgerufen werden. +noSubConfig=Konfiguration der Komponente "{0}" kann keine Unterkonfiguration haben. +noOrgConfig=Konfiguration der Komponente "{0}" kann keine Unternehmenskonfiguration haben. +noConfig=Konfiguration der Komponente "{0}" wird nicht unterst\u00fctzt. +noConfigCreation=Erstellung der Konfiguration von Komponente "{0}" wird nicht unterst\u00fctzt. +noConfigDeletion=L\u00f6schen der Konfiguration von Komponente "{0}" wird nicht unterst\u00fctzt. diff --git a/WebContent/classes/fmConfigurationService_es.properties b/WebContent/classes/fmConfigurationService_es.properties new file mode 100644 index 000000000..c396e4456 --- /dev/null +++ b/WebContent/classes/fmConfigurationService_es.properties @@ -0,0 +1,41 @@ +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. +# +# Copyright (c) 2007 Sun Microsystems Inc. All Rights Reserved +# +# The contents of this file are subject to the terms +# of the Common Development and Distribution License +# (the License). You may not use this file except in +# compliance with the License. +# +# You can obtain a copy of the License at +# https://opensso.dev.java.net/public/CDDLv1.0.html or +# opensso/legal/CDDLv1.0.txt +# See the License for the specific language governing +# permission and limitations under the License. +# +# When distributing Covered Code, include this CDDL +# Header Notice in each file and include the License file +# at opensso/legal/CDDLv1.0.txt. +# If applicable, add the following below the CDDL Header, +# with the fields enclosed by brackets [] replaced by +# your own identifying information: +# "Portions Copyrighted [year] [name of copyright owner]" +# +# $Id: fmConfigurationService_es.properties,v 1.11 2009/12/26 03:50:36 cbasha Exp $ +# + +componentNameUnsupported=No se admite el componente "{0}". +initFailure=Fallo al inicializar. +failedGetConfig=No se puede leer la configuraci\u00f3n del componente "{0}" del dominio "{1}". +configNotExist=La configuraci\u00f3n del componente "{0}" del dominio "{1}" no existe. +failedSetConfig=No se puede establecer la configuraci\u00f3n del componente "{0}" del dominio "{1}". +failedCreateConfig=No se puede crear la configuraci\u00f3n del componente "{0}" del dominio "{1}". +configExist=La instancia de configuraci\u00f3n "{2}" del componente "{0}" del dominio "{1}" ya existe. Eliminar la entrada y volver a cargar los metadatos si es necesario. +failedDeleteConfig=No se puede eliminar la configuraci\u00f3n del componente "{0}" del dominio "{1}". +failedGetConfigNames=No se pueden obtener los nombres de configuraci\u00f3n del componente "{0}" del dominio "{1}". +noSubConfig=La configuraci\u00f3n del componente "{0}" no puede tener una configuraci\u00f3n secundaria. +noOrgConfig=La configuraci\u00f3n del componente "{0}" no puede tener una configuraci\u00f3n de la organizaci\u00f3n. +noConfig=No se admite la configuraci\u00f3n del componente "{0}". +noConfigCreation=No se admite la creaci\u00f3n de la configuraci\u00f3n del componente "{0}". +noConfigDeletion=No se admite la eliminaci\u00f3n de la configuraci\u00f3n del componente "{0}". diff --git a/WebContent/classes/fmConfigurationService_fr.properties b/WebContent/classes/fmConfigurationService_fr.properties new file mode 100644 index 000000000..668756eac --- /dev/null +++ b/WebContent/classes/fmConfigurationService_fr.properties @@ -0,0 +1,41 @@ +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. +# +# Copyright (c) 2007 Sun Microsystems Inc. All Rights Reserved +# +# The contents of this file are subject to the terms +# of the Common Development and Distribution License +# (the License). You may not use this file except in +# compliance with the License. +# +# You can obtain a copy of the License at +# https://opensso.dev.java.net/public/CDDLv1.0.html or +# opensso/legal/CDDLv1.0.txt +# See the License for the specific language governing +# permission and limitations under the License. +# +# When distributing Covered Code, include this CDDL +# Header Notice in each file and include the License file +# at opensso/legal/CDDLv1.0.txt. +# If applicable, add the following below the CDDL Header, +# with the fields enclosed by brackets [] replaced by +# your own identifying information: +# "Portions Copyrighted [year] [name of copyright owner]" +# +# $Id: fmConfigurationService_fr.properties,v 1.11 2009/12/26 03:48:25 cbasha Exp $ +# + +componentNameUnsupported=Le composant "{0}" n\u2019est pas pris en charge. +initFailure=L\u2019initialisation a \u00e9chou\u00e9. +failedGetConfig=Impossible de lire la configuration du composant "{0}" pour le domaine "{1}". +configNotExist=La configuration du composant "{0}" pour le domaine "{1}" n\u2019existe pas. +failedSetConfig=Impossible de d\u00e9finir la configuration du composant "{0}" pour le domaine "{1}". +failedCreateConfig=Impossible de cr\u00e9er la configuration du composant "{0}" pour le domaine "{1}". +configExist=L\u2019instance de configuration "{2}" du composant "{0}" pour le domaine "{1}" existe. Supprimer l\u2019entit\u00e9 et charger \u00e0 nouveau les \u00e9l\u00e9ments m\u00e9ta si n\u00e9cessaire. +failedDeleteConfig=Impossible de supprimer la configuration du composant "{0}" pour le domaine "{1}". +failedGetConfigNames=Impossible d\u2019obtenir les noms de configuration du composant "{0}" pour le domaine "{1}". +noSubConfig=La configuration du composant "{0}" ne peut pas contenir de sous-configuration. +noOrgConfig=La configuration du composant "{0}" ne peut pas contenir de configuration d\u2019organisation. +noConfig=La configuration du composant "{0}" n\u2019est pas prise en charge. +noConfigCreation=La cr\u00e9ation de la configuration du composant "{0}" n\u2019est pas prise en charge. +noConfigDeletion=La suppression de la configuration du composant "{0}" n\u2019est pas prise en charge. diff --git a/WebContent/classes/fmConfigurationService_ja.properties b/WebContent/classes/fmConfigurationService_ja.properties new file mode 100644 index 000000000..85ef73c40 --- /dev/null +++ b/WebContent/classes/fmConfigurationService_ja.properties @@ -0,0 +1,41 @@ +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. +# +# Copyright (c) 2007 Sun Microsystems Inc. All Rights Reserved +# +# The contents of this file are subject to the terms +# of the Common Development and Distribution License +# (the License). You may not use this file except in +# compliance with the License. +# +# You can obtain a copy of the License at +# https://opensso.dev.java.net/public/CDDLv1.0.html or +# opensso/legal/CDDLv1.0.txt +# See the License for the specific language governing +# permission and limitations under the License. +# +# When distributing Covered Code, include this CDDL +# Header Notice in each file and include the License file +# at opensso/legal/CDDLv1.0.txt. +# If applicable, add the following below the CDDL Header, +# with the fields enclosed by brackets [] replaced by +# your own identifying information: +# "Portions Copyrighted [year] [name of copyright owner]" +# +# $Id: fmConfigurationService_ja.properties,v 1.11 2009/12/26 03:47:13 cbasha Exp $ +# + +componentNameUnsupported=\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u300c{0}\u300d\u306f\u30b5\u30dd\u30fc\u30c8\u3057\u3066\u3044\u307e\u305b\u3093\u3002 +initFailure=\u521d\u671f\u5316\u306b\u5931\u6557\u3057\u307e\u3057\u305f\u3002 +failedGetConfig=\u30ec\u30eb\u30e0\u300c{1}\u300d\u306e\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u300c{0}\u300d\u306e\u8a2d\u5b9a\u3092\u8aad\u307f\u53d6\u308c\u307e\u305b\u3093\u3002 +configNotExist=\u30ec\u30eb\u30e0\u300c{1}\u300d\u306e\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u300c{0}\u300d\u306e\u8a2d\u5b9a\u304c\u5b58\u5728\u3057\u307e\u305b\u3093\u3002 +failedSetConfig=\u30ec\u30eb\u30e0\u300c{1}\u300d\u306e\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u300c{0}\u300d\u306e\u8a2d\u5b9a\u3092\u8a2d\u5b9a\u3067\u304d\u307e\u305b\u3093\u3002 +failedCreateConfig=\u30ec\u30eb\u30e0\u300c{1}\u300d\u306e\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u300c{0}\u300d\u306e\u8a2d\u5b9a\u3092\u4f5c\u6210\u3067\u304d\u307e\u305b\u3093\u3002 +configExist=\u30ec\u30eb\u30e0\u300c{1}\u300d\u306e\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u300c{0}\u300d\u306e\u8a2d\u5b9a\u30a4\u30f3\u30b9\u30bf\u30f3\u30b9\u300c{2}\u300d\u304c\u5b58\u5728\u3057\u307e\u3059\u3002\u30a8\u30f3\u30c6\u30a3\u30c6\u30a3\u30fc\u3092\u524a\u9664\u3057\u3001\u5fc5\u8981\u306b\u5fdc\u3058\u3066\u30e1\u30bf\u3092\u518d\u8aad\u307f\u8fbc\u307f\u3057\u307e\u3059\u3002 +failedDeleteConfig=\u30ec\u30eb\u30e0\u300c{1}\u300d\u306e\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u300c{0}\u300d\u306e\u8a2d\u5b9a\u3092\u524a\u9664\u3067\u304d\u307e\u305b\u3093\u3002 +failedGetConfigNames=\u30ec\u30eb\u30e0\u300c{1}\u300d\u306e\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u300c{0}\u300d\u306e\u8a2d\u5b9a\u540d\u3092\u53d6\u5f97\u3067\u304d\u307e\u305b\u3093\u3002 +noSubConfig=\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u300c{0}\u300d\u306e\u8a2d\u5b9a\u306b\u306f\u3001\u30b5\u30d6\u8a2d\u5b9a\u3092\u4f5c\u6210\u3067\u304d\u307e\u305b\u3093\u3002 +noOrgConfig=\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u300c{0}\u300d\u306e\u8a2d\u5b9a\u306b\u306f\u3001\u7d44\u7e54\u8a2d\u5b9a\u3092\u4f5c\u6210\u3067\u304d\u307e\u305b\u3093\u3002 +noConfig=\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u300c{0}\u300d\u306e\u8a2d\u5b9a\u306f\u30b5\u30dd\u30fc\u30c8\u3057\u3066\u3044\u307e\u305b\u3093\u3002 +noConfigCreation=\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u300c{0}\u300d\u306e\u8a2d\u5b9a\u306e\u4f5c\u6210\u306f\u30b5\u30dd\u30fc\u30c8\u3057\u3066\u3044\u307e\u305b\u3093\u3002 +noConfigDeletion=\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u300c{0}\u300d\u306e\u8a2d\u5b9a\u306e\u524a\u9664\u306f\u30b5\u30dd\u30fc\u30c8\u3057\u3066\u3044\u307e\u305b\u3093\u3002 diff --git a/WebContent/classes/fmConfigurationService_ko.properties b/WebContent/classes/fmConfigurationService_ko.properties new file mode 100644 index 000000000..e8fc9dc91 --- /dev/null +++ b/WebContent/classes/fmConfigurationService_ko.properties @@ -0,0 +1,40 @@ +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. +# +# Copyright (c) 2007 Sun Microsystems Inc. All Rights Reserved +# +# The contents of this file are subject to the terms +# of the Common Development and Distribution License +# (the License). You may not use this file except in +# compliance with the License. +# +# You can obtain a copy of the License at +# https://opensso.dev.java.net/public/CDDLv1.0.html or +# opensso/legal/CDDLv1.0.txt +# See the License for the specific language governing +# permission and limitations under the License. +# +# When distributing Covered Code, include this CDDL +# Header Notice in each file and include the License file +# at opensso/legal/CDDLv1.0.txt. +# If applicable, add the following below the CDDL Header, +# with the fields enclosed by brackets [] replaced by +# your own identifying information: +# "Portions Copyrighted [year] [name of copyright owner]" +# +# $Id: fmConfigurationService_ko.properties,v 1.11 2009/07/16 04:27:42 cbasha Exp $ +# + +componentNameUnsupported="{0}" \uad6c\uc131 \uc694\uc18c\ub294 \uc9c0\uc6d0\ub418\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4. +failedGetConfig="{1}" \uc601\uc5ed\uc5d0 \ub300\ud55c \uad6c\uc131 \uc694\uc18c "{0}"\uc758 \uad6c\uc131\uc744 \uc77d\uc744 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4. +configNotExist="{1}" \uc601\uc5ed\uc5d0 \ub300\ud55c \uad6c\uc131 \uc694\uc18c "{0}"\uc758 \uad6c\uc131\uc774 \uc5c6\uc2b5\ub2c8\ub2e4. +failedSetConfig="{1}" \uc601\uc5ed\uc5d0 \ub300\ud55c \uad6c\uc131 \uc694\uc18c "{0}"\uc758 \uad6c\uc131\uc744 \uc124\uc815\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4. +failedCreateConfig="{1}" \uc601\uc5ed\uc5d0 \ub300\ud55c \uad6c\uc131 \uc694\uc18c "{0}"\uc758 \uad6c\uc131\uc744 \ub9cc\ub4e4 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4. +configExist="{1}" \uc601\uc5ed\uc5d0 \ub300\ud55c \uad6c\uc131 \uc694\uc18c "{0}"\uc758 "{2}" \uad6c\uc131 \uc778\uc2a4\ud134\uc2a4\uac00 \uc874\uc7ac\ud569\ub2c8\ub2e4. \ud544\uc694\ud55c \uacbd\uc6b0 \uc5d4\ud2f0\ud2f0\ub97c \uc0ad\uc81c\ud558\uace0 \uba54\ud0c0 \uc815\ubcf4\ub97c \uc7ac\ub85c\ub4dc\ud574\uc57c \ud569\ub2c8\ub2e4. +failedDeleteConfig="{1}" \uc601\uc5ed\uc5d0 \ub300\ud55c \uad6c\uc131 \uc694\uc18c "{0}"\uc758 \uad6c\uc131\uc744 \uc0ad\uc81c\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4. +failedGetConfigNames="{1}" \uc601\uc5ed\uc5d0 \ub300\ud55c \uad6c\uc131 \uc694\uc18c "{0}"\uc758 \uad6c\uc131 \uc774\ub984\uc744 \uac00\uc838\uc62c \uc218 \uc5c6\uc2b5\ub2c8\ub2e4. +noSubConfig="{0}" \uad6c\uc131 \uc694\uc18c\uc758 \uad6c\uc131\uc5d0\ub294 \ud558\uc704 \uad6c\uc131\uc774 \uc788\uc744 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4. +noOrgConfig="{0}" \uad6c\uc131 \uc694\uc18c\uc758 \uad6c\uc131\uc5d0\ub294 \uc870\uc9c1 \uad6c\uc131\uc774 \uc788\uc744 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4. +noConfig="{0}" \uad6c\uc131 \uc694\uc18c\uc758 \uad6c\uc131\uc740 \uc9c0\uc6d0\ub418\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4. +noConfigCreation="{0}" \uad6c\uc131 \uc694\uc18c\uc758 \uad6c\uc131\uc744 \ub9cc\ub4e4 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4. +noConfigDeletion="{0}" \uad6c\uc131 \uc694\uc18c\uc758 \uad6c\uc131\uc744 \uc0ad\uc81c\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4. diff --git a/WebContent/classes/fmConfigurationService_zh.properties b/WebContent/classes/fmConfigurationService_zh.properties new file mode 100644 index 000000000..ebb9d659a --- /dev/null +++ b/WebContent/classes/fmConfigurationService_zh.properties @@ -0,0 +1,41 @@ +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. +# +# Copyright (c) 2007 Sun Microsystems Inc. All Rights Reserved +# +# The contents of this file are subject to the terms +# of the Common Development and Distribution License +# (the License). You may not use this file except in +# compliance with the License. +# +# You can obtain a copy of the License at +# https://opensso.dev.java.net/public/CDDLv1.0.html or +# opensso/legal/CDDLv1.0.txt +# See the License for the specific language governing +# permission and limitations under the License. +# +# When distributing Covered Code, include this CDDL +# Header Notice in each file and include the License file +# at opensso/legal/CDDLv1.0.txt. +# If applicable, add the following below the CDDL Header, +# with the fields enclosed by brackets [] replaced by +# your own identifying information: +# "Portions Copyrighted [year] [name of copyright owner]" +# +# $Id: fmConfigurationService_zh.properties,v 1.12 2009/12/26 03:46:04 cbasha Exp $ +# + +componentNameUnsupported=\u4e0d\u652f\u6301\u7ec4\u4ef6 "{0}"\u3002 +initFailure=\u521d\u59cb\u5316\u5931\u8d25\u3002 +failedGetConfig=\u65e0\u6cd5\u8bfb\u53d6\u9886\u57df "{1}" \u7684\u7ec4\u4ef6 "{0}" \u7684\u914d\u7f6e\u3002 +configNotExist=\u9886\u57df "{1}" \u7684\u7ec4\u4ef6 "{0}" \u7684\u914d\u7f6e\u4e0d\u5b58\u5728\u3002 +failedSetConfig=\u65e0\u6cd5\u8bbe\u7f6e\u9886\u57df "{1}" \u7684\u7ec4\u4ef6 "{0}" \u7684\u914d\u7f6e\u3002 +failedCreateConfig=\u65e0\u6cd5\u521b\u5efa\u9886\u57df "{1}" \u7684\u7ec4\u4ef6 "{0}" \u7684\u914d\u7f6e\u3002 +configExist=\u9886\u57df "{1}" \u7684\u7ec4\u4ef6 "{0}" \u7684\u914d\u7f6e\u5b9e\u4f8b "{2}" \u5b58\u5728\u3002\u5220\u9664\u5b9e\u4f53\u5e76\u91cd\u65b0\u88c5\u5165\u5143\u6570\u636e\uff08\u5982\u679c\u9700\u8981\uff09\u3002 +failedDeleteConfig=\u65e0\u6cd5\u5220\u9664\u9886\u57df "{1}" \u7684\u7ec4\u4ef6 "{0}" \u7684\u914d\u7f6e\u3002 +failedGetConfigNames=\u65e0\u6cd5\u83b7\u53d6\u9886\u57df "{1}" \u7684\u7ec4\u4ef6 "{0}" \u7684\u914d\u7f6e\u540d\u79f0\u3002 +noSubConfig=\u7ec4\u4ef6 "{0}" \u7684\u914d\u7f6e\u4e0d\u80fd\u62e5\u6709\u5b50\u914d\u7f6e\u3002 +noOrgConfig=\u7ec4\u4ef6 "{0}" \u7684\u914d\u7f6e\u4e0d\u80fd\u62e5\u6709\u7ec4\u7ec7\u914d\u7f6e\u3002 +noConfig=\u4e0d\u652f\u6301\u7ec4\u4ef6 "{0}" \u7684\u914d\u7f6e\u3002 +noConfigCreation=\u4e0d\u652f\u6301\u521b\u5efa\u7ec4\u4ef6 "{0}" \u7684\u914d\u7f6e\u3002 +noConfigDeletion=\u4e0d\u652f\u6301\u5220\u9664\u7ec4\u4ef6 "{0}" \u7684\u914d\u7f6e\u3002 diff --git a/WebContent/classes/fmConfigurationService_zh_TW.properties b/WebContent/classes/fmConfigurationService_zh_TW.properties new file mode 100644 index 000000000..61510c4c9 --- /dev/null +++ b/WebContent/classes/fmConfigurationService_zh_TW.properties @@ -0,0 +1,40 @@ +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. +# +# Copyright (c) 2007 Sun Microsystems Inc. All Rights Reserved +# +# The contents of this file are subject to the terms +# of the Common Development and Distribution License +# (the License). You may not use this file except in +# compliance with the License. +# +# You can obtain a copy of the License at +# https://opensso.dev.java.net/public/CDDLv1.0.html or +# opensso/legal/CDDLv1.0.txt +# See the License for the specific language governing +# permission and limitations under the License. +# +# When distributing Covered Code, include this CDDL +# Header Notice in each file and include the License file +# at opensso/legal/CDDLv1.0.txt. +# If applicable, add the following below the CDDL Header, +# with the fields enclosed by brackets [] replaced by +# your own identifying information: +# "Portions Copyrighted [year] [name of copyright owner]" +# +# $Id: fmConfigurationService_zh_TW.properties,v 1.11 2009/07/16 04:27:45 cbasha Exp $ +# + +componentNameUnsupported=\u4e0d\u652f\u63f4\u5143\u4ef6\u300c{0}\u300d\u3002 +failedGetConfig=\u7121\u6cd5\u8b80\u53d6\u7bc4\u570d\u300c{1}\u300d\u4e4b\u5143\u4ef6\u300c{0}\u300d\u7684\u914d\u7f6e\u3002 +configNotExist=\u7bc4\u570d\u300c{1}\u300d\u4e4b\u5143\u4ef6\u300c{0}\u300d\u7684\u914d\u7f6e\u4e0d\u5b58\u5728\u3002 +failedSetConfig=\u7121\u6cd5\u8a2d\u5b9a\u7bc4\u570d\u300c{1}\u300d\u4e4b\u5143\u4ef6\u300c{0}\u300d\u7684\u914d\u7f6e\u3002 +failedCreateConfig=\u7121\u6cd5\u5efa\u7acb\u7bc4\u570d\u300c{1}\u300d\u4e4b\u5143\u4ef6\u300c{0}\u300d\u7684\u914d\u7f6e\u3002 +configExist=\u7bc4\u570d\u300c{1}\u300d\u4e4b\u5143\u4ef6\u300c{0}\u300d\u7684\u914d\u7f6e\u5be6\u4f8b\u300c{2}\u300d\u5b58\u5728\u3002\u522a\u9664\u5be6\u9ad4\uff0c\u7136\u5f8c\u6839\u64da\u9700\u8981\u91cd\u65b0\u8f09\u5165\u4e2d\u4ecb\u8cc7\u6599\u3002 +failedDeleteConfig=\u7121\u6cd5\u522a\u9664\u7bc4\u570d\u300c{1}\u300d\u4e4b\u5143\u4ef6\u300c{0}\u300d\u7684\u914d\u7f6e\u3002 +failedGetConfigNames=\u7121\u6cd5\u53d6\u5f97\u7bc4\u570d\u300c{1}\u300d\u4e4b\u5143\u4ef6\u300c{0}\u300d\u7684\u914d\u7f6e\u540d\u7a31\u3002 +noSubConfig=\u5143\u4ef6\u300c{0}\u300d\u7684\u914d\u7f6e\u4e0d\u80fd\u6709\u5b50\u914d\u7f6e\u3002 +noOrgConfig=\u5143\u4ef6\u300c{0}\u300d\u7684\u914d\u7f6e\u4e0d\u80fd\u6709\u7d44\u7e54\u914d\u7f6e\u3002 +noConfig=\u4e0d\u652f\u63f4\u5143\u4ef6\u300c{0}\u300d\u7684\u914d\u7f6e\u3002 +noConfigCreation=\u4e0d\u652f\u63f4\u5efa\u7acb\u5143\u4ef6\u300c{0}\u300d\u7684\u914d\u7f6e\u3002 +noConfigDeletion=\u4e0d\u652f\u63f4\u522a\u9664\u5143\u4ef6\u300c{0}\u300d\u7684\u914d\u7f6e\u3002 From df59821590c5cd087b4f1bac7695f78b72f65d64 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 14 Apr 2021 17:13:22 +0000 Subject: [PATCH 0777/1906] UPDATE ::: Moving properties to SAML UPDATE ::: Uncommenting out SSOFilter git-svn-id: svn://107.170.10.188:8080/Monolith/dev@43410 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: bcd83eadd6d9531b8280548eacb2b9e67d1b6ef1 --- .../services/saml/SamlVerifierServlet.java | 9 +- src/prerna/web/conf/SSOFilter.java | 173 +++++++++--------- src/prerna/web/conf/util/SSOUtil.java | 3 +- 3 files changed, 92 insertions(+), 93 deletions(-) diff --git a/src/prerna/semoss/web/services/saml/SamlVerifierServlet.java b/src/prerna/semoss/web/services/saml/SamlVerifierServlet.java index 7f8198809..2f8c4ac95 100644 --- a/src/prerna/semoss/web/services/saml/SamlVerifierServlet.java +++ b/src/prerna/semoss/web/services/saml/SamlVerifierServlet.java @@ -70,11 +70,10 @@ public void verifySamlOutput(HttpServletRequest request, HttpServletResponse res // sample file path that we actually need to give. Make sure the Federation // file is there inside the debug folder. // "C:\\workspace\\Semoss_Dev\\saml\\mesoc\\conf\\debug\\Federation" - String federationLogPath = ((String) DIHelper.getInstance().getCoreProp().get("SAML_FEDERATION_LOG_PATH")).trim(); - BufferedWriter out = new BufferedWriter( - new FileWriter(new File(federationLogPath))); - - try { + String federationLogPath = ((String) DIHelper.getInstance().getCoreProp().get(Constants.SAML_FEDERATION_LOG_PATH)).trim(); + + try( BufferedWriter out = new BufferedWriter( + new FileWriter(new File(federationLogPath))) ) { // invoke the SAML processing logic. this will do all the // necessary processing conforming to SAMLv2 specifications, // such as XML signature validation, Audience and Recipient diff --git a/src/prerna/web/conf/SSOFilter.java b/src/prerna/web/conf/SSOFilter.java index 17ad0ef8b..53500e4a5 100644 --- a/src/prerna/web/conf/SSOFilter.java +++ b/src/prerna/web/conf/SSOFilter.java @@ -1,87 +1,86 @@ -//package prerna.web.conf; -// -//import java.io.IOException; -// -//import javax.servlet.Filter; -//import javax.servlet.FilterChain; -//import javax.servlet.FilterConfig; -//import javax.servlet.ServletException; -//import javax.servlet.ServletRequest; -//import javax.servlet.ServletResponse; -//import javax.servlet.http.HttpServletRequest; -//import javax.servlet.http.HttpServletResponse; -//import javax.servlet.http.HttpSession; -// -//import org.apache.logging.log4j.LogManager; -//import org.apache.logging.log4j.Logger; -// -//import prerna.auth.User; -//import prerna.semoss.web.services.config.AdminConfigService; -//import prerna.util.Constants; -//import prerna.util.Utility; -//import prerna.web.conf.util.SSOUtil; -// -///** -// * Servlet Filter implementation class SamlFilter -// */ -//public class SSOFilter implements Filter { -// -// private static final Logger logger = LogManager.getLogger(SSOFilter.class); -// -// private static final String SAML_LOGIN_HTML = "/samlLogin/"; -// -// /** -// * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain) -// */ -// public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { -// -// HttpSession session = ((HttpServletRequest) request).getSession(false); -// User user = null; -// -// // Check if user is already there in the session. If there, -// // then get the existing user and travel down the chain. -// if (session != null) { -// user = (User) session.getAttribute(Constants.SESSION_USER); -// } -// -// // User has not logged in - redirect to the base page to start the -// // SAML workflow -// if(user == null) { -// logger.info("Starting saml transaction."); -// -// // we need to store information in the session -// // so that we can properly come back to the referer once an admin has been added -// String referer = ((HttpServletRequest) request).getHeader("referer"); -// referer = referer + "#!/login"; -// ((HttpServletRequest) request).getSession(true).setAttribute(SSOUtil.SAML_REDIRECT_KEY, referer); -// -// // this will be the deployment name of the app -// String contextPath = request.getServletContext().getContextPath(); -// -// // this will be the full path of the request -// // like http://localhost:8080/Monolith_Dev/api/engine/runPixel -// String fullUrl = Utility.cleanHttpResponse(((HttpServletRequest) request).getRequestURL().toString()); -// -// // we redirect to the index.html page specifically created for the SAML call. -// String redirectUrl = fullUrl.substring(0, fullUrl.indexOf(contextPath) + contextPath.length()) + SAML_LOGIN_HTML; -// ((HttpServletResponse) response).setHeader("redirect", redirectUrl); -// ((HttpServletResponse) response).sendError(302, "Need to redirect to " + redirectUrl); -// return; -// } -// -// chain.doFilter(request, response); -// } -// -// @Override -// public void destroy() { -// // TODO Auto-generated method stub -// -// } -// -// @Override -// public void init(FilterConfig arg0) throws ServletException { -// // TODO Auto-generated method stub -// -// } -// -//} +package prerna.web.conf; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import prerna.auth.User; +import prerna.util.Constants; +import prerna.util.Utility; +import prerna.web.conf.util.SSOUtil; + +/** + * Servlet Filter implementation class SamlFilter + */ +public class SSOFilter implements Filter { + + private static final Logger logger = LogManager.getLogger(SSOFilter.class); + + private static final String SAML_LOGIN_HTML = "/samlLogin/"; + + /** + * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain) + */ + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + + HttpSession session = ((HttpServletRequest) request).getSession(false); + User user = null; + + // Check if user is already there in the session. If there, + // then get the existing user and travel down the chain. + if (session != null) { + user = (User) session.getAttribute(Constants.SESSION_USER); + } + + // User has not logged in - redirect to the base page to start the + // SAML workflow + if(user == null) { + logger.info("Starting saml transaction."); + + // we need to store information in the session + // so that we can properly come back to the referer once an admin has been added + String referer = ((HttpServletRequest) request).getHeader("referer"); + referer = referer + "#!/login"; + ((HttpServletRequest) request).getSession(true).setAttribute(SSOUtil.SAML_REDIRECT_KEY, referer); + + // this will be the deployment name of the app + String contextPath = request.getServletContext().getContextPath(); + + // this will be the full path of the request + // like http://localhost:8080/Monolith_Dev/api/engine/runPixel + String fullUrl = Utility.cleanHttpResponse(((HttpServletRequest) request).getRequestURL().toString()); + + // we redirect to the index.html page specifically created for the SAML call. + String redirectUrl = fullUrl.substring(0, fullUrl.indexOf(contextPath) + contextPath.length()) + SAML_LOGIN_HTML; + ((HttpServletResponse) response).setHeader("redirect", redirectUrl); + ((HttpServletResponse) response).sendError(302, "Need to redirect to " + redirectUrl); + return; + } + + chain.doFilter(request, response); + } + + @Override + public void destroy() { + // TODO Auto-generated method stub + + } + + @Override + public void init(FilterConfig arg0) throws ServletException { + // TODO Auto-generated method stub + + } + +} diff --git a/src/prerna/web/conf/util/SSOUtil.java b/src/prerna/web/conf/util/SSOUtil.java index dd7530c10..b791faff6 100644 --- a/src/prerna/web/conf/util/SSOUtil.java +++ b/src/prerna/web/conf/util/SSOUtil.java @@ -23,6 +23,7 @@ import com.sun.identity.saml2.meta.SAML2MetaException; import com.sun.identity.saml2.meta.SAML2MetaManager; +import prerna.util.Constants; import prerna.util.DIHelper; /** @@ -68,7 +69,7 @@ private void setFedletHomeDir() { System.setProperty("com.sun.identity.federation.fedCookieName", "fedCookie"); // this is where we set the SAML home dir by getting the loc from RDF props. - String confLocation = ((String) DIHelper.getInstance().getCoreProp().get("SAML_PROP_LOC")).trim(); + String confLocation = ((String) DIHelper.getInstance().getCoreProp().get(Constants.SAML_PROP_LOC)).trim(); logger.info("Directory is set to.. " + confLocation); System.getProperties().setProperty("com.sun.identity.fedlet.home", confLocation); From c6d86ce11db005ec687175be95619031f25a5e28 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 14 Apr 2021 17:25:53 +0000 Subject: [PATCH 0778/1906] UPDATE ::: Adding saml login html for redirecting to IDP git-svn-id: svn://107.170.10.188:8080/Monolith/dev@43413 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 53e570095569d47d7d943da805b4787756163784 --- WebContent/samlLogin/index.html | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 WebContent/samlLogin/index.html diff --git a/WebContent/samlLogin/index.html b/WebContent/samlLogin/index.html new file mode 100644 index 000000000..1ff583837 --- /dev/null +++ b/WebContent/samlLogin/index.html @@ -0,0 +1,20 @@ + + + + + + + + + + + \ No newline at end of file From d363875e975c09aa9f3a3dadae8d1f752d1c53d6 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 14 Apr 2021 18:06:38 +0000 Subject: [PATCH 0779/1906] UPDATE ::: Making sure user id for saml is set UPDATE ::: Throwing error when adding user if the id is null git-svn-id: svn://107.170.10.188:8080/Monolith/dev@43416 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: efa6f680a1836452302285ad5f39249e3b28f893 --- src/prerna/semoss/web/services/saml/SamlVerifierServlet.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/prerna/semoss/web/services/saml/SamlVerifierServlet.java b/src/prerna/semoss/web/services/saml/SamlVerifierServlet.java index 2f8c4ac95..2120ae3c8 100644 --- a/src/prerna/semoss/web/services/saml/SamlVerifierServlet.java +++ b/src/prerna/semoss/web/services/saml/SamlVerifierServlet.java @@ -129,8 +129,9 @@ public void verifySamlOutput(HttpServletRequest request, HttpServletResponse res AccessToken token = null; User user = new User(); token = new AccessToken(); - token.setProvider(AuthProvider.SAML); + token.setId(userId); token.setUsername(userId); + token.setProvider(AuthProvider.SAML); user.setAccessToken(token); SecurityUpdateUtils.addOAuthUser(token); session.setAttribute(Constants.SESSION_USER, user); From 2e4a9ebcbb423022e37a616d5b132b0243faf66f Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 14 Apr 2021 18:44:40 +0000 Subject: [PATCH 0780/1906] UPDATE ::: Adding commented out SSOFilter for SAML git-svn-id: svn://107.170.10.188:8080/Monolith/dev@43419 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 3c02b01b15dfce44a7b0bdb701cc5e8a88a281bb --- WebContent/WEB-INF/web.xml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index 8c4ea48b2..4cb54f552 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -119,6 +119,18 @@ /api/schedule/* + + + - com.github.dblock.waffle - waffle-jna - 1.8.1 - + com.github.waffle + waffle-jna + 3.0.0 + * * @@ -1970,15 +1971,14 @@ - org.openidentityplatform.openam - openam-federation-library - 14.6.1 + org.openidentityplatform.openam + openam-federation-library + 14.6.1 - com.github.oshi - oshi-core - 5.7.2 - - + com.github.oshi + oshi-core + 5.7.2 + \ No newline at end of file From 2d469b222f186c0755694056f7576079789c1a6f Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 11 May 2021 17:43:56 +0000 Subject: [PATCH 0792/1906] UPDATE ::: Switching to https for our maven 3rdPartyJars repository git-svn-id: svn://107.170.10.188:8080/Monolith/dev@43673 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 7125ce572afe05844c4495f2cef03279fbb7a457 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 10b3bfc1d..ac472c0c8 100644 --- a/pom.xml +++ b/pom.xml @@ -265,7 +265,7 @@ 3rdPartyJARs Maven repository - http://maven.semoss.org:8081/repository/3rdPartyJARs + https://maven.semoss.org/repository/3rdPartyJARs true From a6f311984f429abd4163134011675e80b10872a1 Mon Sep 17 00:00:00 2001 From: pkapaleeswaran Date: Fri, 14 May 2021 22:55:11 +0000 Subject: [PATCH 0793/1906] New Filter for memory - sits on /* git-svn-id: svn://107.170.10.188:8080/Monolith/dev@43699 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: d9c969e63c8f3a4a5f580cc049713c4d012d3019 --- src/prerna/web/conf/MemoryCheckFilter.java | 97 ++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 src/prerna/web/conf/MemoryCheckFilter.java diff --git a/src/prerna/web/conf/MemoryCheckFilter.java b/src/prerna/web/conf/MemoryCheckFilter.java new file mode 100644 index 000000000..24e0ba2f9 --- /dev/null +++ b/src/prerna/web/conf/MemoryCheckFilter.java @@ -0,0 +1,97 @@ +package prerna.web.conf; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import prerna.auth.User; +import prerna.sablecc2.reactor.mgmt.MgmtUtil; +import prerna.util.Constants; +import prerna.util.DIHelper; +import prerna.util.Settings; +import prerna.util.Utility; + +public class MemoryCheckFilter implements Filter { + + private static final String NO_MORE_MEMORY = "/sessionCounterFail/"; + + @Override + public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { + + //check to see if the user is logged in + // if yes.. nothing to do + // if not then try to see if we have memory + // if not move the uset to oom page + + ServletContext context = arg0.getServletContext(); + + HttpSession session = ((HttpServletRequest) arg0).getSession(false); + String fullUrl = Utility.cleanHttpResponse(((HttpServletRequest) arg0).getRequestURL().toString()); + User user = null; + if (session != null) { + // System.out.println("Session ID >> " + session.getId()); + user = (User) session.getAttribute(Constants.SESSION_USER); + } + if(user == null && !fullUrl.endsWith(NO_MORE_MEMORY) && !canLoadUser() ) + { + // this will be the deployment name of the app + String contextPath = context.getContextPath(); + + // this will be the full path of the request + // like http://localhost:8080/Monolith_Dev/api/engine/runPixel + // we redirect to the index.html page where we have pushed the admin page + String redirectUrl = fullUrl.substring(0, fullUrl.indexOf(contextPath) + contextPath.length()) + NO_MORE_MEMORY; + ((HttpServletResponse) arg1).setHeader("redirect", redirectUrl); + ((HttpServletResponse) arg1).sendError(302, "Need to redirect to " + redirectUrl); + return; + } + + arg2.doFilter(arg0, arg1); + } + + public boolean canLoadUser() + { + boolean canLoad = true; + + String checkMemSettings = DIHelper.getInstance().getProperty(Settings.CHECK_MEM); + + boolean checkMem = checkMemSettings != null && checkMemSettings.equalsIgnoreCase("true"); + if(checkMem) + { + long freeMem = MgmtUtil.getFreeMemory(); + String memProfileSettings = DIHelper.getInstance().getProperty(Settings.MEM_PROFILE_SETTINGS); + + if(memProfileSettings.equalsIgnoreCase(Settings.CONSTANT_MEM)) + { + String memLimitSettings = DIHelper.getInstance().getProperty(Settings.USER_MEM_LIMIT); + int limit = Integer.parseInt(memLimitSettings); + canLoad = limit < freeMem; + } + } + + return canLoad; + } + + + @Override + public void destroy() { + // TODO Auto-generated method stub + + } + + + @Override + public void init(FilterConfig arg0) throws ServletException { + // TODO Auto-generated method stub + + } +} From 732e5281d6a8d6403dc7b8beb79df0677f11bbfc Mon Sep 17 00:00:00 2001 From: pkapaleeswaran Date: Mon, 17 May 2021 02:29:21 +0000 Subject: [PATCH 0794/1906] UserResource - Update to reclaim memory on logout NoUserInSessionFilter.java - Removed all of the check for memory since it is now its own Filter PublicHomeCheckFilter.java - Check for publishing the asset folder. Checks to see if the user is allowed and then triggers the deployment as a symbolic link. git-svn-id: svn://107.170.10.188:8080/Monolith/dev@43707 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 5c3bb1b157e01f1e6dc25055a608c39295badf82 --- .../web/services/local/UserResource.java | 2 + .../web/conf/NoUserInSessionFilter.java | 10 +- .../web/conf/PublicHomeCheckFilter.java | 117 ++++++++++++++++++ 3 files changed, 120 insertions(+), 9 deletions(-) create mode 100644 src/prerna/web/conf/PublicHomeCheckFilter.java diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index af43c6861..316b5962c 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -97,6 +97,7 @@ import prerna.io.connector.surveymonkey.MonkeyProfile; import prerna.io.connector.twitter.TwitterSearcher; import prerna.om.NLPDocumentInput; +import prerna.sablecc2.reactor.mgmt.MgmtUtil; import prerna.security.AbstractHttpHelper; import prerna.util.BeanFiller; import prerna.util.Constants; @@ -240,6 +241,7 @@ public Response logout(@PathParam("provider") String provider, @Context HttpServ if (provider.equalsIgnoreCase("ALL")) { removed = true; noUser = true; + thisUser.removeUserMemory(); } else { AuthProvider token = AuthProvider.valueOf(provider.toUpperCase()); String assetEngineId = null; diff --git a/src/prerna/web/conf/NoUserInSessionFilter.java b/src/prerna/web/conf/NoUserInSessionFilter.java index ee336c066..7e9028731 100644 --- a/src/prerna/web/conf/NoUserInSessionFilter.java +++ b/src/prerna/web/conf/NoUserInSessionFilter.java @@ -318,19 +318,11 @@ private void setInvalidEntryRedirect(ServletContext context, ServletRequest arg0 redirectUrl = fullUrl.substring(0, fullUrl.indexOf(contextPath) + contextPath.length()) + NO_USER_HTML; ((HttpServletResponse) arg1).sendRedirect(redirectUrl); } - } else if(canLoadUser()){ + } else { redirectUrl = redirectUrl + "#!/" + endpoint; String encodedRedirectUrl = Encode.forHtml(redirectUrl); ((HttpServletResponse) arg1).setHeader("redirect", encodedRedirectUrl); ((HttpServletResponse) arg1).sendError(302, "Need to redirect to " + encodedRedirectUrl); - }else // need to change this to the oom end point once neel has it - { - logger.info("Oops.. no more memory"); - redirectUrl = redirectUrl + "#!/" + endpoint; - String encodedRedirectUrl = Encode.forHtml(redirectUrl); - ((HttpServletResponse) arg1).setHeader("redirect", encodedRedirectUrl); - ((HttpServletResponse) arg1).sendError(302, "Need to redirect to " + encodedRedirectUrl); - } } diff --git a/src/prerna/web/conf/PublicHomeCheckFilter.java b/src/prerna/web/conf/PublicHomeCheckFilter.java new file mode 100644 index 000000000..c8e0bcf5e --- /dev/null +++ b/src/prerna/web/conf/PublicHomeCheckFilter.java @@ -0,0 +1,117 @@ +package prerna.web.conf; + +import java.io.File; +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.owasp.encoder.Encode; + +import prerna.auth.User; +import prerna.sablecc2.reactor.mgmt.MgmtUtil; +import prerna.util.Constants; +import prerna.util.DIHelper; +import prerna.util.Settings; +import prerna.util.Utility; + +public class PublicHomeCheckFilter implements Filter { + + public static final String NO_SUCH_APP = "/noSuchApp/"; + public static final String APP_NOT_PUBLISHED = "/appPublishFail/"; + + + @Override + public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { + + // check to see if the user is logged in + // if so pick the user object from session + // isolate the index of public_home/ to the next / + // see if this user has permission by using the engine map + // if yes allow + + ServletContext context = arg0.getServletContext(); + + + HttpSession session = ((HttpServletRequest) arg0).getSession(false); + String fullUrl = Utility.cleanHttpResponse(((HttpServletRequest) arg0).getRequestURL().toString()); + User user = null; + if (session != null) { + // System.out.println("Session ID >> " + session.getId()); + user = (User) session.getAttribute(Constants.SESSION_USER); + } + if(user != null) + { + String public_home = "public_home"; + if(DIHelper.getInstance().getProperty(Settings.PUBLIC_HOME) != null) + public_home = DIHelper.getInstance().getProperty(Settings.PUBLIC_HOME); + + + // this will be the deployment name of the app + // Context Path - this is already / Monolith + String contextPath = context.getContextPath() + "/" + public_home ; + String realPath = context.getRealPath(File.separator); + + // https://server/Monolith/public_home/engineid/resource + // plus 1 is the / on monolith + + String possibleEngineId = fullUrl.substring(fullUrl.indexOf(contextPath) + contextPath.length() + 1); + possibleEngineId = possibleEngineId.substring(0, possibleEngineId.indexOf("/")); + + String [] engTokens = possibleEngineId.split("__"); + if(engTokens != null && engTokens.length == 2) + { + boolean appAllowed = user.checkAppAccess(engTokens[0], engTokens[1]); + + if(appAllowed) + { + boolean mapComplete = Utility.getEngine(engTokens[1]).publish(realPath + File.separator + public_home, possibleEngineId); + if(mapComplete) + arg2.doFilter(arg0, arg1); + else + { + arg1.getWriter().write("Publish is not enabled on this application or there was an error publishing this application" ); +// String redirectUrl = fullUrl.substring(0, fullUrl.indexOf(contextPath) + contextPath.length()) + APP_NOT_PUBLISHED; +// ((HttpServletResponse) arg1).setHeader("redirect", redirectUrl); +// ((HttpServletResponse) arg1).sendError(302, "Need to redirect to " + redirectUrl); + return; + } + } + else + { + // send the user to some kind of page to say the user doesnt have access to this app + arg1.getWriter().write("App does not exist or You do not have acess to this application" ); +// String redirectUrl = fullUrl.substring(0, fullUrl.indexOf(contextPath) + contextPath.length()) + NO_SUCH_APP; +// ((HttpServletResponse) arg1).setHeader("redirect", redirectUrl); +// ((HttpServletResponse) arg1).sendError(302, "Need to redirect to " + redirectUrl); + return; + + } + } + } + + arg1.getWriter().write("You are trying to access an asset without being logged in, please log in first and then try again"); + return; + } + + @Override + public void destroy() { + // TODO Auto-generated method stub + + } + + + @Override + public void init(FilterConfig arg0) throws ServletException { + // TODO Auto-generated method stub + + } +} From d0bb0fa48bf305a25b425f5caea5a6018d9607b6 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 17 May 2021 23:58:50 +0000 Subject: [PATCH 0795/1906] UPDATE ::: Cleanup of the logic to check amount of memory left on the server git-svn-id: svn://107.170.10.188:8080/Monolith/dev@43718 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 2a3cc19b35cf55e9505f14a00264dc8c4ae21e06 --- src/prerna/web/conf/MemoryCheckFilter.java | 75 ++++++++++++++++------ 1 file changed, 54 insertions(+), 21 deletions(-) diff --git a/src/prerna/web/conf/MemoryCheckFilter.java b/src/prerna/web/conf/MemoryCheckFilter.java index 24e0ba2f9..6f27c3c02 100644 --- a/src/prerna/web/conf/MemoryCheckFilter.java +++ b/src/prerna/web/conf/MemoryCheckFilter.java @@ -24,25 +24,35 @@ public class MemoryCheckFilter implements Filter { private static final String NO_MORE_MEMORY = "/sessionCounterFail/"; + private static Boolean checkMem = null; + private static String memProfileSettings = null; + private static int memLimit = -1; + @Override public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { + if(checkMem == null) { + isCheckMem(); + } - //check to see if the user is logged in + if(!checkMem) { + arg2.doFilter(arg0, arg1); + return; + } + + // check to see if the user is logged in // if yes.. nothing to do // if not then try to see if we have memory // if not move the uset to oom page ServletContext context = arg0.getServletContext(); - HttpSession session = ((HttpServletRequest) arg0).getSession(false); String fullUrl = Utility.cleanHttpResponse(((HttpServletRequest) arg0).getRequestURL().toString()); User user = null; if (session != null) { - // System.out.println("Session ID >> " + session.getId()); user = (User) session.getAttribute(Constants.SESSION_USER); } - if(user == null && !fullUrl.endsWith(NO_MORE_MEMORY) && !canLoadUser() ) - { + + if(user == null && !fullUrl.endsWith(NO_MORE_MEMORY) && !canLoadUser()) { // this will be the deployment name of the app String contextPath = context.getContextPath(); @@ -58,29 +68,52 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 arg2.doFilter(arg0, arg1); } - public boolean canLoadUser() - { - boolean canLoad = true; - + /** + * Determine if we need to check memory + */ + private void isCheckMem() { String checkMemSettings = DIHelper.getInstance().getProperty(Settings.CHECK_MEM); - - boolean checkMem = checkMemSettings != null && checkMemSettings.equalsIgnoreCase("true"); - if(checkMem) - { - long freeMem = MgmtUtil.getFreeMemory(); - String memProfileSettings = DIHelper.getInstance().getProperty(Settings.MEM_PROFILE_SETTINGS); - - if(memProfileSettings.equalsIgnoreCase(Settings.CONSTANT_MEM)) - { + if(checkMemSettings != null) { + boolean checkMem = Boolean.parseBoolean(checkMemSettings); + if(checkMem) { String memLimitSettings = DIHelper.getInstance().getProperty(Settings.USER_MEM_LIMIT); - int limit = Integer.parseInt(memLimitSettings); - canLoad = limit < freeMem; + int memLimit = Integer.parseInt(memLimitSettings); + + MemoryCheckFilter.memProfileSettings = DIHelper.getInstance().getProperty(Settings.MEM_PROFILE_SETTINGS); + MemoryCheckFilter.memLimit = memLimit; } + MemoryCheckFilter.checkMem = checkMem; + return; + } + MemoryCheckFilter.checkMem = false; + } + + /** + * Determine if we have enough memory to allow login + * @return + */ + public synchronized boolean canLoadUser() { + /* + * Example RDF_Map.prop options + + # MEMORY stuff + CHECK_MEM True + MEM_PROFILE_SETTINGS CONSTANT + # specification in gigs + USER_MEM_LIMIT 2 + RESERVED_JAVA_MEMORY 12 + * + */ + + boolean canLoad = true; + + long freeMem = MgmtUtil.getFreeMemory(); + if(MemoryCheckFilter.memProfileSettings.equalsIgnoreCase(Settings.CONSTANT_MEM)) { + canLoad = MemoryCheckFilter.memLimit < freeMem; } return canLoad; } - @Override public void destroy() { From 845cca0ad9b73964e8620f84bbbbb79a0012781b Mon Sep 17 00:00:00 2001 From: pkapaleeswaran Date: Tue, 1 Jun 2021 15:22:37 +0000 Subject: [PATCH 0796/1906] Rehoming update. git-svn-id: svn://107.170.10.188:8080/Monolith/dev@43796 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 685b28e620f1e09be69af130639206e80ab0d1b2 --- src/prerna/semoss/web/services/local/AppResource.java | 7 +++++-- src/prerna/upload/ImageUploader.java | 9 ++++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/prerna/semoss/web/services/local/AppResource.java b/src/prerna/semoss/web/services/local/AppResource.java index a0f02806e..4f840960c 100644 --- a/src/prerna/semoss/web/services/local/AppResource.java +++ b/src/prerna/semoss/web/services/local/AppResource.java @@ -41,6 +41,7 @@ import prerna.engine.api.IEngine; import prerna.engine.impl.SmssUtilities; import prerna.nameserver.utility.MasterDatabaseUtility; +import prerna.util.AssetUtility; import prerna.util.Constants; import prerna.util.DIHelper; import prerna.util.Utility; @@ -394,7 +395,8 @@ protected File getAppImageFile(String app) { app = prop.getProperty(Constants.ENGINE_ALIAS); String baseFolder = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER); - String fileLocation = baseFolder + DIR_SEPARATOR + "db" + DIR_SEPARATOR + SmssUtilities.getUniqueName(app, appId) + DIR_SEPARATOR + "version"; + //String fileLocation = baseFolder + DIR_SEPARATOR + "db" + DIR_SEPARATOR + SmssUtilities.getUniqueName(app, appId) + DIR_SEPARATOR + "version"; + String fileLocation = AssetUtility.getAppAssetVersionFolder(app, appId); File f = findImageFile(fileLocation); if(f != null) { return f; @@ -482,7 +484,8 @@ private File getInsightImageFile(String appId, String id, String feUrl, String p String appName = prop.getProperty(Constants.ENGINE_ALIAS); String baseFolder = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER); - String fileLocation = baseFolder + DIR_SEPARATOR + "db" + DIR_SEPARATOR + SmssUtilities.getUniqueName(appName, appId) + DIR_SEPARATOR + "version"; + //String fileLocation = baseFolder + DIR_SEPARATOR + "db" + DIR_SEPARATOR + SmssUtilities.getUniqueName(appName, appId) + DIR_SEPARATOR + "version"; + String fileLocation = AssetUtility.getAppAssetVersionFolder(appName, appId); if(params != null && !params.isEmpty() && !params.equals("undefined")) { String encodedParams = Utility.encodeURIComponent(params); fileLocation = fileLocation + diff --git a/src/prerna/upload/ImageUploader.java b/src/prerna/upload/ImageUploader.java index 8cfbd37a1..9a597bd48 100644 --- a/src/prerna/upload/ImageUploader.java +++ b/src/prerna/upload/ImageUploader.java @@ -31,6 +31,7 @@ import prerna.cluster.util.ClusterUtil; import prerna.engine.impl.SmssUtilities; import prerna.nameserver.utility.MasterDatabaseUtility; +import prerna.util.AssetUtility; import prerna.util.Constants; import prerna.util.DIHelper; import prerna.util.Utility; @@ -262,7 +263,8 @@ private String getImageDir(String filePath, String appId, String appName) { if(ClusterUtil.IS_CLUSTER){ return ClusterUtil.IMAGES_FOLDER_PATH + DIR_SEPARATOR + "apps"; } - return filePath + DIR_SEPARATOR + SmssUtilities.getUniqueName(appName, appId) + DIR_SEPARATOR + "version"; + //return filePath + DIR_SEPARATOR + SmssUtilities.getUniqueName(appName, appId) + DIR_SEPARATOR + "version"; + return AssetUtility.getAppAssetVersionFolder(appName, appId); } private String getImageLoc(String filePath, String appId, String appName, FileItem imageFile){ @@ -356,7 +358,8 @@ public Response uploadInsightImage(@Context ServletContext context, @Context Htt // now that we have the app name // and the image file // we want to write it into the app location - String imageDir = filePath + DIR_SEPARATOR + SmssUtilities.getUniqueName(appName, appId) + DIR_SEPARATOR + "version" + DIR_SEPARATOR + insightId; + //String imageDir = filePath + DIR_SEPARATOR + SmssUtilities.getUniqueName(appName, appId) + DIR_SEPARATOR + "version" + DIR_SEPARATOR + insightId; + String imageDir = AssetUtility.getAppAssetVersionFolder(appName, appId) + DIR_SEPARATOR + insightId; File f = new File(imageDir); if (!f.exists()) { Boolean success = f.mkdirs(); @@ -454,7 +457,7 @@ public Response deleteInsightImage(@Context HttpServletRequest request) throws S // now that we have the app name // and the image file // we want to write it into the app location - String imageDir = filePath + DIR_SEPARATOR + SmssUtilities.getUniqueName(appName, appId) + DIR_SEPARATOR + "version" + DIR_SEPARATOR + insightId; + String imageDir = AssetUtility.getAppAssetVersionFolder(appName, appId) + DIR_SEPARATOR + insightId; File f = new File(Utility.normalizePath(imageDir)); if (f.exists()) { // find all the existing image files From 59e8f260492b2d22a25e8a879582583b87623e3a Mon Sep 17 00:00:00 2001 From: kunalppatel9 Date: Tue, 8 Jun 2021 16:29:49 +0000 Subject: [PATCH 0797/1906] BUGFIX ::: updating call as only app id is passed in, not app__app_id git-svn-id: svn://107.170.10.188:8080/Monolith/dev@43853 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: a7b4611fdc42358923efd429725aa90d9f287277 --- src/prerna/web/conf/PublicHomeCheckFilter.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/prerna/web/conf/PublicHomeCheckFilter.java b/src/prerna/web/conf/PublicHomeCheckFilter.java index c8e0bcf5e..9e5e32622 100644 --- a/src/prerna/web/conf/PublicHomeCheckFilter.java +++ b/src/prerna/web/conf/PublicHomeCheckFilter.java @@ -16,7 +16,10 @@ import org.owasp.encoder.Encode; +import com.google.common.base.Strings; + import prerna.auth.User; +import prerna.nameserver.utility.MasterDatabaseUtility; import prerna.sablecc2.reactor.mgmt.MgmtUtil; import prerna.util.Constants; import prerna.util.DIHelper; @@ -66,14 +69,17 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 String possibleEngineId = fullUrl.substring(fullUrl.indexOf(contextPath) + contextPath.length() + 1); possibleEngineId = possibleEngineId.substring(0, possibleEngineId.indexOf("/")); - String [] engTokens = possibleEngineId.split("__"); - if(engTokens != null && engTokens.length == 2) + // this is engine id ?! why are we splitting! + //String [] engTokens = possibleEngineId.split("__"); + + String alias = MasterDatabaseUtility.getEngineAliasForId(possibleEngineId); + if(!Strings.isNullOrEmpty(alias) && !Strings.isNullOrEmpty(possibleEngineId)) { - boolean appAllowed = user.checkAppAccess(engTokens[0], engTokens[1]); + boolean appAllowed = user.checkAppAccess(alias, possibleEngineId); if(appAllowed) { - boolean mapComplete = Utility.getEngine(engTokens[1]).publish(realPath + File.separator + public_home, possibleEngineId); + boolean mapComplete = Utility.getEngine(possibleEngineId).publish(realPath + File.separator + public_home, possibleEngineId); if(mapComplete) arg2.doFilter(arg0, arg1); else From cad77c6267963a7d79b5033b13416dee7cbfda9b Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 16 Jun 2021 12:07:56 +0000 Subject: [PATCH 0798/1906] UPDATE ::: Adding comments to make RDF_Map.prop one time parsing logic more clear git-svn-id: svn://107.170.10.188:8080/Monolith/dev@43936 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 18e311da93cd187ac671a3010935745255816002 --- src/prerna/web/conf/MemoryCheckFilter.java | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/prerna/web/conf/MemoryCheckFilter.java b/src/prerna/web/conf/MemoryCheckFilter.java index 6f27c3c02..9e4be9a75 100644 --- a/src/prerna/web/conf/MemoryCheckFilter.java +++ b/src/prerna/web/conf/MemoryCheckFilter.java @@ -30,6 +30,13 @@ public class MemoryCheckFilter implements Filter { @Override public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { + /* + * This beginning part is so we dont keep parsing RDF_Map.prop to see if the check memory is enabled or not + * So we will look to see if the Boolean (object class) is initiated + * If not, we will determine its value (true/false) from the isCheckMem() method + * If the check memory is false, then we continue down the filter chain + */ + if(checkMem == null) { isCheckMem(); } @@ -39,10 +46,13 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 return; } - // check to see if the user is logged in - // if yes.. nothing to do - // if not then try to see if we have memory - // if not move the uset to oom page + /* + * User has enabled the memory check filter + * Check to see if the user is logged in + * If yes.. nothing to do + * If not then try to see if we have memory + * If not move the uset to oom page + */ ServletContext context = arg0.getServletContext(); HttpSession session = ((HttpServletRequest) arg0).getSession(false); From 2b0014e966d014b5e4fcfdd6e3a9d0c5580f1598 Mon Sep 17 00:00:00 2001 From: kunalppatel9 Date: Wed, 16 Jun 2021 13:49:34 +0000 Subject: [PATCH 0799/1906] BUGFIX ::: changing github-api jar to updated version due to missing artifacts git-svn-id: svn://107.170.10.188:8080/Monolith/dev@43939 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: fced73b72982d92d9805710aab855e5686ac099d --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ac472c0c8..a5ea6bd5b 100644 --- a/pom.xml +++ b/pom.xml @@ -1498,7 +1498,7 @@ org.kohsuke github-api - 1.86 + 1.131 org.eclipse.mylyn.github From 89d6c38d58eb529823d0ee92fcded002167f8b63 Mon Sep 17 00:00:00 2001 From: pkapaleeswaran Date: Sat, 26 Jun 2021 13:36:51 +0000 Subject: [PATCH 0800/1906] BUGFIX::Fixing the issue for following Symbolic Links. git-svn-id: svn://107.170.10.188:8080/Monolith/dev@44073 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: a8548c55a17ab23ae03677de21f389ddfece3ddc --- src/prerna/web/conf/PublicHomeCheckFilter.java | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/prerna/web/conf/PublicHomeCheckFilter.java b/src/prerna/web/conf/PublicHomeCheckFilter.java index 9e5e32622..cfec28baf 100644 --- a/src/prerna/web/conf/PublicHomeCheckFilter.java +++ b/src/prerna/web/conf/PublicHomeCheckFilter.java @@ -53,14 +53,15 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 } if(user != null) { - String public_home = "public_home"; + String public_home = "/public_home"; if(DIHelper.getInstance().getProperty(Settings.PUBLIC_HOME) != null) public_home = DIHelper.getInstance().getProperty(Settings.PUBLIC_HOME); + //public_home = ""; // this will be the deployment name of the app // Context Path - this is already / Monolith - String contextPath = context.getContextPath() + "/" + public_home ; + String contextPath = context.getContextPath() + public_home ; String realPath = context.getRealPath(File.separator); // https://server/Monolith/public_home/engineid/resource @@ -77,11 +78,19 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 { boolean appAllowed = user.checkAppAccess(alias, possibleEngineId); + File phomeFile = new File(realPath + public_home); // try to create the public home from scratch + + if(!phomeFile.exists()) + phomeFile.mkdir(); + if(appAllowed) { - boolean mapComplete = Utility.getEngine(possibleEngineId).publish(realPath + File.separator + public_home, possibleEngineId); + boolean mapComplete = Utility.getEngine(possibleEngineId).publish(realPath + public_home, possibleEngineId); if(mapComplete) + { arg2.doFilter(arg0, arg1); + return; + } else { arg1.getWriter().write("Publish is not enabled on this application or there was an error publishing this application" ); From 33e8a6594f9496845e834b999286e8134bae9dbe Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 22 Jul 2021 12:27:33 +0000 Subject: [PATCH 0801/1906] UPDATE ::: Adding in additional logic to redirect to a specific url based on being logged in already git-svn-id: svn://107.170.10.188:8080/Monolith/dev@44209 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 5a3299fb589c5b9e0a0fcbd71920b26460785087 --- .../web/services/saml/IdpSSOServlet.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/prerna/semoss/web/services/saml/IdpSSOServlet.java b/src/prerna/semoss/web/services/saml/IdpSSOServlet.java index 44be1206e..d0dd62bed 100644 --- a/src/prerna/semoss/web/services/saml/IdpSSOServlet.java +++ b/src/prerna/semoss/web/services/saml/IdpSSOServlet.java @@ -8,10 +8,14 @@ import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import prerna.auth.AuthProvider; +import prerna.auth.User; +import prerna.util.Constants; import prerna.web.conf.util.SSOUtil; /** @@ -33,6 +37,21 @@ public IdpSSOServlet() { * does a redirect to the IDP. */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + // if already logged in + // then nothing to do, redirect + if(request.getSession(false) != null) { + HttpSession session = request.getSession(false); + User user = ((User) session.getAttribute(Constants.SESSION_USER)); + if(user != null && user.getAccessToken(AuthProvider.SAML) != null) { + String redirect = request.getParameter("redirect"); + if(redirect != null && !(redirect = redirect.trim()).isEmpty()) { + response.setStatus(302); + response.sendRedirect(redirect); + return; + } + } + } + logger.info("Starting IDP initiated SSO."); SSOUtil util = SSOUtil.getInstance(); util.setSSODeployURI((request).getRequestURI()); From ededcc030a0ea0dfba2cdec8181db4f67f9b43b8 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 22 Jul 2021 16:08:51 +0000 Subject: [PATCH 0802/1906] UPDATE ::: Adding redirect logic for specific pages after the login occurs git-svn-id: svn://107.170.10.188:8080/Monolith/dev@44213 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 5aa4fb24eb8803e007fe220d20de75fa75b1d738 --- .../semoss/web/services/saml/IdpSSOServlet.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/prerna/semoss/web/services/saml/IdpSSOServlet.java b/src/prerna/semoss/web/services/saml/IdpSSOServlet.java index d0dd62bed..207772ec0 100644 --- a/src/prerna/semoss/web/services/saml/IdpSSOServlet.java +++ b/src/prerna/semoss/web/services/saml/IdpSSOServlet.java @@ -39,11 +39,11 @@ public IdpSSOServlet() { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // if already logged in // then nothing to do, redirect + String redirect = request.getParameter("redirect"); if(request.getSession(false) != null) { - HttpSession session = request.getSession(false); + HttpSession session = request.getSession(); User user = ((User) session.getAttribute(Constants.SESSION_USER)); if(user != null && user.getAccessToken(AuthProvider.SAML) != null) { - String redirect = request.getParameter("redirect"); if(redirect != null && !(redirect = redirect.trim()).isEmpty()) { response.setStatus(302); response.sendRedirect(redirect); @@ -51,7 +51,14 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) t } } } - + + // if we are specifying the redirect + // set it here so after the login we redirect to the correct page + if(redirect != null && !(redirect = redirect.trim()).isEmpty()) { + HttpSession session = request.getSession(); + session.setAttribute(SSOUtil.SAML_REDIRECT_KEY, redirect); + } + logger.info("Starting IDP initiated SSO."); SSOUtil util = SSOUtil.getInstance(); util.setSSODeployURI((request).getRequestURI()); From 6da3f180a7c0ca65f4f7a3b128b13e4e1e16bc44 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 22 Jul 2021 18:12:38 +0000 Subject: [PATCH 0803/1906] UPDATE ::: Switching the elasticsearch version to 3.9.1 git-svn-id: svn://107.170.10.188:8080/Monolith/dev@44214 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: bb182a2e5427df8074039e1d0dd3a4414a9f69ea --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index a5ea6bd5b..b7329a477 100644 --- a/pom.xml +++ b/pom.xml @@ -1966,7 +1966,7 @@ org.elasticsearch.plugin x-pack-sql-jdbc - 7.11.2 + 7.9.1 From 8591343add316bf514acb223863e24bc5275f22a Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 23 Jul 2021 14:17:10 +0000 Subject: [PATCH 0804/1906] UPDATE ::: Pushing aws elastic search jdbc driver git-svn-id: svn://107.170.10.188:8080/Monolith/dev@44222 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 16336e0b4e2df391e3e26b23e514a726231186e3 --- pom.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pom.xml b/pom.xml index b7329a477..434b29fcd 100644 --- a/pom.xml +++ b/pom.xml @@ -1968,6 +1968,12 @@ x-pack-sql-jdbc 7.9.1 + + + com.amazon.opendistroforelasticsearch.client + opendistro-sql-jdbc + 1.11.0.0 + From 646ed2d76927f05951acc4d3f1b0af8e4a990be4 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 23 Jul 2021 14:24:57 +0000 Subject: [PATCH 0805/1906] UPDATE ::: Allowing cacId to come from SAML auth provider in addition to CAC auth provider git-svn-id: svn://107.170.10.188:8080/Monolith/dev@44223 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 6dd5bfe2d0f6d7645fe855b3dd05d58c8ea61deb --- src/prerna/semoss/web/form/FormResource.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/prerna/semoss/web/form/FormResource.java b/src/prerna/semoss/web/form/FormResource.java index 94f3d8cff..8a76e6126 100644 --- a/src/prerna/semoss/web/form/FormResource.java +++ b/src/prerna/semoss/web/form/FormResource.java @@ -240,7 +240,12 @@ private String getCacId(@Context HttpServletRequest request) throws IOException try { HttpSession session = ((HttpServletRequest)request).getSession(false); User user = (User) session.getAttribute(Constants.SESSION_USER); - x509Id = user.getAccessToken(AuthProvider.CAC).getId(); + if(user.getAccessToken(AuthProvider.CAC) != null) { + x509Id = user.getAccessToken(AuthProvider.CAC).getId(); + } else { + // if not CAC - we are using SMAL + x509Id = user.getAccessToken(AuthProvider.SAML).getId(); + } } catch(Exception e) { throw new IOException("Could not identify user"); } From 1142c5563f3751379fbb311c1005cd576fde52ba Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 26 Jul 2021 18:49:10 +0000 Subject: [PATCH 0806/1906] WARNING ::: THIS WILL BE SLIGHTLY EXPERIMENTAL - DO NOT UPDATE IF YOU PLAN ON DEMOING. REQUIERES UPDATE FROM FE AS WELL. UPDATE ::: Pushing database/project refactor into dev branch. git-svn-id: svn://107.170.10.188:8080/Monolith/dev@44247 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 18aeb612ad730bf504a837d89111d4b32ac04745 --- .../cluster/RawSelectWrapperService.java | 12 +- .../semoss/web/app/MonolithApplication.java | 7 + src/prerna/semoss/web/form/FormResource.java | 4 +- .../web/services/local/AppResource.java | 426 +----------- .../web/services/local/DataframeResource.java | 32 +- .../web/services/local/EngineResource.java | 29 +- .../local/ExecuteInsightResource.java | 22 +- .../semoss/web/services/local/NameServer.java | 65 +- .../web/services/local/ProjectResource.java | 607 ++++++++++++++++++ .../web/services/local/UserResource.java | 30 +- .../auth/AdminAppAuthorizationResource.java | 18 +- .../AdminInsightAuthorizationResource.java | 126 ++-- .../AdminProjectAuthorizationResource.java | 464 +++++++++++++ .../local/auth/AppAuthorizationResource.java | 12 +- .../auth/InsightAuthorizationResource.java | 75 +-- .../auth/ProjectAuthorizationResource.java | 446 +++++++++++++ .../services/remote/EngineRemoteResource.java | 14 +- src/prerna/upload/FileUploader.java | 4 +- src/prerna/upload/ImageUploader.java | 416 +++++++++--- src/prerna/web/conf/DBLoader.java | 23 +- .../web/conf/PublicHomeCheckFilter.java | 10 +- 21 files changed, 2105 insertions(+), 737 deletions(-) create mode 100644 src/prerna/semoss/web/services/local/ProjectResource.java create mode 100644 src/prerna/semoss/web/services/local/auth/AdminProjectAuthorizationResource.java create mode 100644 src/prerna/semoss/web/services/local/auth/ProjectAuthorizationResource.java diff --git a/src/prerna/cluster/RawSelectWrapperService.java b/src/prerna/cluster/RawSelectWrapperService.java index 23729120d..1594e43ce 100644 --- a/src/prerna/cluster/RawSelectWrapperService.java +++ b/src/prerna/cluster/RawSelectWrapperService.java @@ -103,13 +103,13 @@ private boolean removeRawSelectWrapper(String appId, String wrapperId) { private IEngine getEngine(String appId) { IEngine engine = null; - if (appId.endsWith("_InsightsRDBMS")) { - String parentAppId = appId.replace("_InsightsRDBMS", ""); - IEngine parentEngine = Utility.getEngine(parentAppId); - engine = parentEngine.getInsightDatabase(); - } else { +// if (appId.endsWith("_InsightsRDBMS")) { +// String parentAppId = appId.replace("_InsightsRDBMS", ""); +// IEngine parentEngine = Utility.getEngine(parentAppId); +// engine = parentEngine.getInsightDatabase(); +// } else { engine = Utility.getEngine(appId); - } +// } return engine; } diff --git a/src/prerna/semoss/web/app/MonolithApplication.java b/src/prerna/semoss/web/app/MonolithApplication.java index 07bd54e38..aa6140e78 100644 --- a/src/prerna/semoss/web/app/MonolithApplication.java +++ b/src/prerna/semoss/web/app/MonolithApplication.java @@ -40,6 +40,7 @@ import prerna.semoss.web.services.local.AuthorizationResource; import prerna.semoss.web.services.local.ExecuteInsightResource; import prerna.semoss.web.services.local.NameServer; +import prerna.semoss.web.services.local.ProjectResource; import prerna.semoss.web.services.local.SchedulerResource; import prerna.semoss.web.services.local.SessionResource; import prerna.semoss.web.services.local.ShareInsightResource; @@ -47,9 +48,11 @@ import prerna.semoss.web.services.local.UserResource; import prerna.semoss.web.services.local.auth.AdminAppAuthorizationResource; import prerna.semoss.web.services.local.auth.AdminInsightAuthorizationResource; +import prerna.semoss.web.services.local.auth.AdminProjectAuthorizationResource; import prerna.semoss.web.services.local.auth.AdminUserAuthorizationResource; import prerna.semoss.web.services.local.auth.AppAuthorizationResource; import prerna.semoss.web.services.local.auth.InsightAuthorizationResource; +import prerna.semoss.web.services.local.auth.ProjectAuthorizationResource; import prerna.upload.FileUploader; import prerna.upload.ImageUploader; @@ -63,15 +66,18 @@ public MonolithApplication() { singletons.add(new UserResource()); singletons.add(new NameServer()); singletons.add(new AppResource()); + singletons.add(new ProjectResource()); singletons.add(new FileUploader()); singletons.add(new ImageUploader()); singletons.add(new SessionResource()); // authorization resources singletons.add(new AuthorizationResource()); singletons.add(new AppAuthorizationResource()); + singletons.add(new ProjectAuthorizationResource()); singletons.add(new InsightAuthorizationResource()); // admin authorization singletons.add(new AdminAppAuthorizationResource()); + singletons.add(new AdminProjectAuthorizationResource()); singletons.add(new AdminInsightAuthorizationResource()); singletons.add(new AdminUserAuthorizationResource()); // insight execution @@ -84,6 +90,7 @@ public MonolithApplication() { singletons.add(new RawSelectWrapperService()); // legacy forms - still used in production - RDF specific singletons.add(new FormResource()); + } @Override diff --git a/src/prerna/semoss/web/form/FormResource.java b/src/prerna/semoss/web/form/FormResource.java index 8a76e6126..4e42463f2 100644 --- a/src/prerna/semoss/web/form/FormResource.java +++ b/src/prerna/semoss/web/form/FormResource.java @@ -145,7 +145,7 @@ public Response renameInstance(@Context HttpServletRequest request, MultivaluedM // log the operation logger.info(ResourceUtility.getLogMessage(request, request.getSession(), cacId, "is renaming " + origUri + " to " + newUri)); - IEngine coreEngine = Utility.getEngine(MasterDatabaseUtility.testEngineIdIfAlias(dbName)); + IEngine coreEngine = Utility.getEngine(MasterDatabaseUtility.testDatabaseIdIfAlias(dbName)); AbstractFormBuilder formbuilder = FormFactory.getFormBuilder(coreEngine); formbuilder.modifyInstanceValue(origUri, newUri, deleteInstanceBoolean); return WebUtility.getResponse("success", 200); @@ -177,7 +177,7 @@ public Response certifyInstance(@Context HttpServletRequest request, Multivalued return WebUtility.getResponse(err, 400); } - IEngine coreEngine = Utility.getEngine(MasterDatabaseUtility.testEngineIdIfAlias(dbName)); + IEngine coreEngine = Utility.getEngine(MasterDatabaseUtility.testDatabaseIdIfAlias(dbName)); AbstractFormBuilder formbuilder = FormFactory.getFormBuilder(coreEngine); formbuilder.setUser(cacId); formbuilder.certifyInstance(instanceType, instanceName); diff --git a/src/prerna/semoss/web/services/local/AppResource.java b/src/prerna/semoss/web/services/local/AppResource.java index 4f840960c..d78d97d7b 100644 --- a/src/prerna/semoss/web/services/local/AppResource.java +++ b/src/prerna/semoss/web/services/local/AppResource.java @@ -4,8 +4,6 @@ import java.io.FileFilter; import java.io.FileInputStream; import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Paths; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -17,7 +15,6 @@ import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; -import javax.ws.rs.QueryParam; import javax.ws.rs.core.Context; import javax.ws.rs.core.EntityTag; import javax.ws.rs.core.MediaType; @@ -25,9 +22,7 @@ import javax.ws.rs.core.Response; import javax.ws.rs.core.Response.ResponseBuilder; -import org.apache.commons.io.FileUtils; import org.apache.commons.io.FilenameUtils; -import org.apache.commons.io.IOUtils; import org.apache.commons.io.filefilter.WildcardFileFilter; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -35,13 +30,10 @@ import prerna.auth.User; import prerna.auth.utils.AbstractSecurityUtils; import prerna.auth.utils.SecurityAppUtils; -import prerna.auth.utils.SecurityInsightUtils; import prerna.auth.utils.SecurityQueryUtils; import prerna.cluster.util.ClusterUtil; -import prerna.engine.api.IEngine; import prerna.engine.impl.SmssUtilities; import prerna.nameserver.utility.MasterDatabaseUtility; -import prerna.util.AssetUtility; import prerna.util.Constants; import prerna.util.DIHelper; import prerna.util.Utility; @@ -52,21 +44,18 @@ public class AppResource { private static final String DIR_SEPARATOR = java.nio.file.FileSystems.getDefault().getSeparator(); - private static String defaultEmbedLogo = null; - private static boolean noLogo = false; private static final Logger logger = LogManager.getLogger(AppResource.class); - private static final String STACKTRACE = "StackTrace: "; private boolean canAccessApp(User user, String appId) throws IllegalAccessException { if(AbstractSecurityUtils.securityEnabled()) { - appId = SecurityQueryUtils.testUserEngineIdForAlias(user, appId); - if(!SecurityAppUtils.userCanViewEngine(user, appId)) { + appId = SecurityQueryUtils.testUserDatabaseIdForAlias(user, appId); + if(!SecurityAppUtils.userCanViewDatabase(user, appId)) { throw new IllegalAccessException("App " + appId + " does not exist or user does not have access to database"); } } else { - appId = MasterDatabaseUtility.testEngineIdIfAlias(appId); - if(!MasterDatabaseUtility.getAllEngineIds().contains(appId)) { + appId = MasterDatabaseUtility.testDatabaseIdIfAlias(appId); + if(!MasterDatabaseUtility.getAllDatabaseIds().contains(appId)) { throw new IllegalAccessException("App " + appId + " does not exist"); } } @@ -74,248 +63,6 @@ private boolean canAccessApp(User user, String appId) throws IllegalAccessExcept return true; } - private boolean canAccessInsight(User user, String appId, String insightId) throws IllegalAccessException { - if(AbstractSecurityUtils.securityEnabled()) { - appId = SecurityQueryUtils.testUserEngineIdForAlias(user, appId); - if(!SecurityInsightUtils.userCanViewInsight(user, appId, insightId)) { - throw new IllegalAccessException("Insight does not exist or user does not have access to view"); - } - } else { - appId = MasterDatabaseUtility.testEngineIdIfAlias(appId); - if(!MasterDatabaseUtility.getAllEngineIds().contains(appId)) { - throw new IllegalAccessException("App " + appId + " does not exist"); - } - } - - return true; - } - - /** - * Utility method to get the app only if person has access to it - * @param user - * @param appId - * @return - * @throws IllegalAccessException - */ - private IEngine getApp(User user, String appId) throws IllegalAccessException { - canAccessApp(user, appId); - return Utility.getEngine(appId); - } - - /////////////////////////////////////////////////////////////////////////////////////////////////////// - /////////////////////////////////////////////////////////////////////////////////////////////////////// - /////////////////////////////////////////////////////////////////////////////////////////////////////// - /////////////////////////////////////////////////////////////////////////////////////////////////////// - /////////////////////////////////////////////////////////////////////////////////////////////////////// - - /* - * Code below is around retrieving app assets - */ - - @GET - @Path("/landing") - @Produces(MediaType.TEXT_HTML) - public Response getAppLandingPage(@Context final Request coreRequest, @Context HttpServletRequest request, @PathParam("appId") String appId) { - User user = null; - try { - user = ResourceUtility.getUser(request); - } catch (IllegalAccessException e) { - Map errorMap = new HashMap<>(); - errorMap.put("error", "User session is invalid"); - return WebUtility.getResponse(errorMap, 401); - } - try { - canAccessApp(user, appId); - } catch (IllegalAccessException e) { - Map errorMap = new HashMap<>(); - errorMap.put("error", e.getMessage()); - return WebUtility.getResponse(errorMap, 401); - } - - String propFileLoc = DIHelper.getInstance().getProperty(appId + "_" + Constants.STORE); - Properties prop = Utility.loadProperties(propFileLoc); - String appName = prop.getProperty(Constants.ENGINE_ALIAS); - - String baseFolder = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER); - String fileLocation = baseFolder + DIR_SEPARATOR + "db" + DIR_SEPARATOR + SmssUtilities.getUniqueName(appName, appId) + DIR_SEPARATOR + "version/assets/landing.html"; - File file = new File(fileLocation); - if(file != null && file.exists()) { - try { - String html = FileUtils.readFileToString(file, "UTF-8"); - - // want to cache this on browser if user has access -// CacheControl cc = new CacheControl(); -// cc.setMaxAge(1); -// cc.setPrivate(true); - EntityTag etag = new EntityTag(Integer.toString(html.hashCode())); - ResponseBuilder builder = coreRequest.evaluatePreconditions(etag); - - // cached resource did not change - if(builder != null) { - return builder.build(); - } - - return Response.status(200).entity(html) -// .cacheControl(cc) - .tag(etag) -// .lastModified(new Date(file.lastModified())) - .build(); - } catch (IOException e) { - Map errorMap = new HashMap<>(); - errorMap.put("errorMessage", "Unable to load landing html file"); - return WebUtility.getResponse(errorMap, 404); - } - } else { - Map errorMap = new HashMap<>(); - errorMap.put("errorMessage", "No custom landing page found"); - return WebUtility.getResponse(errorMap, 404); - } - } - - @GET - @Path("/downloadAppAsset/{relPath}") - @Produces({MediaType.TEXT_HTML, MediaType.APPLICATION_OCTET_STREAM}) - public Response getAppFile(@Context final Request coreRequest, @Context HttpServletRequest request, @PathParam("appId") String appId, @PathParam("relPath") String relPath) { - User user = null; - try { - user = ResourceUtility.getUser(request); - } catch (IllegalAccessException e) { - Map errorMap = new HashMap<>(); - errorMap.put("error", "User session is invalid"); - return WebUtility.getResponse(errorMap, 401); - } - try { - canAccessApp(user, appId); - } catch (IllegalAccessException e) { - Map errorMap = new HashMap<>(); - errorMap.put("error", e.getMessage()); - return WebUtility.getResponse(errorMap, 401); - } - - String propFileLoc = DIHelper.getInstance().getProperty(appId + "_" + Constants.STORE); - Properties prop = Utility.loadProperties(propFileLoc); - String appName = prop.getProperty(Constants.ENGINE_ALIAS); - - String baseFolder = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER); - String fileLocation = baseFolder + DIR_SEPARATOR + "db" + DIR_SEPARATOR + SmssUtilities.getUniqueName(appName, appId) + DIR_SEPARATOR + "version/assets/" + relPath; - File file = new File(fileLocation); - if(file != null && file.exists()) { - try { - String contents = FileUtils.readFileToString(file, "UTF-8"); - - // want to cache this on browser if user has access -// CacheControl cc = new CacheControl(); -// cc.setMaxAge(1); -// cc.setPrivate(true); - EntityTag etag = new EntityTag(Integer.toString(contents.hashCode())); - ResponseBuilder builder = coreRequest.evaluatePreconditions(etag); - - // cached resource did not change - if(builder != null) { - return builder.build(); - } - - return Response.status(200).entity(contents) -// .cacheControl(cc) - .tag(etag) -// .lastModified(new Date(file.lastModified())) - .build(); - } catch (IOException e) { - Map errorMap = new HashMap<>(); - errorMap.put("errorMessage", "Unable to load file"); - return WebUtility.getResponse(errorMap, 404); - } - } else { - Map errorMap = new HashMap<>(); - errorMap.put("errorMessage", "No file found"); - return WebUtility.getResponse(errorMap, 404); - } - } - - @GET - @Path("/embedLogo") - @Produces({MediaType.TEXT_HTML, MediaType.APPLICATION_OCTET_STREAM}) - public Response getEmbedUrl(@Context final Request coreRequest, @Context HttpServletRequest request, @PathParam("appId") String appId, @QueryParam("insightId") String insightId) { - User user = null; - if(AbstractSecurityUtils.securityEnabled()) { - try { - user = ResourceUtility.getUser(request); - } catch (IllegalAccessException e) { - Map errorMap = new HashMap<>(); - errorMap.put("error", "User session is invalid"); - return WebUtility.getResponse(errorMap, 401); - } - try { - canAccessApp(user, appId); - } catch (IllegalAccessException e) { - Map errorMap = new HashMap<>(); - errorMap.put("error", e.getMessage()); - return WebUtility.getResponse(errorMap, 401); - } - } - - //TODO: ALLOW APP SPECIFIC EMBED IMAGES - //TODO: ALLOW INSIGHT SPECIFIC EMBED IMAGES - - String embedLogo = getEmbedLogo(); - if(AppResource.noLogo) { - Map errorMap = new HashMap<>(); - errorMap.put("error", "no defualt logo"); - return WebUtility.getResponse(errorMap, 404); - } - - File file = new File(embedLogo); - if(file != null && file.exists()) { - try { - String contents = new String(Files.readAllBytes(Paths.get(file.getAbsolutePath()))); - - // want to cache this on browser if user has access -// CacheControl cc = new CacheControl(); -// cc.setMaxAge(1); -// cc.setPrivate(true); - EntityTag etag = new EntityTag(Integer.toString(contents.hashCode())); - ResponseBuilder builder = coreRequest.evaluatePreconditions(etag); - - // cached resource did not change - if(builder != null) { - return builder.build(); - } - - String mimeType = Files.probeContentType(file.toPath()); - return Response.status(200).entity(contents).type(mimeType) -// .cacheControl(cc) - .tag(etag) -// .lastModified(new Date(file.lastModified())) - .build(); - } catch (IOException e) { - Map errorMap = new HashMap<>(); - errorMap.put("errorMessage", "Unable to load file"); - return WebUtility.getResponse(errorMap, 400); - } - } else { - Map errorMap = new HashMap<>(); - errorMap.put("errorMessage", "Default logo file not found"); - return WebUtility.getResponse(errorMap, 404); - } - } - - private static String getEmbedLogo() { - if(AppResource.defaultEmbedLogo == null) { - String embedFileName = DIHelper.getInstance().getProperty(Constants.EMBED_URL_LOGO); - if(embedFileName == null || embedFileName.equalsIgnoreCase("NONE")) { - AppResource.noLogo = true; - AppResource.defaultEmbedLogo = "NONE"; - } else { - String baseFolder = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER); - String embedFolder = baseFolder + DIR_SEPARATOR + "images" + DIR_SEPARATOR + "embed"; - AppResource.defaultEmbedLogo = embedFolder + DIR_SEPARATOR + embedFileName; - AppResource.noLogo = false; - } - } - return AppResource.defaultEmbedLogo; - } - - /////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -382,11 +129,11 @@ public Response downloadAppImage(@Context final Request coreRequest, @Context Ht * @return */ protected File getAppImageFile(String app) { - String appId = MasterDatabaseUtility.testEngineIdIfAlias(app); + String appId = MasterDatabaseUtility.testDatabaseIdIfAlias(app); if(ClusterUtil.IS_CLUSTER){ - return ClusterUtil.getImage(app); + return ClusterUtil.getDatabaseImage(app); } - String propFileLoc = DIHelper.getInstance().getProperty(appId + "_" + Constants.STORE); + String propFileLoc = (String) DIHelper.getInstance().getDbProperty(appId + "_" + Constants.STORE); if(propFileLoc == null && !app.equals("NEWSEMOSSAPP")) { String imageDir = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER) + "/images/stock/"; return new File(imageDir + "color-logo.png"); @@ -395,8 +142,9 @@ protected File getAppImageFile(String app) { app = prop.getProperty(Constants.ENGINE_ALIAS); String baseFolder = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER); - //String fileLocation = baseFolder + DIR_SEPARATOR + "db" + DIR_SEPARATOR + SmssUtilities.getUniqueName(app, appId) + DIR_SEPARATOR + "version"; - String fileLocation = AssetUtility.getAppAssetVersionFolder(app, appId); + String fileLocation = baseFolder + DIR_SEPARATOR + Constants.DB_FOLDER + DIR_SEPARATOR + + SmssUtilities.getUniqueName(app, appId) + DIR_SEPARATOR + "app_root" + DIR_SEPARATOR + "version"; + //String fileLocation = AssetUtility.getAppAssetVersionFolder(app, appId); File f = findImageFile(fileLocation); if(f != null) { return f; @@ -420,116 +168,6 @@ protected File getAppImageFile(String app) { } } - @GET - @Path("/insightImage/download") - @Produces({MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_SVG_XML}) - public Response downloadInsightImage(@Context final Request coreRequest, @Context HttpServletRequest request, @PathParam("appId") String appId, @QueryParam("rdbmsId") String id, @QueryParam("params") String params) { - String sessionId = null; - if(AbstractSecurityUtils.securityEnabled()) { - User user = null; - try { - user = ResourceUtility.getUser(request); - } catch (IllegalAccessException e) { - Map errorMap = new HashMap<>(); - errorMap.put("error", "User session is invalid"); - return WebUtility.getResponse(errorMap, 401); - } - try { - canAccessInsight(user, appId, id); - } catch (IllegalAccessException e) { - Map errorMap = new HashMap<>(); - errorMap.put("error", e.getMessage()); - return WebUtility.getResponse(errorMap, 401); - } - - sessionId = request.getSession(false).getId(); - } - - File exportFile = getInsightImageFile(appId, id, request.getHeader("Referer"), params, sessionId); - if(exportFile != null && exportFile.exists()) { - String exportName = appId + "_Image." + FilenameUtils.getExtension(exportFile.getAbsolutePath()); - // want to cache this on browser if user has access -// CacheControl cc = new CacheControl(); -// cc.setMaxAge(86400); -// cc.setPrivate(true); -// cc.setMustRevalidate(true); - EntityTag etag = new EntityTag(Integer.toString(exportFile.hashCode())); - ResponseBuilder builder = coreRequest.evaluatePreconditions(etag); - - // cached resource did not change - if(builder != null) { - return builder.build(); - } - - return Response.status(200).entity(exportFile).header("Content-Disposition", "attachment; filename=" + exportName) -// .cacheControl(cc) - .tag(etag) -// .lastModified(new Date(exportFile.lastModified())) - .build(); - } else { - Map errorMap = new HashMap<>(); - errorMap.put("errorMessage", "Error sending image file"); - return WebUtility.getResponse(errorMap, 404); - } - } - - /** - * Use to find the file for the image - * @param app - * @return - */ - private File getInsightImageFile(String appId, String id, String feUrl, String params, String sessionId) { - String propFileLoc = DIHelper.getInstance().getProperty(appId + "_" + Constants.STORE); - Properties prop = Utility.loadProperties(propFileLoc); - String appName = prop.getProperty(Constants.ENGINE_ALIAS); - - String baseFolder = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER); - //String fileLocation = baseFolder + DIR_SEPARATOR + "db" + DIR_SEPARATOR + SmssUtilities.getUniqueName(appName, appId) + DIR_SEPARATOR + "version"; - String fileLocation = AssetUtility.getAppAssetVersionFolder(appName, appId); - if(params != null && !params.isEmpty() && !params.equals("undefined")) { - String encodedParams = Utility.encodeURIComponent(params); - fileLocation = fileLocation + - DIR_SEPARATOR + id + - DIR_SEPARATOR + "params" + - DIR_SEPARATOR + encodedParams; - } else { - fileLocation = fileLocation + DIR_SEPARATOR + id; - } - File f = findImageFile(fileLocation); - if(f != null && f.exists()) { - return f; - } else { - // try making the image - // JK! this is super annoying when running a bunch of - // insights at the same time which is what happens - // currently on the app home page -// if (!ClusterUtil.IS_CLUSTER) { -// if(feUrl != null) { -// try { -// ImageCaptureReactor.runImageCapture(feUrl, appId, id, params, sessionId); -// } -// catch(Exception | NoSuchMethodError er) { -// //Image Capture will not run. No image exists nor will be made. The exception kills the rest. -// // return stock image -// er.printStackTrace(); -// f = AbstractSecurityUtils.getStockImage(appId, id); -// return f; -// } -// } -// } - // the image capture ran - // let us try to see if there is a file now... - f = findImageFile(fileLocation); - if(f != null && f.exists()) { - return f; - } else { - // return stock image - f = AbstractSecurityUtils.getStockImage(appId, id); - return f; - } - } - } - ///////////////////////////////////////////////////////////////// /* @@ -566,51 +204,9 @@ protected void closeStream(FileInputStream fis) { try { fis.close(); } catch (IOException e) { - logger.error(STACKTRACE, e); + logger.error(Constants.STACKTRACE, e); } } } - /////////////////////////////////////////////////////// - /////////////////////////////////////////////////////// - /////////////////////////////////////////////////////// - /////////////////////////////////////////////////////// - /////////////////////////////////////////////////////// - - /* - * Currently not used below... - */ - - @GET - @Path("/appWidget") - @Produces(MediaType.APPLICATION_OCTET_STREAM) - public Response getAppWidget(@PathParam("appId") String app, @QueryParam("widget") String widgetName, @QueryParam("file") String fileName) { - final String basePath = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER); - String appWidgetDirLoc = basePath + DIR_SEPARATOR + "db" + - DIR_SEPARATOR + app + - DIR_SEPARATOR + "version" + - DIR_SEPARATOR + "widgets"; - - // Get widget file - String widgetFile = appWidgetDirLoc + DIR_SEPARATOR + widgetName + DIR_SEPARATOR + fileName; - File f = new File(widgetFile); - FileInputStream fis = null; - if (f.exists()) { - try { - fis = new FileInputStream(f); - byte[] byteArray = IOUtils.toByteArray(fis); - // return file - return Response.status(200).entity(byteArray).build(); - } catch (IOException e) { - logger.error(STACKTRACE, e); - } finally { - closeStream(fis); - } - } - // return error - Map errorMap = new HashMap<>(); - errorMap.put("errorMessage", "error sending widget file " + widgetName + "\\" + fileName); - return WebUtility.getResponse(errorMap, 400); - } - } diff --git a/src/prerna/semoss/web/services/local/DataframeResource.java b/src/prerna/semoss/web/services/local/DataframeResource.java index 62eaddfd9..647fc906a 100644 --- a/src/prerna/semoss/web/services/local/DataframeResource.java +++ b/src/prerna/semoss/web/services/local/DataframeResource.java @@ -41,22 +41,22 @@ public class DataframeResource { // return WebUtility.getResponse("Successfully closed back door", 200); // } - @POST - @Path("/applyCalc") - @Produces("application/json") - public Response applyCalculation(MultivaluedMap form, @Context HttpServletRequest request){ - String pkqlCmd = form.getFirst("expression"); - Map resultHash = null; - synchronized(insight) { - resultHash = insight.runPkql(pkqlCmd); - } - - //TODO: stupid stuff that was never cleaned up... - Map stupidFEObj = new HashMap(); - stupidFEObj.put("insights", new Object[]{resultHash}); - - return WebUtility.getResponse(stupidFEObj, 200); - } +// @POST +// @Path("/applyCalc") +// @Produces("application/json") +// public Response applyCalculation(MultivaluedMap form, @Context HttpServletRequest request){ +// String pkqlCmd = form.getFirst("expression"); +// Map resultHash = null; +// synchronized(insight) { +// resultHash = insight.runPkql(pkqlCmd); +// } +// +// //TODO: stupid stuff that was never cleaned up... +// Map stupidFEObj = new HashMap(); +// stupidFEObj.put("insights", new Object[]{resultHash}); +// +// return WebUtility.getResponse(stupidFEObj, 200); +// } //for handling playsheet specific tool calls @POST diff --git a/src/prerna/semoss/web/services/local/EngineResource.java b/src/prerna/semoss/web/services/local/EngineResource.java index f50b632c6..781daba87 100644 --- a/src/prerna/semoss/web/services/local/EngineResource.java +++ b/src/prerna/semoss/web/services/local/EngineResource.java @@ -28,7 +28,6 @@ package prerna.semoss.web.services.local; import java.util.HashMap; -import java.util.Hashtable; import java.util.List; import java.util.Map; import java.util.Vector; @@ -93,18 +92,18 @@ public void setEngine(IEngine coreEngine) * @param request * @return a hashtable with "perspectives" pointing to to array of perspectives (e.g. ["Generic-Perspective","Movie-Perspective"]) */ - @GET - @Path("perspectives") - @Produces("application/json") - public Response getPerspectives(@Context HttpServletRequest request) - { - // if the type is null then send all the insights else only that - Hashtable> hashtable = new Hashtable>(); - Vector perspectivesVector = coreEngine.getPerspectives(); - hashtable.put("perspectives", perspectivesVector); -// return Response.status(200).entity(WebUtility.getSO(hashtable)).build(); - return WebUtility.getResponse(hashtable, 200); - } +// @GET +// @Path("perspectives") +// @Produces("application/json") +// public Response getPerspectives(@Context HttpServletRequest request) +// { +// // if the type is null then send all the insights else only that +// Hashtable> hashtable = new Hashtable>(); +// Vector perspectivesVector = coreEngine.getPerspectives(); +// hashtable.put("perspectives", perspectivesVector); +//// return Response.status(200).entity(WebUtility.getSO(hashtable)).build(); +// return WebUtility.getResponse(hashtable, 200); +// } // gets a particular insight // not sure if I should keep it as it is or turn this into a post because of the query @@ -177,7 +176,7 @@ public Response getInsightParams(@QueryParam("insight") String insightId) paramR.In(); GenRowStruct grs1 = new GenRowStruct(); grs1.add(new NounMetadata(coreEngine.getEngineId(), PixelDataType.CONST_STRING)); - paramR.getNounStore().addNoun(ReactorKeysEnum.APP.getKey(), grs1); + paramR.getNounStore().addNoun(ReactorKeysEnum.DATABASE.getKey(), grs1); GenRowStruct grs2 = new GenRowStruct(); grs2.add(new NounMetadata(insightId, PixelDataType.CONST_STRING)); paramR.getNounStore().addNoun(ReactorKeysEnum.ID.getKey(), grs2); @@ -226,7 +225,7 @@ public Response createOutput(MultivaluedMap form, @Context HttpS playsheetRunReactor.setPixelPlanner(planner); GenRowStruct grs1 = new GenRowStruct(); grs1.add(new NounMetadata(coreEngine.getEngineId(), PixelDataType.CONST_STRING)); - playsheetRunReactor.getNounStore().addNoun(ReactorKeysEnum.APP.getKey(), grs1); + playsheetRunReactor.getNounStore().addNoun(ReactorKeysEnum.DATABASE.getKey(), grs1); GenRowStruct grs2 = new GenRowStruct(); grs2.add(new NounMetadata(insightId, PixelDataType.CONST_STRING)); playsheetRunReactor.getNounStore().addNoun(ReactorKeysEnum.ID.getKey(), grs2); diff --git a/src/prerna/semoss/web/services/local/ExecuteInsightResource.java b/src/prerna/semoss/web/services/local/ExecuteInsightResource.java index 500d0fdfc..67ad54b2d 100644 --- a/src/prerna/semoss/web/services/local/ExecuteInsightResource.java +++ b/src/prerna/semoss/web/services/local/ExecuteInsightResource.java @@ -15,10 +15,10 @@ import prerna.auth.utils.SecurityInsightUtils; import prerna.auth.utils.SecurityQueryUtils; import prerna.cluster.util.ClusterUtil; -import prerna.engine.api.IEngine; import prerna.nameserver.utility.MasterDatabaseUtility; import prerna.om.Insight; import prerna.om.InsightStore; +import prerna.project.api.IProject; import prerna.util.Constants; import prerna.util.Utility; import prerna.web.services.util.WebUtility; @@ -34,7 +34,7 @@ public Object test() { @Path("/a-{appId}/i-{insightId}") public Object generateInsight(@Context HttpServletRequest request, - @PathParam("appId") String appId, + @PathParam("appId") String projectId, @PathParam("insightId") String rdbmsId) { boolean securityEnabled = AbstractSecurityUtils.securityEnabled(); User user = null; @@ -60,28 +60,28 @@ public Object generateInsight(@Context HttpServletRequest request, } if(securityEnabled) { - appId = SecurityQueryUtils.testUserEngineIdForAlias(user, appId); - if(!SecurityInsightUtils.userCanViewInsight(user, appId, rdbmsId)) { + projectId = SecurityQueryUtils.testUserDatabaseIdForAlias(user, projectId); + if(!SecurityInsightUtils.userCanViewInsight(user, projectId, rdbmsId)) { Map errorMap = new HashMap(); errorMap.put("error", "User does not have access to this insight"); return WebUtility.getResponse(errorMap, 401); } } else { - appId = MasterDatabaseUtility.testEngineIdIfAlias(appId); + projectId = MasterDatabaseUtility.testDatabaseIdIfAlias(projectId); } - IEngine engine = Utility.getEngine(appId); - if(engine == null) { - throw new IllegalArgumentException("Cannot find app = " + appId); + IProject project = Utility.getProject(projectId); + if(project == null) { + throw new IllegalArgumentException("Cannot find project = " + projectId); } Insight newInsight = null; try { - List in = engine.getInsight(rdbmsId + ""); + List in = project.getInsight(rdbmsId + ""); newInsight = in.get(0); } catch (ArrayIndexOutOfBoundsException e) { - ClusterUtil.reactorUpdateApp(appId); + ClusterUtil.reactorUpdateApp(projectId); try { - List in = engine.getInsight(rdbmsId + ""); + List in = project.getInsight(rdbmsId + ""); newInsight = in.get(0); } catch (ArrayIndexOutOfBoundsException e2) { Map errorMap = new HashMap(); diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index bf8701667..9def5bdab 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -86,7 +86,6 @@ import prerna.om.Insight; import prerna.om.InsightStore; import prerna.om.ThreadStore; -import prerna.sablecc.PKQLRunner; import prerna.sablecc2.PixelRunner; import prerna.sablecc2.PixelStreamUtility; import prerna.sablecc2.PixelUtility; @@ -829,16 +828,16 @@ public Object getLocalDatabase(@Context HttpServletRequest request, @PathParam(" if (user == null) { return WebUtility.getSO("Not properly authenticated"); } - engineId = SecurityQueryUtils.testUserEngineIdForAlias(user, engineId); - if (!SecurityAppUtils.userCanViewEngine(user, engineId)) { + engineId = SecurityQueryUtils.testUserDatabaseIdForAlias(user, engineId); + if (!SecurityAppUtils.userCanViewDatabase(user, engineId)) { Map errorMap = new HashMap<>(); errorMap.put(Constants.ERROR_MESSAGE, "Database " + engineId + " does not exist or user does not have access to database"); return WebUtility.getResponse(errorMap, 400); } } else { - engineId = MasterDatabaseUtility.testEngineIdIfAlias(engineId); - if (!MasterDatabaseUtility.getAllEngineIds().contains(engineId)) { + engineId = MasterDatabaseUtility.testDatabaseIdIfAlias(engineId); + if (!MasterDatabaseUtility.getAllDatabaseIds().contains(engineId)) { Map errorMap = new HashMap<>(); errorMap.put(Constants.ERROR_MESSAGE, "Database " + engineId + " does not exist"); return WebUtility.getResponse(errorMap, 400); @@ -1015,34 +1014,34 @@ public void write(OutputStream outputStream) throws IOException, WebApplicationE }; } - @POST - @Path("runPkql") - @Produces("application/json") - @Deprecated - public StreamingOutput runPkql(MultivaluedMap form) { - /* - * This is only used for calls that do not require us to hold state - * pkql that run in here should not touch a data farme - */ - String expression = form.getFirst("expression"); - PKQLRunner runner = new PKQLRunner(); - runner.runPKQL(expression); - - Map resultHash = new HashMap<>(); - - // this is technically the only piece of information the FE needs - // but to keep the return consistent for them - // i am sending back the information in the same weird ordering - Map pkqlDataHash = new HashMap<>(); - pkqlDataHash.put("pkqlData", runner.getResults()); - - Object[] insightArr = new Object[1]; - insightArr[0] = pkqlDataHash; - - resultHash.put("insights", insightArr); - - return WebUtility.getSO(resultHash); - } +// @POST +// @Path("runPkql") +// @Produces("application/json") +// @Deprecated +// public StreamingOutput runPkql(MultivaluedMap form) { +// /* +// * This is only used for calls that do not require us to hold state +// * pkql that run in here should not touch a data farme +// */ +// String expression = form.getFirst("expression"); +// PKQLRunner runner = new PKQLRunner(); +// runner.runPKQL(expression); +// +// Map resultHash = new HashMap<>(); +// +// // this is technically the only piece of information the FE needs +// // but to keep the return consistent for them +// // i am sending back the information in the same weird ordering +// Map pkqlDataHash = new HashMap<>(); +// pkqlDataHash.put("pkqlData", runner.getResults()); +// +// Object[] insightArr = new Object[1]; +// insightArr[0] = pkqlDataHash; +// +// resultHash.put("insights", insightArr); +// +// return WebUtility.getSO(resultHash); +// } //////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////// diff --git a/src/prerna/semoss/web/services/local/ProjectResource.java b/src/prerna/semoss/web/services/local/ProjectResource.java new file mode 100644 index 000000000..de10170c9 --- /dev/null +++ b/src/prerna/semoss/web/services/local/ProjectResource.java @@ -0,0 +1,607 @@ +package prerna.semoss.web.services.local; + +import java.io.File; +import java.io.FileFilter; +import java.io.FileInputStream; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Vector; + +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.EntityTag; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Request; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.ResponseBuilder; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.io.IOUtils; +import org.apache.commons.io.filefilter.WildcardFileFilter; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import prerna.auth.User; +import prerna.auth.utils.AbstractSecurityUtils; +import prerna.auth.utils.SecurityInsightUtils; +import prerna.auth.utils.SecurityProjectUtils; +import prerna.cluster.util.ClusterUtil; +import prerna.engine.impl.SmssUtilities; +import prerna.nameserver.utility.MasterDatabaseUtility; +import prerna.util.AssetUtility; +import prerna.util.Constants; +import prerna.util.DIHelper; +import prerna.util.Utility; +import prerna.util.insight.TextToGraphic; +import prerna.web.services.util.WebUtility; + +@Path("/project-{projectId}") +public class ProjectResource { + + private static final String DIR_SEPARATOR = java.nio.file.FileSystems.getDefault().getSeparator(); + private static String defaultEmbedLogo = null; + private static boolean noLogo = false; + + private static final Logger logger = LogManager.getLogger(ProjectResource.class); + + private boolean canAccessProject(User user, String projectId) throws IllegalAccessException { + if(AbstractSecurityUtils.securityEnabled()) { + projectId = SecurityProjectUtils.testUserProjectIdForAlias(user, projectId); + if(!SecurityProjectUtils.userCanViewProject(user, projectId)) { + throw new IllegalAccessException("Project " + projectId + " does not exist or user does not have access"); + } + } else { + projectId = MasterDatabaseUtility.testDatabaseIdIfAlias(projectId); + if(!MasterDatabaseUtility.getAllDatabaseIds().contains(projectId)) { + throw new IllegalAccessException("Project " + projectId + " does not exist"); + } + } + + return true; + } + + private boolean canAccessInsight(User user, String projectId, String insightId) throws IllegalAccessException { + if(AbstractSecurityUtils.securityEnabled()) { + projectId = SecurityProjectUtils.testUserProjectIdForAlias(user, projectId); + if(!SecurityInsightUtils.userCanViewInsight(user, projectId, insightId)) { + throw new IllegalAccessException("Insight does not exist or user does not have access to view"); + } + } else { + projectId = MasterDatabaseUtility.testDatabaseIdIfAlias(projectId); + if(!MasterDatabaseUtility.getAllDatabaseIds().contains(projectId)) { + throw new IllegalAccessException("Project " + projectId + " does not exist"); + } + } + + return true; + } + + /////////////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////////////// + + /* + * Code below is around retrieving app assets + */ + + @GET + @Path("/landing") + @Produces(MediaType.TEXT_HTML) + public Response getProjectLandingPage(@Context final Request coreRequest, @Context HttpServletRequest request, @PathParam("projectId") String projectId) { + User user = null; + try { + user = ResourceUtility.getUser(request); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap<>(); + errorMap.put("error", "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + try { + canAccessProject(user, projectId); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap<>(); + errorMap.put("error", e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + + String propFileLoc = (String) DIHelper.getInstance().getProjectProperty(projectId + "_" + Constants.STORE); + Properties prop = Utility.loadProperties(propFileLoc); + String projectName = prop.getProperty(Constants.PROJECT_ALIAS); + + String baseFolder = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER); + String fileLocation = baseFolder + DIR_SEPARATOR + Constants.PROJECT_FOLDER + DIR_SEPARATOR + SmssUtilities.getUniqueName(projectName, projectId) + + DIR_SEPARATOR + "app_root/version/assets/landing.html"; + File file = new File(fileLocation); + if(file != null && file.exists()) { + try { + String html = FileUtils.readFileToString(file, "UTF-8"); + + // want to cache this on browser if user has access +// CacheControl cc = new CacheControl(); +// cc.setMaxAge(1); +// cc.setPrivate(true); + EntityTag etag = new EntityTag(Integer.toString(html.hashCode())); + ResponseBuilder builder = coreRequest.evaluatePreconditions(etag); + + // cached resource did not change + if(builder != null) { + return builder.build(); + } + + return Response.status(200).entity(html) +// .cacheControl(cc) + .tag(etag) +// .lastModified(new Date(file.lastModified())) + .build(); + } catch (IOException e) { + Map errorMap = new HashMap<>(); + errorMap.put("errorMessage", "Unable to load landing html file"); + return WebUtility.getResponse(errorMap, 404); + } + } else { + Map errorMap = new HashMap<>(); + errorMap.put("errorMessage", "No custom landing page found"); + return WebUtility.getResponse(errorMap, 404); + } + } + + @GET + @Path("/downloadProjectAsset/{relPath}") + @Produces({MediaType.TEXT_HTML, MediaType.APPLICATION_OCTET_STREAM}) + public Response downloadProjectAsset(@Context final Request coreRequest, @Context HttpServletRequest request, @PathParam("projectId") String projectId, @PathParam("relPath") String relPath) { + User user = null; + try { + user = ResourceUtility.getUser(request); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap<>(); + errorMap.put("error", "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + try { + canAccessProject(user, projectId); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap<>(); + errorMap.put("error", e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + + String propFileLoc = (String) DIHelper.getInstance().getProjectProperty(projectId + "_" + Constants.STORE); + Properties prop = Utility.loadProperties(propFileLoc); + String projectName = prop.getProperty(Constants.PROJECT_ALIAS); + + String baseFolder = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER); + String fileLocation = baseFolder + DIR_SEPARATOR + Constants.PROJECT_FOLDER + DIR_SEPARATOR + SmssUtilities.getUniqueName(projectName, projectId) + + DIR_SEPARATOR + "app_root/version/assets/" + relPath; + File file = new File(fileLocation); + if(file != null && file.exists()) { + try { + String contents = FileUtils.readFileToString(file, "UTF-8"); + + // want to cache this on browser if user has access +// CacheControl cc = new CacheControl(); +// cc.setMaxAge(1); +// cc.setPrivate(true); + EntityTag etag = new EntityTag(Integer.toString(contents.hashCode())); + ResponseBuilder builder = coreRequest.evaluatePreconditions(etag); + + // cached resource did not change + if(builder != null) { + return builder.build(); + } + + return Response.status(200).entity(contents) +// .cacheControl(cc) + .tag(etag) +// .lastModified(new Date(file.lastModified())) + .build(); + } catch (IOException e) { + Map errorMap = new HashMap<>(); + errorMap.put("errorMessage", "Unable to load file"); + return WebUtility.getResponse(errorMap, 404); + } + } else { + Map errorMap = new HashMap<>(); + errorMap.put("errorMessage", "No file found"); + return WebUtility.getResponse(errorMap, 404); + } + } + + @GET + @Path("/embedLogo") + @Produces({MediaType.TEXT_HTML, MediaType.APPLICATION_OCTET_STREAM}) + public Response getEmbedUrl(@Context final Request coreRequest, @Context HttpServletRequest request, @PathParam("projectId") String projectId, @QueryParam("insightId") String insightId) { + User user = null; + if(AbstractSecurityUtils.securityEnabled()) { + try { + user = ResourceUtility.getUser(request); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap<>(); + errorMap.put("error", "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + try { + canAccessProject(user, projectId); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap<>(); + errorMap.put("error", e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + } + + //TODO: ALLOW APP SPECIFIC EMBED IMAGES + //TODO: ALLOW INSIGHT SPECIFIC EMBED IMAGES + + String embedLogo = getEmbedLogo(); + if(ProjectResource.noLogo) { + Map errorMap = new HashMap<>(); + errorMap.put("error", "no defualt logo"); + return WebUtility.getResponse(errorMap, 404); + } + + File file = new File(embedLogo); + if(file != null && file.exists()) { + try { + String contents = new String(Files.readAllBytes(Paths.get(file.getAbsolutePath()))); + + // want to cache this on browser if user has access +// CacheControl cc = new CacheControl(); +// cc.setMaxAge(1); +// cc.setPrivate(true); + EntityTag etag = new EntityTag(Integer.toString(contents.hashCode())); + ResponseBuilder builder = coreRequest.evaluatePreconditions(etag); + + // cached resource did not change + if(builder != null) { + return builder.build(); + } + + String mimeType = Files.probeContentType(file.toPath()); + return Response.status(200).entity(contents).type(mimeType) +// .cacheControl(cc) + .tag(etag) +// .lastModified(new Date(file.lastModified())) + .build(); + } catch (IOException e) { + Map errorMap = new HashMap<>(); + errorMap.put("errorMessage", "Unable to load file"); + return WebUtility.getResponse(errorMap, 400); + } + } else { + Map errorMap = new HashMap<>(); + errorMap.put("errorMessage", "Default logo file not found"); + return WebUtility.getResponse(errorMap, 404); + } + } + + private static String getEmbedLogo() { + if(ProjectResource.defaultEmbedLogo == null) { + String embedFileName = DIHelper.getInstance().getProperty(Constants.EMBED_URL_LOGO); + if(embedFileName == null || embedFileName.equalsIgnoreCase("NONE")) { + ProjectResource.noLogo = true; + ProjectResource.defaultEmbedLogo = "NONE"; + } else { + String baseFolder = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER); + String embedFolder = baseFolder + DIR_SEPARATOR + "images" + DIR_SEPARATOR + "embed"; + ProjectResource.defaultEmbedLogo = embedFolder + DIR_SEPARATOR + embedFileName; + ProjectResource.noLogo = false; + } + } + return ProjectResource.defaultEmbedLogo; + } + + + /////////////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////////////////////////////// + + /* + * Code below is around app images and insight images + */ + + @GET + @Path("/projectImage/download") + @Produces({MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_SVG_XML}) + public Response downloadProjectImage(@Context final Request coreRequest, @Context HttpServletRequest request, @PathParam("projectId") String projectId) { + if(AbstractSecurityUtils.securityEnabled()) { + User user = null; + try { + user = ResourceUtility.getUser(request); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap<>(); + errorMap.put("error", "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + try { + canAccessProject(user, projectId); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap<>(); + errorMap.put("error", e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + } + + File exportFile = getProjectImageFile(projectId); + if(exportFile != null && exportFile.exists()) { + String exportName = projectId + "_Image." + FilenameUtils.getExtension(exportFile.getAbsolutePath()); + // want to cache this on browser if user has access +// CacheControl cc = new CacheControl(); +// cc.setMaxAge(86400); +// cc.setPrivate(true); +// cc.setMustRevalidate(true); + EntityTag etag = new EntityTag(Integer.toString(exportFile.hashCode())); + ResponseBuilder builder = coreRequest.evaluatePreconditions(etag); + + // cached resource did not change + if(builder != null) { + return builder.build(); + } + + return Response.status(200).entity(exportFile).header("Content-Disposition", "attachment; filename=" + exportName) +// .cacheControl(cc) + .tag(etag) +// .lastModified(new Date(exportFile.lastModified())) + .build(); + } else { + Map errorMap = new HashMap<>(); + errorMap.put("errorMessage", "error sending image file"); + return WebUtility.getResponse(errorMap, 400); + } + } + + /** + * Use to find the file for the image + * @param projectId + * @return + */ + protected File getProjectImageFile(String projectId) { + if(ClusterUtil.IS_CLUSTER) { + return ClusterUtil.getProjectImage(projectId); + } + String propFileLoc = (String) DIHelper.getInstance().getProjectProperty(projectId + "_" + Constants.STORE); + if(propFileLoc == null && !projectId.equals("NEWSEMOSSAPP")) { + String imageDir = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER) + "/images/stock/"; + return new File(imageDir + "color-logo.png"); + } + Properties prop = Utility.loadProperties(propFileLoc); + projectId = prop.getProperty(Constants.PROJECT_ALIAS); + + String fileLocation = AssetUtility.getProjectAssetVersionFolder(projectId, projectId); + File f = findImageFile(fileLocation); + if(f != null) { + return f; + } else { + // make the image + f = new File(fileLocation); + if(!f.exists()) { + Boolean success = f.mkdirs(); + if(!success) { + logger.info("Unable to make direction at location: " + Utility.cleanLogString(fileLocation)); + } + } + fileLocation = fileLocation + DIR_SEPARATOR + "image.png"; + if(projectId != null) { + TextToGraphic.makeImage(projectId, fileLocation); + } else { + TextToGraphic.makeImage(projectId, fileLocation); + } + f = new File(fileLocation); + return f; + } + } + + @GET + @Path("/insightImage/download") + @Produces({MediaType.APPLICATION_OCTET_STREAM, MediaType.APPLICATION_SVG_XML}) + public Response downloadInsightImage(@Context final Request coreRequest, @Context HttpServletRequest request, + @PathParam("projectId") String projectId, @QueryParam("rdbmsId") String id, @QueryParam("params") String params) { + String sessionId = null; + if(AbstractSecurityUtils.securityEnabled()) { + User user = null; + try { + user = ResourceUtility.getUser(request); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap<>(); + errorMap.put("error", "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + try { + canAccessInsight(user, projectId, id); + } catch (IllegalAccessException e) { + Map errorMap = new HashMap<>(); + errorMap.put("error", e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + + sessionId = request.getSession(false).getId(); + } + + File exportFile = getInsightImageFile(projectId, id, request.getHeader("Referer"), params, sessionId); + if(exportFile != null && exportFile.exists()) { + String exportName = projectId + "_Image." + FilenameUtils.getExtension(exportFile.getAbsolutePath()); + // want to cache this on browser if user has access +// CacheControl cc = new CacheControl(); +// cc.setMaxAge(86400); +// cc.setPrivate(true); +// cc.setMustRevalidate(true); + EntityTag etag = new EntityTag(Integer.toString(exportFile.hashCode())); + ResponseBuilder builder = coreRequest.evaluatePreconditions(etag); + + // cached resource did not change + if(builder != null) { + return builder.build(); + } + + return Response.status(200).entity(exportFile).header("Content-Disposition", "attachment; filename=" + exportName) +// .cacheControl(cc) + .tag(etag) +// .lastModified(new Date(exportFile.lastModified())) + .build(); + } else { + Map errorMap = new HashMap<>(); + errorMap.put("errorMessage", "Error sending image file"); + return WebUtility.getResponse(errorMap, 404); + } + } + + /** + * Use to find the file for the image + * @param app + * @return + */ + private File getInsightImageFile(String projectId, String id, String feUrl, String params, String sessionId) { + File f = null; + String fileLocation = null; + String propFileLoc = (String) DIHelper.getInstance().getProjectProperty(projectId + "_" + Constants.STORE); + if(propFileLoc != null) { + Properties prop = Utility.loadProperties(propFileLoc); + String projectName = prop.getProperty(Constants.PROJECT_ALIAS); + + fileLocation = AssetUtility.getProjectAssetVersionFolder(projectName, projectId); + if(params != null && !params.isEmpty() && !params.equals("undefined")) { + String encodedParams = Utility.encodeURIComponent(params); + fileLocation = fileLocation + + DIR_SEPARATOR + id + + DIR_SEPARATOR + "params" + + DIR_SEPARATOR + encodedParams; + } else { + fileLocation = fileLocation + DIR_SEPARATOR + id; + } + f = findImageFile(fileLocation); + } + if(f != null && f.exists()) { + return f; + } else { + // try making the image + // JK! this is super annoying when running a bunch of + // insights at the same time which is what happens + // currently on the app home page +// if (!ClusterUtil.IS_CLUSTER) { +// if(feUrl != null) { +// try { +// ImageCaptureReactor.runImageCapture(feUrl, appId, id, params, sessionId); +// } +// catch(Exception | NoSuchMethodError er) { +// //Image Capture will not run. No image exists nor will be made. The exception kills the rest. +// // return stock image +// er.printStackTrace(); +// f = AbstractSecurityUtils.getStockImage(appId, id); +// return f; +// } +// } +// } + // the image capture ran + // let us try to see if there is a file now... + f = findImageFile(fileLocation); + if(f != null && f.exists()) { + return f; + } else { + // return stock image + f = AbstractSecurityUtils.getStockImage(projectId, id); + return f; + } + } + } + + ///////////////////////////////////////////////////////////////// + + /* + * Image utility methods + */ + + /** + * Find an image in the directory + * @param baseDir + * @return + */ + private File findImageFile(String baseDir) { + if(baseDir == null) { + return null; + } + List extensions = new Vector<>(); + extensions.add("image.png"); + extensions.add("image.jpeg"); + extensions.add("image.jpg"); + extensions.add("image.gif"); + extensions.add("image.svg"); + FileFilter imageExtensionFilter = new WildcardFileFilter(extensions); + File baseFolder = new File(baseDir); + File[] imageFiles = baseFolder.listFiles(imageExtensionFilter); + if(imageFiles != null && imageFiles.length > 0) { + return imageFiles[0]; + } + return null; + } + + /** + * Close a file stream + * @param fis + */ + protected void closeStream(FileInputStream fis) { + if(fis != null) { + try { + fis.close(); + } catch (IOException e) { + logger.error(Constants.STACKTRACE, e); + } + } + } + + /////////////////////////////////////////////////////// + /////////////////////////////////////////////////////// + /////////////////////////////////////////////////////// + /////////////////////////////////////////////////////// + /////////////////////////////////////////////////////// + + /* + * Currently not used below... + */ + + @GET + @Path("/projectWidget") + @Produces(MediaType.APPLICATION_OCTET_STREAM) + public Response getAppWidget(@PathParam("projectId") String projectId, @QueryParam("widget") String widgetName, @QueryParam("file") String fileName) { + final String basePath = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER); + String appWidgetDirLoc = basePath + DIR_SEPARATOR + Constants.PROJECT_FOLDER + + DIR_SEPARATOR + projectId + + DIR_SEPARATOR + "app_root" + + DIR_SEPARATOR + "version" + + DIR_SEPARATOR + "widgets"; + + // Get widget file + String widgetFile = appWidgetDirLoc + DIR_SEPARATOR + widgetName + DIR_SEPARATOR + fileName; + File f = new File(widgetFile); + FileInputStream fis = null; + if (f.exists()) { + try { + fis = new FileInputStream(f); + byte[] byteArray = IOUtils.toByteArray(fis); + // return file + return Response.status(200).entity(byteArray).build(); + } catch (IOException e) { + logger.error(Constants.STACKTRACE, e); + } finally { + closeStream(fis); + } + } + // return error + Map errorMap = new HashMap<>(); + errorMap.put("errorMessage", "error sending widget file " + widgetName + "\\" + fileName); + return WebUtility.getResponse(errorMap, 400); + } + +} diff --git a/src/prerna/semoss/web/services/local/UserResource.java b/src/prerna/semoss/web/services/local/UserResource.java index 316b5962c..8cc9dc527 100644 --- a/src/prerna/semoss/web/services/local/UserResource.java +++ b/src/prerna/semoss/web/services/local/UserResource.java @@ -97,7 +97,6 @@ import prerna.io.connector.surveymonkey.MonkeyProfile; import prerna.io.connector.twitter.TwitterSearcher; import prerna.om.NLPDocumentInput; -import prerna.sablecc2.reactor.mgmt.MgmtUtil; import prerna.security.AbstractHttpHelper; import prerna.util.BeanFiller; import prerna.util.Constants; @@ -124,13 +123,24 @@ public class UserResource { private static void loadSocialProperties() { FileInputStream fis = null; - File f = new File(DIHelper.getInstance().getProperty("SOCIAL")); + String socialPropFile = DIHelper.getInstance().getProperty("SOCIAL"); try { - if (f.exists()) { - socialData = new Properties(); - fis = new FileInputStream(f); - socialData.load(fis); - setLoginsAllowed(); + if(socialPropFile != null) { + File f = new File(DIHelper.getInstance().getProperty("SOCIAL")); + if (f.exists()) { + socialData = new Properties(); + fis = new FileInputStream(f); + socialData.load(fis); + setLoginsAllowed(); + } else { + logger.warn("No social.properties file found!"); + logger.warn("No social.properties file found!"); + logger.warn("No social.properties file found!"); + } + } else { + logger.warn("No social.properties defined in RDF_Map.prop!"); + logger.warn("No social.properties defined in RDF_Map.prop!"); + logger.warn("No social.properties defined in RDF_Map.prop!"); } } catch (FileNotFoundException fnfe) { logger.error(Constants.STACKTRACE, fnfe); @@ -247,9 +257,11 @@ public Response logout(@PathParam("provider") String provider, @Context HttpServ String assetEngineId = null; String workspaceEngineId = null; + // TODO: what does this part do? + // TODO: feel like when logout need to adjust the asset id if (thisUser.getLogins().size() == 1) { - thisUser.getAssetEngineId(token); - thisUser.getWorkspaceEngineId(token); + thisUser.getAssetProjectId(token); + thisUser.getWorkspaceProjectId(token); } removed = thisUser.dropAccessToken(token); if (thisUser.getLogins().isEmpty()) { diff --git a/src/prerna/semoss/web/services/local/auth/AdminAppAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/AdminAppAuthorizationResource.java index 5699a0f21..53a0877f1 100644 --- a/src/prerna/semoss/web/services/local/auth/AdminAppAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/AdminAppAuthorizationResource.java @@ -98,7 +98,7 @@ public Response grantAllApps(@Context HttpServletRequest request, MultivaluedMap } try { - adminUtils.grantAllApps(userId, permission); + adminUtils.grantAllDatabases(userId, permission); } catch (Exception e) { logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); @@ -136,7 +136,7 @@ public Response grantNewUsersAppAccess(@Context HttpServletRequest request, Mult } try { - adminUtils.grantNewUsersAppAccess(appId, permission); + adminUtils.grantNewUsersDatabaseAccess(appId, permission); } catch (Exception e) { logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); @@ -206,7 +206,7 @@ public Response addAppUserPermission(@Context HttpServletRequest request, Multiv } try { - adminUtils.addAppUser(newUserId, appId, permission); + adminUtils.addDatabaseUser(newUserId, appId, permission); } catch (Exception e) { logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); @@ -249,7 +249,7 @@ public Response addAllUsers(@Context HttpServletRequest request, MultivaluedMap< } try { - adminUtils.addAllAppUsers(appId, permission); + adminUtils.addAllDatabaseUsers(appId, permission); } catch (Exception e) { logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); @@ -294,7 +294,7 @@ public Response editAppUserPermission(@Context HttpServletRequest request, Multi } try { - adminUtils.editAppUserPermission(existingUserId, appId, newPermission); + adminUtils.editDatabaseUserPermission(existingUserId, appId, newPermission); } catch (Exception e) { logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); @@ -336,7 +336,7 @@ public Response updateAppUserPermissions(@Context HttpServletRequest request, Mu } try { - adminUtils.updateAppUserPermissions(appId, newPermission); + adminUtils.updateDatabaseUserPermissions(appId, newPermission); } catch (Exception e) { logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); @@ -380,7 +380,7 @@ public Response removeAppUserPermission(@Context HttpServletRequest request, Mul } try { - adminUtils.removeAppUser(existingUserId, appId); + adminUtils.removeDatabaseUser(existingUserId, appId); } catch (Exception e) { logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); @@ -419,7 +419,7 @@ public Response setAppGlobal(@Context HttpServletRequest request, MultivaluedMap } try { - adminUtils.setAppGlobal(appId, isPublic); + adminUtils.setDatabaseGlobal(appId, isPublic); } catch (Exception e){ logger.error("Stacktrace: ",e); Map errorRet = new HashMap(); @@ -457,7 +457,7 @@ public Response getAppUsersNoCredentials(@Context HttpServletRequest request, @Q errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 401); } - List> ret = adminUtils.getAppUsersNoCredentials(appId); + List> ret = adminUtils.getDatabaseUsersNoCredentials(appId); return WebUtility.getResponse(ret, 200); } diff --git a/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java index e4f1ff759..ed2a32c66 100644 --- a/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/AdminInsightAuthorizationResource.java @@ -22,8 +22,8 @@ import prerna.auth.User; import prerna.auth.utils.SecurityAdminUtils; import prerna.cluster.util.ClusterUtil; -import prerna.engine.api.IEngine; import prerna.engine.impl.InsightAdministrator; +import prerna.project.api.IProject; import prerna.semoss.web.services.local.ResourceUtility; import prerna.util.Constants; import prerna.util.Utility; @@ -35,43 +35,43 @@ public class AdminInsightAuthorizationResource extends AbstractAdminResource { private static final Logger logger = LogManager.getLogger(AdminInsightAuthorizationResource.class); /** - * Get the insights for the app + * Get the insights for the project * @param request * @param form * @return */ @GET @Produces("application/json") - @Path("getAppInsights") - public Response getAppInsights(@Context HttpServletRequest request, @QueryParam("appId") String appId) { + @Path("getProjectInsights") + public Response getProjectInsights(@Context HttpServletRequest request, @QueryParam("projectId") String projectId) { SecurityAdminUtils adminUtils = null; User user = null; try { user = ResourceUtility.getUser(request); adminUtils = performAdminCheck(request, user); } catch (IllegalAccessException e) { - logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to see all the insight for app " + appId + " when not an admin")); + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to see all the insight for project " + projectId + " when not an admin")); logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 401); } - List> ret = adminUtils.getAppInsights(appId); + List> ret = adminUtils.getProjectInsights(projectId); return WebUtility.getResponse(ret, 200); } /** - * Get the app users and their permissions + * Get the project users and their permissions * @param request * @param form * @return */ @POST @Produces("application/json") - @Path("getAllAppInsightUsers") - public Response getAllAppInsightUsers(@Context HttpServletRequest request, MultivaluedMap form) { - String appId = form.getFirst("appId"); + @Path("getAllProjectInsightUsers") + public Response getAllProjectInsightUsers(@Context HttpServletRequest request, MultivaluedMap form) { + String projectId = form.getFirst("projectId"); String userId = form.getFirst("userId"); SecurityAdminUtils adminUtils = null; @@ -80,14 +80,14 @@ public Response getAllAppInsightUsers(@Context HttpServletRequest request, Multi user = ResourceUtility.getUser(request); adminUtils = performAdminCheck(request, user); } catch (IllegalAccessException e) { - logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to see all the user insight access for app " + appId + " when not an admin")); + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to see all the user insight access for project " + projectId + " when not an admin")); logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 401); } - return WebUtility.getResponse(adminUtils.getAllUserInsightAccess(appId, userId), 200); + return WebUtility.getResponse(adminUtils.getAllUserInsightAccess(projectId, userId), 200); } @@ -99,12 +99,12 @@ public Response getAllAppInsightUsers(@Context HttpServletRequest request, Multi */ @POST @Produces("application/json") - @Path("deleteAppInsights") - public Response deleteAppInsights(@Context HttpServletRequest request, MultivaluedMap form) { + @Path("deleteProjectInsights") + public Response deleteProjectInsights(@Context HttpServletRequest request, MultivaluedMap form) { SecurityAdminUtils adminUtils = null; User user = null; - String appId = form.getFirst("appId"); + String projectId = form.getFirst("projectId"); Gson gson = new Gson(); List insightIds = gson.fromJson(form.getFirst("insightId"), List.class); @@ -112,7 +112,7 @@ public Response deleteAppInsights(@Context HttpServletRequest request, Multivalu user = ResourceUtility.getUser(request); adminUtils = performAdminCheck(request, user); } catch (IllegalAccessException e) { - logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to delete insight from app " + appId + " when not an admin")); + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to delete insight from projectId " + projectId + " when not an admin")); logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); @@ -120,11 +120,11 @@ public Response deleteAppInsights(@Context HttpServletRequest request, Multivalu } try { - ClusterUtil.reactorPullInsightsDB(appId); - adminUtils.deleteAppInsights(appId, insightIds); + ClusterUtil.reactorPullInsightsDB(projectId); + adminUtils.deleteProjectInsights(projectId, insightIds); // since modifying insight list // need to push to cloud storage - ClusterUtil.reactorPushInsightDB(appId); + ClusterUtil.reactorPushInsightDB(projectId); } catch (Exception e) { logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); @@ -146,14 +146,14 @@ public Response deleteAppInsights(@Context HttpServletRequest request, Multivalu @GET @Produces("application/json") @Path("getInsightUsers") - public Response getInsightUsers(@Context HttpServletRequest request, @QueryParam("appId") String appId, @QueryParam("insightId") String insightId) { + public Response getInsightUsers(@Context HttpServletRequest request, @QueryParam("projectId") String projectId, @QueryParam("insightId") String insightId) { SecurityAdminUtils adminUtils = null; User user = null; try { user = ResourceUtility.getUser(request); adminUtils = performAdminCheck(request, user); } catch (IllegalAccessException e) { - logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to get all users who have access to insight " + insightId + " in app " + appId + " when not an admin")); + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to get all users who have access to insight " + insightId + " in project " + projectId + " when not an admin")); logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); @@ -162,7 +162,7 @@ public Response getInsightUsers(@Context HttpServletRequest request, @QueryParam List> ret = null; try { - ret = adminUtils.getInsightUsers(appId, insightId); + ret = adminUtils.getInsightUsers(projectId, insightId); } catch (IllegalAccessException e) { logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); @@ -188,7 +188,7 @@ public Response addInsightUserPermission(@Context HttpServletRequest request, Mu User user = null; String newUserId = form.getFirst("id"); - String appId = form.getFirst("appId"); + String projectId = form.getFirst("projectId"); String insightId = form.getFirst("insightId"); String permission = form.getFirst("permission"); @@ -196,7 +196,7 @@ public Response addInsightUserPermission(@Context HttpServletRequest request, Mu user = ResourceUtility.getUser(request); adminUtils = performAdminCheck(request, user); } catch (IllegalAccessException e) { - logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to add user " + newUserId + " to insight " + insightId + " in app " + appId + " when not an admin")); + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to add user " + newUserId + " to insight " + insightId + " in project " + projectId + " when not an admin")); logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); @@ -204,7 +204,7 @@ public Response addInsightUserPermission(@Context HttpServletRequest request, Mu } try { - adminUtils.addInsightUser(newUserId, appId, insightId, permission); + adminUtils.addInsightUser(newUserId, projectId, insightId, permission); } catch (Exception e) { logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); @@ -213,7 +213,7 @@ public Response addInsightUserPermission(@Context HttpServletRequest request, Mu } // log the operation - logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has added user " + newUserId + " to insight " + insightId + " in app " + appId + " with permission " + permission)); + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has added user " + newUserId + " to insight " + insightId + " in project " + projectId + " with permission " + permission)); Map ret = new HashMap(); ret.put("success", true); @@ -221,25 +221,25 @@ public Response addInsightUserPermission(@Context HttpServletRequest request, Mu } /** - * Give permission to user for all insights in an app + * Give permission to user for all insights in a project * @param request * @param form * @return */ @POST - @Path("/grantAllAppInsights") @Produces("application/json") - public Response grantAllAppInsights(@Context HttpServletRequest request, MultivaluedMap form) { + @Path("/grantAllProjectInsights") + public Response grantAllProjectInsights(@Context HttpServletRequest request, MultivaluedMap form) { SecurityAdminUtils adminUtils = null; User user = null; - String appId = form.getFirst("appId"); + String projectId = form.getFirst("projectId"); String userId = form.getFirst("userId"); String permission = form.getFirst("permission"); try { user = ResourceUtility.getUser(request); adminUtils = performAdminCheck(request, user); } catch (IllegalAccessException e) { - logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to pull the apps that user " + userId + " has access to when not an admin")); + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to pull the projects that user " + userId + " has access to when not an admin")); logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); @@ -247,7 +247,7 @@ public Response grantAllAppInsights(@Context HttpServletRequest request, Multiva } try { - adminUtils.grantAllAppInsights(appId, userId, permission); + adminUtils.grantAllProjectInsights(projectId, userId, permission); } catch (Exception e) { logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); @@ -257,7 +257,7 @@ public Response grantAllAppInsights(@Context HttpServletRequest request, Multiva // log the operation logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), - "has granted all apps to " + userId + "with permission " + permission)); + "has granted all projects to " + userId + "with permission " + permission)); Map ret = new HashMap(); ret.put("success", true); @@ -265,18 +265,18 @@ public Response grantAllAppInsights(@Context HttpServletRequest request, Multiva } /** - * Give permission to user for all insights in an app + * Give permission to user for all insights in an project * @param request * @param form * @return */ @POST - @Path("/grantNewUsersInsightAccess") @Produces("application/json") + @Path("/grantNewUsersInsightAccess") public Response grantNewUsersInsightAccess(@Context HttpServletRequest request, MultivaluedMap form) { SecurityAdminUtils adminUtils = null; User user = null; - String appId = form.getFirst("appId"); + String projectId = form.getFirst("projectId"); String insightId = form.getFirst("insightId"); String permission = form.getFirst("permission"); try { @@ -291,7 +291,7 @@ public Response grantNewUsersInsightAccess(@Context HttpServletRequest request, } try { - adminUtils.grantNewUsersInsightAccess(appId, insightId, permission); + adminUtils.grantNewUsersInsightAccess(projectId, insightId, permission); } catch (Exception e) { logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); @@ -320,14 +320,14 @@ public Response grantNewUsersInsightAccess(@Context HttpServletRequest request, public Response addAllUsers(@Context HttpServletRequest request, MultivaluedMap form) { SecurityAdminUtils adminUtils = null; User user = null; - String appId = form.getFirst("appId"); + String projectId = form.getFirst("projectId"); String insightId = form.getFirst("insightId"); String permission = form.getFirst("permission"); try { user = ResourceUtility.getUser(request); adminUtils = performAdminCheck(request, user); } catch (IllegalAccessException e) { - logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to add all users to insight " + insightId + " in app " + appId + " when not an admin")); + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to add all users to insight " + insightId + " in project " + projectId + " when not an admin")); logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); @@ -335,7 +335,7 @@ public Response addAllUsers(@Context HttpServletRequest request, MultivaluedMap< } try { - adminUtils.addAllInsightUsers(appId, insightId, permission); + adminUtils.addAllInsightUsers(projectId, insightId, permission); } catch (Exception e) { logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); @@ -344,7 +344,7 @@ public Response addAllUsers(@Context HttpServletRequest request, MultivaluedMap< } // log the operation - logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has added all users to app " + appId + " with permission " + permission)); + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has added all users to project " + projectId + " with permission " + permission)); Map ret = new HashMap(); ret.put("success", true); @@ -366,7 +366,7 @@ public Response editInsightUserPermission(@Context HttpServletRequest request, M User user = null; String existingUserId = form.getFirst("id"); - String appId = form.getFirst("appId"); + String projectId = form.getFirst("projectId"); String insightId = form.getFirst("insightId"); String newPermission = form.getFirst("permission"); @@ -374,7 +374,7 @@ public Response editInsightUserPermission(@Context HttpServletRequest request, M user = ResourceUtility.getUser(request); adminUtils = performAdminCheck(request, user); } catch (IllegalAccessException e) { - logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to edit user " + existingUserId + " permissions for insight " + insightId + " in app " + appId + " when not an admin")); + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to edit user " + existingUserId + " permissions for insight " + insightId + " in project " + projectId + " when not an admin")); logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); @@ -382,7 +382,7 @@ public Response editInsightUserPermission(@Context HttpServletRequest request, M } try { - adminUtils.editInsightUserPermission(existingUserId, appId, insightId, newPermission); + adminUtils.editInsightUserPermission(existingUserId, projectId, insightId, newPermission); } catch (Exception e) { logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); @@ -391,7 +391,7 @@ public Response editInsightUserPermission(@Context HttpServletRequest request, M } // log the operation - logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has edited user " + existingUserId + " permission to insight " + insightId + " in app " + appId + " with level " + newPermission)); + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has edited user " + existingUserId + " permission to insight " + insightId + " in project " + projectId + " with level " + newPermission)); Map ret = new HashMap(); ret.put("success", true); @@ -410,7 +410,7 @@ public Response editInsightUserPermission(@Context HttpServletRequest request, M public Response updateAppUserPermissions(@Context HttpServletRequest request, MultivaluedMap form) { SecurityAdminUtils adminUtils = null; User user = null; - String appId = form.getFirst("appId"); + String projectId = form.getFirst("projectId"); String newPermission = form.getFirst("permission"); String insightId = form.getFirst("insightId"); try { @@ -418,14 +418,14 @@ public Response updateAppUserPermissions(@Context HttpServletRequest request, Mu adminUtils = performAdminCheck(request, user); } catch (IllegalAccessException e) { logger.error(Constants.STACKTRACE, e); - logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to edit user permissions for app " + appId + " when not an admin")); + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to edit user permissions for project " + projectId + " when not an admin")); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 401); } try { - adminUtils.updateInsightUserPermissions(appId, insightId, newPermission); + adminUtils.updateInsightUserPermissions(projectId, insightId, newPermission); } catch (Exception e) { logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); @@ -455,14 +455,14 @@ public Response removeInsightUserPermission(@Context HttpServletRequest request, User user = null; String existingUserId = form.getFirst("id"); - String appId = form.getFirst("appId"); + String projectId = form.getFirst("projectId"); String insightId = form.getFirst("insightId"); try { user = ResourceUtility.getUser(request); adminUtils = performAdminCheck(request, user); } catch (IllegalAccessException e) { - logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to remove user " + existingUserId + " from having access to insight " + insightId + " in app " + appId + " when not an admin")); + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to remove user " + existingUserId + " from having access to insight " + insightId + " in project " + projectId + " when not an admin")); logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); @@ -470,7 +470,7 @@ public Response removeInsightUserPermission(@Context HttpServletRequest request, } try { - adminUtils.removeInsightUser(existingUserId, appId, insightId); + adminUtils.removeInsightUser(existingUserId, projectId, insightId); } catch (Exception e) { logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); @@ -479,7 +479,7 @@ public Response removeInsightUserPermission(@Context HttpServletRequest request, } // log the operation - logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has removed user " + existingUserId + " from having access to insight " + insightId + " in app " + appId)); + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has removed user " + existingUserId + " from having access to insight " + insightId + " in project " + projectId)); Map ret = new HashMap(); ret.put("success", true); @@ -499,7 +499,7 @@ public Response setInsightGlobal(@Context HttpServletRequest request, Multivalue SecurityAdminUtils adminUtils = null; User user = null; - String appId = form.getFirst("appId"); + String projectId = form.getFirst("projectId"); String insightId = form.getFirst("insightId"); boolean isPublic = Boolean.parseBoolean(form.getFirst("isPublic")); String logPublic = isPublic ? " public " : " private"; @@ -508,7 +508,7 @@ public Response setInsightGlobal(@Context HttpServletRequest request, Multivalue user = ResourceUtility.getUser(request); adminUtils = performAdminCheck(request, user); } catch (IllegalAccessException e) { - logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to set the insight " + insightId + " in app " + appId + logPublic + " when not an admin")); + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to set the insight " + insightId + " in project " + projectId + logPublic + " when not an admin")); logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); @@ -516,15 +516,15 @@ public Response setInsightGlobal(@Context HttpServletRequest request, Multivalue } try { - adminUtils.setInsightGlobalWithinApp(appId, insightId, isPublic); + adminUtils.setInsightGlobalWithinProject(projectId, insightId, isPublic); // also update in the app itself // so it is properly synchronized with the security db - ClusterUtil.reactorPullInsightsDB(appId); - IEngine app = Utility.getEngine(appId); - InsightAdministrator admin = new InsightAdministrator(app.getInsightDatabase()); + ClusterUtil.reactorPullInsightsDB(projectId); + IProject project = Utility.getProject(projectId); + InsightAdministrator admin = new InsightAdministrator(project.getInsightDatabase()); admin.updateInsightGlobal(insightId, !isPublic); - ClusterUtil.reactorPushInsightDB(appId); + ClusterUtil.reactorPushInsightDB(projectId); } catch (Exception e) { logger.error(Constants.STACKTRACE, e); @@ -534,7 +534,7 @@ public Response setInsightGlobal(@Context HttpServletRequest request, Multivalue } // log the operation - logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has set the insight " + insightId + " in app " + appId + logPublic)); + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has set the insight " + insightId + " in project " + projectId + logPublic)); Map ret = new HashMap(); ret.put("success", true); @@ -550,20 +550,20 @@ public Response setInsightGlobal(@Context HttpServletRequest request, Multivalue @GET @Produces("application/json") @Path("getInsightUsersNoCredentials") - public Response getInsightUsersNoCredentials(@Context HttpServletRequest request, @QueryParam("appId") String appId, @QueryParam("insightId") String insightId) { + public Response getInsightUsersNoCredentials(@Context HttpServletRequest request, @QueryParam("projectId") String projectId, @QueryParam("insightId") String insightId) { SecurityAdminUtils adminUtils = null; User user = null; try { user = ResourceUtility.getUser(request); adminUtils = performAdminCheck(request, user); } catch (IllegalAccessException e) { - logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to get all users who have access to insight " + insightId + " in app " + appId + " when not an admin")); + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to get all users who have access to insight " + insightId + " in project " + projectId + " when not an admin")); logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); return WebUtility.getResponse(errorMap, 401); } - List> ret = adminUtils.getInsightUsersNoCredentials(appId, insightId); + List> ret = adminUtils.getInsightUsersNoCredentials(projectId, insightId); return WebUtility.getResponse(ret, 200); } diff --git a/src/prerna/semoss/web/services/local/auth/AdminProjectAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/AdminProjectAuthorizationResource.java new file mode 100644 index 000000000..c0e7a97f2 --- /dev/null +++ b/src/prerna/semoss/web/services/local/auth/AdminProjectAuthorizationResource.java @@ -0,0 +1,464 @@ +package prerna.semoss.web.services.local.auth; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.Response; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import prerna.auth.User; +import prerna.auth.utils.SecurityAdminUtils; +import prerna.semoss.web.services.local.ResourceUtility; +import prerna.util.Constants; +import prerna.web.services.util.WebUtility; + +@Path("/auth/admin/project") +public class AdminProjectAuthorizationResource extends AbstractAdminResource { + + private static final Logger logger = LogManager.getLogger(AdminProjectAuthorizationResource.class); + + @Context + protected ServletContext context; + + /** + * Get the projects the user has access to + * @param request + * @return + */ + @GET + @Produces("application/json") + @Path("getProjects") + public Response getProjects(@Context HttpServletRequest request) { + SecurityAdminUtils adminUtils = null; + User user = null; + try { + user = ResourceUtility.getUser(request); + adminUtils = performAdminCheck(request, user); + } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to get all projects when not an admin")); + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + + return WebUtility.getResponse(adminUtils.getAllProjectSettings(), 200); + } + + @POST + @Path("/getAllUserProjects") + @Produces("application/json") + public Response getAllUserProjects(@Context HttpServletRequest request, MultivaluedMap form) { + SecurityAdminUtils adminUtils = null; + User user = null; + String userId = form.getFirst("userId"); + try { + user = ResourceUtility.getUser(request); + adminUtils = performAdminCheck(request, user); + } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to pull the projects that user " + userId + " has access to when not an admin")); + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + + return WebUtility.getResponse(adminUtils.getAllUserProjects(userId), 200); + } + + @POST + @Path("/grantAllProjects") + @Produces("application/json") + public Response grantAllProjects(@Context HttpServletRequest request, MultivaluedMap form) { + SecurityAdminUtils adminUtils = null; + User user = null; + String userId = form.getFirst("userId"); + String permission = form.getFirst("permission"); + try { + user = ResourceUtility.getUser(request); + adminUtils = performAdminCheck(request, user); + } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to grant all the projects to user " + userId + " when not an admin")); + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + + try { + adminUtils.grantAllProjects(userId, permission); + } catch (Exception e) { + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 400); + } + + // log the operation + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), + "has granted all projects to " + userId + "with permission " + permission)); + + Map ret = new HashMap(); + ret.put("success", true); + return WebUtility.getResponse(ret, 200); + } + + + @POST + @Path("/grantNewUsersProjectAccess") + @Produces("application/json") + public Response grantNewUsersProjectAccess(@Context HttpServletRequest request, MultivaluedMap form) { + SecurityAdminUtils adminUtils = null; + User user = null; + String permission = form.getFirst("permission"); + String projectId = form.getFirst("projectId"); + try { + user = ResourceUtility.getUser(request); + adminUtils = performAdminCheck(request, user); + } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to grant projects to new users when not an admin")); + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + + try { + adminUtils.grantNewUsersProjectAccess(projectId, permission); + } catch (Exception e) { + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 400); + } + + // log the operation + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), + "has granted project " + projectId + "to new users with permission " + permission)); + + Map ret = new HashMap(); + ret.put("success", true); + return WebUtility.getResponse(ret, 200); + } + + /** + * Get the project users and their permissions + * @param request + * @param form + * @return + */ + @GET + @Produces("application/json") + @Path("getProjectUsers") + public Response getProjectUsers(@Context HttpServletRequest request, @QueryParam("projectId") String projectId) { + SecurityAdminUtils adminUtils = null; + User user = null; + try { + user = ResourceUtility.getUser(request); + adminUtils = performAdminCheck(request, user); + } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to pull all the users who use project " + projectId + " when not an admin")); + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + + return WebUtility.getResponse(adminUtils.getProjectUsers(projectId), 200); + } + + /** + * Add a user to an project + * @param request + * @param form + * @return + */ + @POST + @Produces("application/json") + @Path("addProjectUserPermission") + public Response addProjectUserPermission(@Context HttpServletRequest request, MultivaluedMap form) { + SecurityAdminUtils adminUtils = null; + User user = null; + String newUserId = form.getFirst("id"); + String projectId = form.getFirst("projectId"); + String permission = form.getFirst("permission"); + try { + user = ResourceUtility.getUser(request); + adminUtils = performAdminCheck(request, user); + } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to add user " + newUserId + " to project " + projectId + " when not an admin")); + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + + try { + adminUtils.addProjectUser(newUserId, projectId, permission); + } catch (Exception e) { + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 400); + } + + // log the operation + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has added user " + newUserId + " to project " + projectId + " with permission " + permission)); + + Map ret = new HashMap(); + ret.put("success", true); + return WebUtility.getResponse(ret, 200); + } + + /** + * Add all users to an project + * @param request + * @param form + * @return + */ + @POST + @Produces("application/json") + @Path("addAllUsers") + public Response addAllUsers(@Context HttpServletRequest request, MultivaluedMap form) { + SecurityAdminUtils adminUtils = null; + User user = null; + String projectId = form.getFirst("projectId"); + String permission = form.getFirst("permission"); + + try { + user = ResourceUtility.getUser(request); + adminUtils = performAdminCheck(request, user); + } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to add all users to project " + projectId + " when not an admin")); + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + + try { + adminUtils.addAllProjectUsers(projectId, permission); + } catch (Exception e) { + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 400); + } + + // log the operation + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has added all users to project " + projectId + " with permission " + permission)); + + Map ret = new HashMap(); + ret.put("success", true); + return WebUtility.getResponse(ret, 200); + } + + /** + * Edit user permission for an project + * @param request + * @param form + * @return + */ + @POST + @Produces("application/json") + @Path("editProjectUserPermission") + public Response editProjectUserPermission(@Context HttpServletRequest request, MultivaluedMap form) { + SecurityAdminUtils adminUtils = null; + User user = null; + + String existingUserId = form.getFirst("id"); + String projectId = form.getFirst("projectId"); + String newPermission = form.getFirst("permission"); + + try { + user = ResourceUtility.getUser(request); + adminUtils = performAdminCheck(request, user); + } catch (IllegalAccessException e) { + logger.error(Constants.STACKTRACE, e); + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to edit user " + existingUserId + " permissions for project " + projectId + " when not an admin")); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + + try { + adminUtils.editProjectUserPermission(existingUserId, projectId, newPermission); + } catch (Exception e) { + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 400); + } + + // log the operation + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has edited user " + existingUserId + " permission to project " + projectId + " with level " + newPermission)); + + Map ret = new HashMap(); + ret.put("success", true); + return WebUtility.getResponse(ret, 200); + } + + /** + * update all user's permission level to new permission level for an project + * @param request + * @param form + * @return + */ + @POST + @Produces("application/json") + @Path("updateProjectUserPermissions") + public Response updateProjectUserPermissions(@Context HttpServletRequest request, MultivaluedMap form) { + SecurityAdminUtils adminUtils = null; + User user = null; + String projectId = form.getFirst("projectId"); + String newPermission = form.getFirst("permission"); + try { + user = ResourceUtility.getUser(request); + adminUtils = performAdminCheck(request, user); + } catch (IllegalAccessException e) { + logger.error(Constants.STACKTRACE, e); + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to edit user permissions for project " + projectId + " when not an admin")); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + + try { + adminUtils.updateProjectUserPermissions(projectId, newPermission); + } catch (Exception e) { + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 400); + } + + // log the operation + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has edited user permissions to project " + projectId + " with level " + newPermission)); + + Map ret = new HashMap(); + ret.put("success", true); + return WebUtility.getResponse(ret, 200); + } + + /** + * Remove user permission for an project + * @param request + * @param form + * @return + */ + @POST + @Produces("application/json") + @Path("removeProjectUserPermission") + public Response removeProjectUserPermission(@Context HttpServletRequest request, MultivaluedMap form) { + SecurityAdminUtils adminUtils = null; + User user = null; + + String existingUserId = form.getFirst("id"); + String projectId = form.getFirst("projectId"); + + try { + user = ResourceUtility.getUser(request); + adminUtils = performAdminCheck(request, user); + } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to remove user " + existingUserId + " from having access to project " + projectId + " when not an admin")); + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + + try { + adminUtils.removeProjectUser(existingUserId, projectId); + } catch (Exception e) { + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 400); + } + + // log the operation + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has removed user " + existingUserId + " from having access to project " + projectId)); + + Map ret = new HashMap(); + ret.put("success", true); + return WebUtility.getResponse(ret, 200); + } + + @POST + @Produces("application/json") + @Path("setProjectGlobal") + public Response setProjectGlobal(@Context HttpServletRequest request, MultivaluedMap form) { + SecurityAdminUtils adminUtils = null; + User user = null; + + String projectId = form.getFirst("projectId"); + boolean isPublic = Boolean.parseBoolean(form.getFirst("public")); + String logPublic = isPublic ? " public " : " private"; + + try { + user = ResourceUtility.getUser(request); + adminUtils = performAdminCheck(request, user); + } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to set the project " + projectId + logPublic + " when not an admin")); + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + + try { + adminUtils.setProjectGlobal(projectId, isPublic); + } catch (Exception e){ + logger.error("Stacktrace: ",e); + Map errorRet = new HashMap(); + errorRet.put("error", "An unexpected error happened. Please try again."); + return WebUtility.getResponse(errorRet, 500); + } + + // log the operation + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has set the project " + projectId + logPublic)); + + Map ret = new HashMap(); + ret.put("success", true); + return WebUtility.getResponse(ret, 200); + } + + /** + * Get users with no access to a given project + * @param request + * @param form + * @return + */ + @GET + @Produces("application/json") + @Path("getProjectUsersNoCredentials") + public Response getProjectUsersNoCredentials(@Context HttpServletRequest request, @QueryParam("projectId") String projectId) { + SecurityAdminUtils adminUtils = null; + User user = null; + try { + user = ResourceUtility.getUser(request); + adminUtils = performAdminCheck(request, user); + } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), " is trying to get all users when not an admin")); + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + List> ret = adminUtils.getProjectUsersNoCredentials(projectId); + return WebUtility.getResponse(ret, 200); + } + +} diff --git a/src/prerna/semoss/web/services/local/auth/AppAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/AppAuthorizationResource.java index 902186a69..27b382205 100644 --- a/src/prerna/semoss/web/services/local/auth/AppAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/AppAuthorizationResource.java @@ -78,7 +78,7 @@ public Response getUserAppPermission(@Context HttpServletRequest request, @Query return WebUtility.getResponse(errorMap, 401); } - String permission = SecurityAppUtils.getActualUserAppPermission(user, appId); + String permission = SecurityAppUtils.getActualUserDatabasePermission(user, appId); if(permission == null) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to pull permission details for app " + appId + " without having proper access")); Map errorMap = new HashMap(); @@ -114,7 +114,7 @@ public Response getAppUsers(@Context HttpServletRequest request, @QueryParam("ap List> ret = null; try { - ret = SecurityAppUtils.getAppUsers(user, appId); + ret = SecurityAppUtils.getDatabaseUsers(user, appId); } catch (IllegalAccessException e) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to pull users for app " + appId + " without having proper access")); logger.error(Constants.STACKTRACE, e); @@ -195,7 +195,7 @@ public Response editAppUserPermission(@Context HttpServletRequest request, Multi String newPermission = form.getFirst("permission"); try { - SecurityAppUtils.editAppUserPermission(user, existingUserId, appId, newPermission); + SecurityAppUtils.editDatabaseUserPermission(user, existingUserId, appId, newPermission); } catch(IllegalAccessException e) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to edit user " + existingUserId + " permissions for app " + appId + " without having proper access")); logger.error(Constants.STACKTRACE, e); @@ -241,7 +241,7 @@ public Response removeAppUserPermission(@Context HttpServletRequest request, Mul String appId = form.getFirst("appId"); try { - SecurityAppUtils.removeAppUser(user, existingUserId, appId); + SecurityAppUtils.removeDatabaseUser(user, existingUserId, appId); } catch (IllegalAccessException e) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to remove user " + existingUserId + " from having access to app " + appId + " without having proper access")); logger.error(Constants.STACKTRACE, e); @@ -296,7 +296,7 @@ public Response setAppGlobal(@Context HttpServletRequest request, MultivaluedMap String logPublic = isPublic ? " public " : " private"; try { - SecurityAppUtils.setAppGlobal(user, appId, isPublic); + SecurityAppUtils.setDatabaseGlobal(user, appId, isPublic); } catch(IllegalAccessException e) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to set the app " + appId + logPublic + " without having proper access")); logger.error(Constants.STACKTRACE, e); @@ -433,7 +433,7 @@ public Response getAppUsersNoCredentials(@Context HttpServletRequest request, @Q List> ret = null; try { - ret = SecurityAppUtils.getAppUsersNoCredentials(user, appId); + ret = SecurityAppUtils.getDatabaseUsersNoCredentials(user, appId); } catch (IllegalAccessException e) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), " is trying to pull users for " + appId + " that do not have credentials without having proper access")); logger.error(Constants.STACKTRACE, e); diff --git a/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java index 71b4793fc..63df07f01 100644 --- a/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/InsightAuthorizationResource.java @@ -19,8 +19,8 @@ import prerna.auth.AccessPermission; import prerna.auth.User; -import prerna.auth.utils.SecurityAppUtils; import prerna.auth.utils.SecurityInsightUtils; +import prerna.auth.utils.SecurityProjectUtils; import prerna.semoss.web.services.local.ResourceUtility; import prerna.util.Constants; import prerna.web.services.util.WebUtility; @@ -31,15 +31,15 @@ public class InsightAuthorizationResource { private static final Logger logger = LogManager.getLogger(InsightAuthorizationResource.class); /** - * Get the insights the user can edit in the app + * Get the insights the user can edit in the project * @param request * @param form * @return */ @GET @Produces("application/json") - @Path("getAppInsights") - public Response getAppInsights(@Context HttpServletRequest request, @QueryParam("appId") String appId) { + @Path("getProjectInsights") + public Response getProjectInsights(@Context HttpServletRequest request, @QueryParam("projectId") String projectId) { User user = null; try { user = ResourceUtility.getUser(request); @@ -51,7 +51,7 @@ public Response getAppInsights(@Context HttpServletRequest request, @QueryParam( return WebUtility.getResponse(errorMap, 401); } - List> ret = SecurityInsightUtils.getUserEditableInsighs(user, appId); + List> ret = SecurityInsightUtils.getUserEditableInsighs(user, projectId); return WebUtility.getResponse(ret, 200); } @@ -64,7 +64,7 @@ public Response getAppInsights(@Context HttpServletRequest request, @QueryParam( @GET @Produces("application/json") @Path("getUserInsightPermission") - public Response getUserInsightPermission(@Context HttpServletRequest request, @QueryParam("appId") String appId, @QueryParam("insightId") String insightId) { + public Response getUserInsightPermission(@Context HttpServletRequest request, @QueryParam("projectId") String projectId, @QueryParam("insightId") String insightId) { User user = null; try { user = ResourceUtility.getUser(request); @@ -76,9 +76,9 @@ public Response getUserInsightPermission(@Context HttpServletRequest request, @Q return WebUtility.getResponse(errorMap, 401); } - String permission = SecurityInsightUtils.getActualUserInsightPermission(user, appId, insightId); + String permission = SecurityInsightUtils.getActualUserInsightPermission(user, projectId, insightId); if(permission == null) { - logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to pull permission details for insight " + insightId + " in app " + appId + " without having proper access")); + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to pull permission details for insight " + insightId + " in project " + projectId + " without having proper access")); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, "User does not have access to this insight"); return WebUtility.getResponse(errorMap, 401); @@ -98,7 +98,7 @@ public Response getUserInsightPermission(@Context HttpServletRequest request, @Q @GET @Produces("application/json") @Path("getInsightUsers") - public Response getInsightUsers(@Context HttpServletRequest request, @QueryParam("appId") String appId, @QueryParam("insightId") String insightId) { + public Response getInsightUsers(@Context HttpServletRequest request, @QueryParam("projectId") String projectId, @QueryParam("insightId") String insightId) { User user = null; try { user = ResourceUtility.getUser(request); @@ -112,9 +112,9 @@ public Response getInsightUsers(@Context HttpServletRequest request, @QueryParam List> ret = null; try { - ret = SecurityInsightUtils.getInsightUsers(user, appId, insightId); + ret = SecurityInsightUtils.getInsightUsers(user, projectId, insightId); } catch (IllegalAccessException e) { - logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to pull permission details for insight " + insightId + " in app " + appId + " without having proper access")); + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to pull permission details for insight " + insightId + " in project " + projectId + " without having proper access")); logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); @@ -146,16 +146,16 @@ public Response addInsightUserPermission(@Context HttpServletRequest request, Mu } String newUserId = form.getFirst("id"); - String appId = form.getFirst("appId"); + String projectId = form.getFirst("projectId"); String insightId = form.getFirst("insightId"); String permission = form.getFirst("permission"); // add the person with read only access if they do not have access to the app - if(SecurityAppUtils.getUserAppPermission(newUserId, appId) == null) { + if(SecurityProjectUtils.getUserProjectPermission(newUserId, projectId) == null) { try { - SecurityAppUtils.addAppUser(user, newUserId, appId, AccessPermission.READ_ONLY.getPermission()); + SecurityProjectUtils.addProjectUser(user, newUserId, projectId, AccessPermission.READ_ONLY.getPermission()); } catch(IllegalAccessException e) { - logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to add user " + newUserId + " to insight " + insightId + " in app " + appId + " without having proper access")); + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to add user " + newUserId + " to insight " + insightId + " in project " + projectId + " without having proper access")); logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); @@ -169,7 +169,7 @@ public Response addInsightUserPermission(@Context HttpServletRequest request, Mu } try { - SecurityInsightUtils.addInsightUser(user, newUserId, appId, insightId, permission); + SecurityInsightUtils.addInsightUser(user, newUserId, projectId, insightId, permission); } catch (Exception e) { logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); @@ -178,7 +178,7 @@ public Response addInsightUserPermission(@Context HttpServletRequest request, Mu } // log the operation - logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has added user " + newUserId + " to insight " + insightId + " in app " + appId + " with permission " + permission)); + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has added user " + newUserId + " to insight " + insightId + " in project " + projectId + " with permission " + permission)); Map ret = new HashMap(); ret.put("success", true); @@ -207,14 +207,14 @@ public Response editInsightUserPermission(@Context HttpServletRequest request, M } String existingUserId = form.getFirst("id"); - String appId = form.getFirst("appId"); + String projectId = form.getFirst("projectId"); String insightId = form.getFirst("insightId"); String newPermission = form.getFirst("permission"); try { - SecurityInsightUtils.editInsightUserPermission(user, existingUserId, appId, insightId, newPermission); + SecurityInsightUtils.editInsightUserPermission(user, existingUserId, projectId, insightId, newPermission); } catch(IllegalAccessException e) { - logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to edit user " + existingUserId + " permissions for insight " + insightId + " in app " + appId + " without having proper access")); + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to edit user " + existingUserId + " permissions for insight " + insightId + " in project " + projectId + " without having proper access")); logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); @@ -227,7 +227,7 @@ public Response editInsightUserPermission(@Context HttpServletRequest request, M } // log the operation - logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has edited user " + existingUserId + " permission to insight " + insightId + " in app " + appId + " with level " + newPermission)); + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has edited user " + existingUserId + " permission to insight " + insightId + " in project " + projectId + " with level " + newPermission)); Map ret = new HashMap(); ret.put("success", true); @@ -256,13 +256,13 @@ public Response removeInsightUserPermission(@Context HttpServletRequest request, } String existingUserId = form.getFirst("id"); - String appId = form.getFirst("appId"); + String projectId = form.getFirst("projectId"); String insightId = form.getFirst("insightId"); try { - SecurityInsightUtils.removeInsightUser(user, existingUserId, appId, insightId); + SecurityInsightUtils.removeInsightUser(user, existingUserId, projectId, insightId); } catch(IllegalAccessException e) { - logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to remove user " + existingUserId + " from having access to insight " + insightId + " in app " + appId + " without having proper access")); + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to remove user " + existingUserId + " from having access to insight " + insightId + " in project " + projectId + " without having proper access")); logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); @@ -275,7 +275,7 @@ public Response removeInsightUserPermission(@Context HttpServletRequest request, } // log the operation - logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has removed user " + existingUserId + " from having access to insight " + insightId + " in app " + appId)); + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has removed user " + existingUserId + " from having access to insight " + insightId + " in project " + projectId)); Map ret = new HashMap(); ret.put("success", true); @@ -303,13 +303,13 @@ public Response setInsightGlobal(@Context HttpServletRequest request, Multivalue return WebUtility.getResponse(errorMap, 401); } - String appId = form.getFirst("appId"); + String projectId = form.getFirst("projectId"); String insightId = form.getFirst("insightId"); boolean isPublic = Boolean.parseBoolean(form.getFirst("isPublic")); String logPublic = isPublic ? " public " : " private"; try { - SecurityInsightUtils.setInsightGlobalWithinApp(user, appId, insightId, isPublic); + SecurityInsightUtils.setInsightGlobalWithinApp(user, projectId, insightId, isPublic); /* * BELOW COMMENTED OUT IS INVALID LOGIC @@ -326,7 +326,7 @@ public Response setInsightGlobal(@Context HttpServletRequest request, Multivalue // ClusterUtil.reactorPushInsightDB(appId); } catch (IllegalAccessException e) { - logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to set the insight " + insightId + " in app " + appId + logPublic + " without having proper access")); + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to set the insight " + insightId + " in project " + projectId + logPublic + " without having proper access")); logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); @@ -339,7 +339,7 @@ public Response setInsightGlobal(@Context HttpServletRequest request, Multivalue } // log the operation - logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has set the insight " + insightId + " in app " + appId + logPublic)); + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has set the insight " + insightId + " in project " + projectId + logPublic)); Map ret = new HashMap(); ret.put("success", true); @@ -350,12 +350,13 @@ public Response setInsightGlobal(@Context HttpServletRequest request, Multivalue * Set the insight as favorited by the user * @param request * @param form + * @param appId * @return */ @POST @Produces("application/json") @Path("setInsightFavorite") - public Response setInsightFavorite(@Context HttpServletRequest request, MultivaluedMap form) { + public Response setInsightFavorite(@Context HttpServletRequest request, MultivaluedMap form, String appId) { User user = null; try { user = ResourceUtility.getUser(request); @@ -367,15 +368,15 @@ public Response setInsightFavorite(@Context HttpServletRequest request, Multival return WebUtility.getResponse(errorMap, 401); } - String appId = form.getFirst("appId"); + String projectId = form.getFirst("projectId"); String insightId = form.getFirst("insightId"); boolean isFavorite = Boolean.parseBoolean(form.getFirst("isFavorite")); String logFavorited = isFavorite ? " favorited " : " not favorited"; try { - SecurityInsightUtils.setInsightFavorite(user, appId, insightId, isFavorite); + SecurityInsightUtils.setInsightFavorite(user, projectId, insightId, isFavorite); } catch (IllegalAccessException e) { - logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to set the insight " + insightId + " in app " + appId + logFavorited + " without having proper access")); + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to set the insight " + insightId + " in project " + projectId + logFavorited + " without having proper access")); logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); @@ -388,7 +389,7 @@ public Response setInsightFavorite(@Context HttpServletRequest request, Multival } // log the operation - logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has set the insight " + insightId + " in app " + appId + logFavorited)); + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has set the insight " + insightId + " in project " + appId + logFavorited)); Map ret = new HashMap(); ret.put("success", true); @@ -404,7 +405,7 @@ public Response setInsightFavorite(@Context HttpServletRequest request, Multival @GET @Produces("application/json") @Path("getInsightUsersNoCredentials") - public Response getInsightUsersNoCredentials(@Context HttpServletRequest request, @QueryParam("appId") String appId, @QueryParam("insightId") String insightId) { + public Response getInsightUsersNoCredentials(@Context HttpServletRequest request, @QueryParam("projectId") String projectId, @QueryParam("insightId") String insightId) { User user = null; try { user = ResourceUtility.getUser(request); @@ -418,9 +419,9 @@ public Response getInsightUsersNoCredentials(@Context HttpServletRequest request List> ret = null; try { - ret = SecurityInsightUtils.getInsightUsersNoCredentials(user, appId, insightId); + ret = SecurityInsightUtils.getInsightUsersNoCredentials(user, projectId, insightId); } catch (IllegalAccessException e) { - logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), " is trying to pull users without access to insight " + insightId + " in app " + appId + " without having proper access")); + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), " is trying to pull users without access to insight " + insightId + " in project " + projectId + " without having proper access")); logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); diff --git a/src/prerna/semoss/web/services/local/auth/ProjectAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/ProjectAuthorizationResource.java new file mode 100644 index 000000000..bc4b11026 --- /dev/null +++ b/src/prerna/semoss/web/services/local/auth/ProjectAuthorizationResource.java @@ -0,0 +1,446 @@ +package prerna.semoss.web.services.local.auth; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.core.Response; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import prerna.auth.User; +import prerna.auth.utils.SecurityProjectUtils; +import prerna.semoss.web.services.local.ResourceUtility; +import prerna.util.Constants; +import prerna.web.services.util.WebUtility; + +@Path("/auth/project") +public class ProjectAuthorizationResource { + + private static final Logger logger = LogManager.getLogger(ProjectAuthorizationResource.class); + + @Context + protected ServletContext context; + + /** + * Get the apps the user has access to + * @param request + * @return + */ + @GET + @Produces("application/json") + @Path("getProjects") + public Response getUserProjects(@Context HttpServletRequest request) { + User user = null; + try { + user = ResourceUtility.getUser(request); + } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "invalid user session trying to access authorization resources")); + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put("error", "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + + return WebUtility.getResponse(SecurityProjectUtils.getAllUserProjectSettings(user), 200); + } + + /** + * Get the user app permission level + * @param request + * @param form + * @return + */ + @GET + @Produces("application/json") + @Path("getUserProjectPermission") + public Response getUserProjectPermission(@Context HttpServletRequest request, @QueryParam("projectId") String projectId) { + User user = null; + try { + user = ResourceUtility.getUser(request); + } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "invalid user session trying to access authorization resources")); + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + + String permission = SecurityProjectUtils.getActualUserProjectPermission(user, projectId); + if(permission == null) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to pull permission details for project " + projectId + " without having proper access")); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, "User does not have access to this project"); + return WebUtility.getResponse(errorMap, 401); + } + + Map ret = new HashMap(); + ret.put("permission", permission); + return WebUtility.getResponse(ret, 200); + } + + /** + * Get the app users and their permissions + * @param request + * @param form + * @return + */ + @GET + @Produces("application/json") + @Path("getProjectUsers") + public Response getProjectUsers(@Context HttpServletRequest request, @QueryParam("projectId") String projectId) { + User user = null; + try { + user = ResourceUtility.getUser(request); + } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "invalid user session trying to access authorization resources")); + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + + List> ret = null; + try { + ret = SecurityProjectUtils.getProjectUsers(user, projectId); + } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to pull users for project " + projectId + " without having proper access")); + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + + return WebUtility.getResponse(ret, 200); + } + + /** + * Add a user to an app + * @param request + * @param form + * @return + */ + @POST + @Produces("application/json") + @Path("addProjectUserPermission") + public Response addProjectUserPermission(@Context HttpServletRequest request, MultivaluedMap form) { + User user = null; + try { + user = ResourceUtility.getUser(request); + } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "invalid user session trying to access authorization resources")); + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + + String newUserId = form.getFirst("id"); + String projectId = form.getFirst("projectId"); + String permission = form.getFirst("permission"); + + try { + SecurityProjectUtils.addProjectUser(user, newUserId, projectId, permission); + } catch (Exception e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to add a user for app " + projectId + " without having proper access")); + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 400); + } + + // log the operation + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has added user " + newUserId + " to project " + projectId + " with permission " + permission)); + + Map ret = new HashMap(); + ret.put("success", true); + return WebUtility.getResponse(ret, 200); + } + + /** + * Edit user permission for an app + * @param request + * @param form + * @return + */ + @POST + @Produces("application/json") + @Path("editProjectUserPermission") + public Response editProjectUserPermission(@Context HttpServletRequest request, MultivaluedMap form) { + User user = null; + try { + user = ResourceUtility.getUser(request); + } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "invalid user session trying to access authorization resources")); + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + + String existingUserId = form.getFirst("id"); + String projectId = form.getFirst("projectId"); + String newPermission = form.getFirst("permission"); + + try { + SecurityProjectUtils.editProjectUserPermission(user, existingUserId, projectId, newPermission); + } catch(IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to edit user " + existingUserId + " permissions for project " + projectId + " without having proper access")); + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 400); + } catch (Exception e) { + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 400); + } + + // log the operation + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has edited user " + existingUserId + " permission to project " + projectId + " with level " + newPermission)); + + Map ret = new HashMap(); + ret.put("success", true); + return WebUtility.getResponse(ret, 200); + } + + /** + * Remove user permission for an app + * @param request + * @param form + * @return + */ + @POST + @Produces("application/json") + @Path("removeProjectUserPermission") + public Response removeProjectUserPermission(@Context HttpServletRequest request, MultivaluedMap form) { + User user = null; + try { + user = ResourceUtility.getUser(request); + } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "invalid user session trying to access authorization resources")); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + + String existingUserId = form.getFirst("id"); + String projectId = form.getFirst("projectId"); + + try { + SecurityProjectUtils.removeProjectUser(user, existingUserId, projectId); + } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to remove user " + existingUserId + " from having access to project " + projectId + " without having proper access")); + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 400); + } catch (Exception e) { + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 400); + } + + // log the operation + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has removed user " + existingUserId + " from having access to project " + projectId)); + + Map ret = new HashMap(); + ret.put("success", true); + return WebUtility.getResponse(ret, 200); + } + + /** + * Get the app as being global (read only) for the entire semoss instance + * @param request + * @param form + * @return + */ + @POST + @Produces("application/json") + @Path("setProjectGlobal") + public Response setProjectGlobal(@Context HttpServletRequest request, MultivaluedMap form) { + boolean onlyAdmin = Boolean.parseBoolean(context.getInitParameter(Constants.ADMIN_SET_PUBLIC)); + if(onlyAdmin) { + Map errorMap = new HashMap(); + errorMap.put("error", "For this instance, only admins are allowed to set specific apps global"); + return WebUtility.getResponse(errorMap, 400); + } + + User user = null; + try { + user = ResourceUtility.getUser(request); + } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "invalid user session trying to access authorization resources")); + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + + String projectId = form.getFirst("projectId"); + boolean isPublic = Boolean.parseBoolean(form.getFirst("public")); + String logPublic = isPublic ? " public " : " private"; + + try { + SecurityProjectUtils.setProjectGlobal(user, projectId, isPublic); + } catch(IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to set the project " + projectId + logPublic + " without having proper access")); + logger.error(Constants.STACKTRACE, e); + Map errorRet = new HashMap(); + errorRet.put("error", e.getMessage()); + return WebUtility.getResponse(errorRet, 400); + } catch (Exception e){ + logger.error(Constants.STACKTRACE, e); + Map errorRet = new HashMap(); + errorRet.put("error", "An unexpected error happened. Please try again."); + return WebUtility.getResponse(errorRet, 500); + } + + // log the operation + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has set the project " + projectId + logPublic)); + + Map ret = new HashMap(); + ret.put("success", true); + return WebUtility.getResponse(ret, 200); + } + + /** + * Set the app visibility for the user to be seen + * @param request + * @param form + * @return + */ + @POST + @Produces("application/json") + @Path("setProjectVisibility") + public Response setProjectVisibility(@Context HttpServletRequest request, MultivaluedMap form) { + User user = null; + try { + user = ResourceUtility.getUser(request); + } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "invalid user session trying to access authorization resources")); + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put("error", "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + + String projectId = form.getFirst("projectId"); + boolean visible = Boolean.parseBoolean(form.getFirst("visibility")); + String logVisible = visible ? " visible " : " not visible"; + + try { + SecurityProjectUtils.setProjectVisibility(user, projectId, visible); + } catch(IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to set the project " + projectId + logVisible + " without having proper access")); + logger.error(Constants.STACKTRACE, e); + Map errorRet = new HashMap(); + errorRet.put("error", e.getMessage()); + return WebUtility.getResponse(errorRet, 400); + } catch (Exception e){ + logger.error(Constants.STACKTRACE, e); + Map errorRet = new HashMap(); + errorRet.put("error", "An unexpected error happened. Please try again."); + return WebUtility.getResponse(errorRet, 500); + } + + // log the operation + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has set the project " + projectId + logVisible)); + + return WebUtility.getResponse(true, 200); + } + + /** + * Set the app as favorited by the user + * @param request + * @param form + * @return + */ + @POST + @Produces("application/json") + @Path("setProjectFavorite") + public Response setProjectFavorite(@Context HttpServletRequest request, MultivaluedMap form) { + User user = null; + try { + user = ResourceUtility.getUser(request); + } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "invalid user session trying to access authorization resources")); + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put("error", "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + + String projectId = form.getFirst("projectId"); + boolean isFavorite = Boolean.parseBoolean(form.getFirst("isFavorite")); + String logFavorited = isFavorite ? " favorited " : " not favorited"; + + try { + SecurityProjectUtils.setProjectFavorite(user, projectId, isFavorite); + } catch(IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to set the project " + projectId + logFavorited + " without having proper access")); + logger.error(Constants.STACKTRACE, e); + Map errorRet = new HashMap(); + errorRet.put("error", e.getMessage()); + return WebUtility.getResponse(errorRet, 400); + } catch (Exception e){ + logger.error(Constants.STACKTRACE, e); + Map errorRet = new HashMap(); + errorRet.put("error", "An unexpected error happened. Please try again."); + return WebUtility.getResponse(errorRet, 500); + } + + // log the operation + logger.info(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "has set the project " + projectId + logFavorited)); + + return WebUtility.getResponse(true, 200); + } + + /** + * Get users with no access to a given app + * @param request + * @param form + * @return + */ + @GET + @Produces("application/json") + @Path("getProjectUsersNoCredentials") + public Response getProjectUsersNoCredentials(@Context HttpServletRequest request, @QueryParam("projectId") String projectId) { + User user = null; + try { + user = ResourceUtility.getUser(request); + } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), " invalid user session trying to access authorization resources")); + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, "User session is invalid"); + return WebUtility.getResponse(errorMap, 401); + } + + List> ret = null; + try { + ret = SecurityProjectUtils.getProjectUsersNoCredentials(user, projectId); + } catch (IllegalAccessException e) { + logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), " is trying to pull users for " + projectId + " that do not have credentials without having proper access")); + logger.error(Constants.STACKTRACE, e); + Map errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + + return WebUtility.getResponse(ret, 200); + } + +} diff --git a/src/prerna/semoss/web/services/remote/EngineRemoteResource.java b/src/prerna/semoss/web/services/remote/EngineRemoteResource.java index 9239dfa8a..aa234bfbf 100644 --- a/src/prerna/semoss/web/services/remote/EngineRemoteResource.java +++ b/src/prerna/semoss/web/services/remote/EngineRemoteResource.java @@ -201,13 +201,13 @@ public StreamingOutput execAskQuery(@FormParam("query") String query) { // return WebUtility.getSO(coreEngine.getParamValues(label, type, insightId, query)); // } - @POST - @Path("getInsightDefinition") - @Produces("application/text") - public String getInsightDefinition() { - logger.info("ENgine is " + coreEngine); - return coreEngine.getInsightDefinition(); - } +// @POST +// @Path("getInsightDefinition") +// @Produces("application/text") +// public String getInsightDefinition() { +// logger.info("ENgine is " + coreEngine); +// return coreEngine.getInsightDefinition(); +// } @POST @Path("getOWLDefinition") diff --git a/src/prerna/upload/FileUploader.java b/src/prerna/upload/FileUploader.java index 50e19e1f0..77efc6221 100644 --- a/src/prerna/upload/FileUploader.java +++ b/src/prerna/upload/FileUploader.java @@ -216,7 +216,7 @@ public Response baseUpload(@Context ServletContext context, @Context HttpServlet return WebUtility.getResponse(errorMap, 400); } - if(in.isSavedInsight() && !SecurityInsightUtils.userCanEditInsight(user, in.getEngineId(), in.getRdbmsId())) { + if(in.isSavedInsight() && !SecurityInsightUtils.userCanEditInsight(user, in.getProjectId(), in.getRdbmsId())) { HashMap errorMap = new HashMap(); errorMap.put("errorMessage", "User does not edit access for this insight"); return WebUtility.getResponse(errorMap, 400); @@ -229,7 +229,7 @@ public Response baseUpload(@Context ServletContext context, @Context HttpServlet } if(appId != null && !appId.equalsIgnoreCase("user")) { - if (!SecurityAppUtils.userCanEditEngine(in.getUser(), appId)) { + if (!SecurityAppUtils.userCanEditDatabase(in.getUser(), appId)) { HashMap errorMap = new HashMap(); errorMap.put("errorMessage", "User does not have permission for this app."); return WebUtility.getResponse(errorMap, 400); diff --git a/src/prerna/upload/ImageUploader.java b/src/prerna/upload/ImageUploader.java index 9a597bd48..b09e71ddc 100644 --- a/src/prerna/upload/ImageUploader.java +++ b/src/prerna/upload/ImageUploader.java @@ -26,6 +26,7 @@ import prerna.auth.utils.AbstractSecurityUtils; import prerna.auth.utils.SecurityAppUtils; import prerna.auth.utils.SecurityInsightUtils; +import prerna.auth.utils.SecurityProjectUtils; import prerna.auth.utils.SecurityQueryUtils; import prerna.cluster.util.CloudClient; import prerna.cluster.util.ClusterUtil; @@ -44,13 +45,13 @@ public class ImageUploader extends Uploader { private static final Logger logger = LogManager.getLogger(ImageUploader.class); @POST - @Path("/appImage/upload") + @Path("/databaseImage/upload") @Produces("application/json") - public Response uploadAppImage(@Context ServletContext context, @Context HttpServletRequest request) throws SQLException { + public Response uploadDatabaseImage(@Context ServletContext context, @Context HttpServletRequest request) throws SQLException { Map returnMap = new HashMap<>(); // base path is the db folder - String filePath = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER) + DIR_SEPARATOR + "db"; + String filePath = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER) + DIR_SEPARATOR + Constants.DATABASE_FOLDER; filePath = Utility.normalizePath(filePath); List fileItems = processRequest(context, request, null); @@ -65,7 +66,7 @@ public Response uploadAppImage(@Context ServletContext context, @Context HttpSer if (fieldName.equals("file")) { imageFile = fi; } - if (fieldName.equals("app")) { + if (fieldName.equals("databaseId")) { appName = value; } } @@ -74,7 +75,7 @@ public Response uploadAppImage(@Context ServletContext context, @Context HttpSer returnMap.put(Constants.ERROR_MESSAGE, "Could not find the file to upload for the insight in the request"); return WebUtility.getResponse(returnMap, 400); } else if (appName == null) { - returnMap.put(Constants.ERROR_MESSAGE, "Need to pass the proper app id to upload the image"); + returnMap.put(Constants.ERROR_MESSAGE, "Need to pass the proper database id to upload the image"); return WebUtility.getResponse(returnMap, 400); } @@ -84,34 +85,34 @@ public Response uploadAppImage(@Context ServletContext context, @Context HttpSer User user = ((User) session.getAttribute(Constants.SESSION_USER)); if (user == null) { HashMap errorMap = new HashMap<>(); - errorMap.put(Constants.ERROR_MESSAGE, "Session could not be validated in order to upload the app image"); + errorMap.put(Constants.ERROR_MESSAGE, "Session could not be validated in order to upload the database image"); return WebUtility.getResponse(errorMap, 400); } if (user.isAnonymous()) { HashMap errorMap = new HashMap<>(); - errorMap.put(Constants.ERROR_MESSAGE, "Must be logged in to upload an app image"); + errorMap.put(Constants.ERROR_MESSAGE, "Must be logged in to upload an database image"); return WebUtility.getResponse(errorMap, 400); } try { - appId = SecurityQueryUtils.testUserEngineIdForAlias(user, appName); + appId = SecurityQueryUtils.testUserDatabaseIdForAlias(user, appName); } catch (Exception e) { returnMap.put(Constants.ERROR_MESSAGE, e.getMessage()); return WebUtility.getResponse(returnMap, 400); } - if (!SecurityAppUtils.userCanEditEngine(user, appId)) { - returnMap.put(Constants.ERROR_MESSAGE, "User does not have access to this app or the app id does not exist"); + if (!SecurityAppUtils.userCanEditDatabase(user, appId)) { + returnMap.put(Constants.ERROR_MESSAGE, "User does not have access to this database or the database id does not exist"); return WebUtility.getResponse(returnMap, 400); } - appName = SecurityQueryUtils.getEngineAliasForId(appId); + appName = SecurityQueryUtils.getDatabaseAliasForId(appId); } else { returnMap.put(Constants.ERROR_MESSAGE, "User session is invalid"); return WebUtility.getResponse(returnMap, 400); } } else { - appId = MasterDatabaseUtility.testEngineIdIfAlias(appName); - appName = MasterDatabaseUtility.getEngineAliasForId(appId); + appId = MasterDatabaseUtility.testDatabaseIdIfAlias(appName); + appName = MasterDatabaseUtility.getDatabaseAliasForId(appId); String appDir = filePath + DIR_SEPARATOR + SmssUtilities.getUniqueName(appName, appId); if (!(new File(appDir).exists())) { returnMap.put(Constants.ERROR_MESSAGE, "Could not find app directory"); @@ -119,8 +120,8 @@ public Response uploadAppImage(@Context ServletContext context, @Context HttpSer } } - String imageDir = getImageDir(filePath, appId, appName); - String imageLoc = getImageLoc(filePath, appId, appName, imageFile); + String imageDir = getDbImageDir(filePath, appId, appName); + String imageLoc = getDbImageLoc(filePath, appId, appName, imageFile); File f = new File(imageDir); if (!f.exists()) { @@ -151,7 +152,7 @@ public Response uploadAppImage(@Context ServletContext context, @Context HttpSer writeFile(imageFile, f); try { if (ClusterUtil.IS_CLUSTER) { - CloudClient.getClient().pushImageFolder(); + CloudClient.getClient().pushAppImageFolder(); } } catch (IOException ioe) { logger.error(Constants.STACKTRACE, ioe); @@ -161,24 +162,24 @@ public Response uploadAppImage(@Context ServletContext context, @Context HttpSer } returnMap.put("message", "Successfully updated app image"); - returnMap.put("app_id", appId); - returnMap.put("app_name", appName); + returnMap.put("database_id", appId); + returnMap.put("database_name", appName); return WebUtility.getResponse(returnMap, 200); } @POST - @Path("/appImage/delete") - public Response deleteAppImage(@Context HttpServletRequest request) throws SQLException { + @Path("/databaseImage/delete") + public Response deleteDatabaseImage(@Context HttpServletRequest request) throws SQLException { Map returnMap = new HashMap<>(); // base path is the db folder String filePath = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER) + DIR_SEPARATOR + "db"; filePath = Utility.normalizePath(filePath); - String appId = request.getParameter("appId"); + String appId = request.getParameter("databaseId"); String appName = null; if(appId == null) { - returnMap.put(Constants.ERROR_MESSAGE, "Need to pass the proper app id to remove the image"); + returnMap.put(Constants.ERROR_MESSAGE, "Need to pass the proper database id to remove the image"); return WebUtility.getResponse(returnMap, 400); } @@ -188,34 +189,34 @@ public Response deleteAppImage(@Context HttpServletRequest request) throws SQLEx User user = ((User) session.getAttribute(Constants.SESSION_USER)); if (user == null) { HashMap errorMap = new HashMap<>(); - errorMap.put(Constants.ERROR_MESSAGE, "Session could not be validated in order to upload the app image"); + errorMap.put(Constants.ERROR_MESSAGE, "Session could not be validated in order to upload the database image"); return WebUtility.getResponse(errorMap, 400); } if (user.isAnonymous()) { HashMap errorMap = new HashMap<>(); - errorMap.put(Constants.ERROR_MESSAGE, "Must be logged in to upload an app image"); + errorMap.put(Constants.ERROR_MESSAGE, "Must be logged in to upload an database image"); return WebUtility.getResponse(errorMap, 400); } try { - appId = SecurityQueryUtils.testUserEngineIdForAlias(user, appId); + appId = SecurityQueryUtils.testUserDatabaseIdForAlias(user, appId); } catch (Exception e) { returnMap.put(Constants.ERROR_MESSAGE, e.getMessage()); return WebUtility.getResponse(returnMap, 400); } - if (!SecurityAppUtils.userCanEditEngine(user, appId)) { - returnMap.put(Constants.ERROR_MESSAGE, "User does not have access to this app or the app id does not exist"); + if (!SecurityAppUtils.userCanEditDatabase(user, appId)) { + returnMap.put(Constants.ERROR_MESSAGE, "User does not have access to this app or the database id does not exist"); return WebUtility.getResponse(returnMap, 400); } - appName = SecurityQueryUtils.getEngineAliasForId(appId); + appName = SecurityQueryUtils.getDatabaseAliasForId(appId); } else { returnMap.put(Constants.ERROR_MESSAGE, "User session is invalid"); return WebUtility.getResponse(returnMap, 400); } } else { - appId = MasterDatabaseUtility.testEngineIdIfAlias(appId); - appName = MasterDatabaseUtility.getEngineAliasForId(appId); + appId = MasterDatabaseUtility.testDatabaseIdIfAlias(appId); + appName = MasterDatabaseUtility.getDatabaseAliasForId(appId); String appDir = filePath + DIR_SEPARATOR + SmssUtilities.getUniqueName(appName, appId); if (!(new File(appDir).exists())) { returnMap.put(Constants.ERROR_MESSAGE, "Could not find app directory"); @@ -223,7 +224,7 @@ public Response deleteAppImage(@Context HttpServletRequest request) throws SQLEx } } - String imageDir = getImageDir(filePath, appId, appName); + String imageDir = getDbImageDir(filePath, appId, appName); File f = new File(imageDir); File[] oldImages = null; if (ClusterUtil.IS_CLUSTER) { @@ -244,7 +245,7 @@ public Response deleteAppImage(@Context HttpServletRequest request) throws SQLEx try { if (ClusterUtil.IS_CLUSTER) { - CloudClient.getClient().pushImageFolder(); + CloudClient.getClient().pushAppImageFolder(); } } catch (IOException ioe) { logger.error(Constants.STACKTRACE, ioe); @@ -253,28 +254,249 @@ public Response deleteAppImage(@Context HttpServletRequest request) throws SQLEx logger.error(Constants.STACKTRACE, ie); } - returnMap.put("app_id", appId); - returnMap.put("app_name", appName); - returnMap.put("message", "Successfully deleted app image"); + returnMap.put("database_id", appId); + returnMap.put("database_name", appName); + returnMap.put("message", "Successfully deleted database image"); return WebUtility.getResponse(returnMap, 200); } - - private String getImageDir(String filePath, String appId, String appName) { + + private String getDbImageDir(String filePath, String appId, String appName) { if(ClusterUtil.IS_CLUSTER){ - return ClusterUtil.IMAGES_FOLDER_PATH + DIR_SEPARATOR + "apps"; + return ClusterUtil.IMAGES_FOLDER_PATH + DIR_SEPARATOR + "databases"; } - //return filePath + DIR_SEPARATOR + SmssUtilities.getUniqueName(appName, appId) + DIR_SEPARATOR + "version"; - return AssetUtility.getAppAssetVersionFolder(appName, appId); + String baseFolder = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER); + String versionFolder = baseFolder + DIR_SEPARATOR + Constants.DB_FOLDER + DIR_SEPARATOR + SmssUtilities.getUniqueName(appName, appId) + + DIR_SEPARATOR + "version"; + return versionFolder; } - private String getImageLoc(String filePath, String appId, String appName, FileItem imageFile){ - String imageDir = getImageDir(filePath, appId, appName); + private String getDbImageLoc(String filePath, String id, String name, FileItem imageFile){ + String imageDir = getProjectImageDir(filePath, id, name); if(ClusterUtil.IS_CLUSTER){ - return imageDir + DIR_SEPARATOR + appId + "." + imageFile.getContentType().split("/")[1]; + return imageDir + DIR_SEPARATOR + id + "." + imageFile.getContentType().split("/")[1]; } return imageDir + DIR_SEPARATOR + "image." + imageFile.getContentType().split("/")[1]; } + @POST + @Path("/projectImage/upload") + @Produces("application/json") + public Response uploadProjectImage(@Context ServletContext context, @Context HttpServletRequest request) throws SQLException { + Map returnMap = new HashMap<>(); + + // base path is the db folder + String filePath = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER) + DIR_SEPARATOR + Constants.PROJECT_FOLDER; + filePath = Utility.normalizePath(filePath); + + List fileItems = processRequest(context, request, null); + // collect all of the data input on the form + FileItem imageFile = null; + String projectId = null; + String projectName = null; + + for (FileItem fi : fileItems) { + String fieldName = fi.getFieldName(); + String value = fi.getString(); + if (fieldName.equals("file")) { + imageFile = fi; + } + if (fieldName.equals("project")) { + projectId = value; + } + } + + if (imageFile == null) { + returnMap.put(Constants.ERROR_MESSAGE, "Could not find the file to upload for the insight in the request"); + return WebUtility.getResponse(returnMap, 400); + } else if (projectId == null) { + returnMap.put(Constants.ERROR_MESSAGE, "Need to pass the proper project id to upload the image"); + return WebUtility.getResponse(returnMap, 400); + } + + if (AbstractSecurityUtils.securityEnabled()) { + HttpSession session = request.getSession(false); + if (session != null) { + User user = ((User) session.getAttribute(Constants.SESSION_USER)); + if (user == null) { + HashMap errorMap = new HashMap<>(); + errorMap.put(Constants.ERROR_MESSAGE, "Session could not be validated in order to upload the project image"); + return WebUtility.getResponse(errorMap, 400); + } + + if (user.isAnonymous()) { + HashMap errorMap = new HashMap<>(); + errorMap.put(Constants.ERROR_MESSAGE, "Must be logged in to upload an project image"); + return WebUtility.getResponse(errorMap, 400); + } + + try { + projectId = SecurityProjectUtils.testUserProjectIdForAlias(user, projectId); + } catch (Exception e) { + returnMap.put(Constants.ERROR_MESSAGE, e.getMessage()); + return WebUtility.getResponse(returnMap, 400); + } + if (!SecurityProjectUtils.userCanEditProject(user, projectId)) { + returnMap.put(Constants.ERROR_MESSAGE, "User does not have access to edit this project"); + return WebUtility.getResponse(returnMap, 400); + } + projectName = SecurityQueryUtils.getDatabaseAliasForId(projectId); + } else { + returnMap.put(Constants.ERROR_MESSAGE, "User session is invalid"); + return WebUtility.getResponse(returnMap, 400); + } + } +// else { +// projectId = MasterDatabaseUtility.testEngineIdIfAlias(projectName); +// projectName = MasterDatabaseUtility.getEngineAliasForId(projectId); +// String appDir = filePath + DIR_SEPARATOR + SmssUtilities.getUniqueName(projectName, projectId); +// if (!(new File(appDir).exists())) { +// returnMap.put(Constants.ERROR_MESSAGE, "Could not find app directory"); +// return WebUtility.getResponse(returnMap, 400); +// } +// } + + String imageDir = getProjectImageDir(filePath, projectId, projectName); + String imageLoc = getProjectImageLoc(filePath, projectId, projectName, imageFile); + + File f = new File(imageDir); + if (!f.exists()) { + Boolean success = f.mkdirs(); + if(!success) { + logger.info("Unable to make direction at location: " + Utility.cleanLogString(filePath)); + } + } + f = new File(imageLoc); + // find all the existing image files + // and delete them + File[] oldImages = null; + if (ClusterUtil.IS_CLUSTER) { + FilenameFilter appIdFilter = new WildcardFileFilter(projectId + "*"); + oldImages = f.getParentFile().listFiles(appIdFilter); + } else { + oldImages = InsightUtility.findImageFile(f.getParentFile()); + } + // delete if any exist + if (oldImages != null) { + for (File oldI : oldImages) { + Boolean success = oldI.delete(); + if (!success) { + logger.info("Unable to delete file at location: " + Utility.cleanLogString(oldI.getAbsolutePath())); + } + } + } + writeFile(imageFile, f); + try { + if (ClusterUtil.IS_CLUSTER) { + CloudClient.getClient().pushProjectImageFolder(); + } + } catch (IOException ioe) { + logger.error(Constants.STACKTRACE, ioe); + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); + logger.error(Constants.STACKTRACE, ie); + } + + returnMap.put("message", "Successfully updated project image"); + returnMap.put("app_id", projectId); + returnMap.put("app_name", projectName); + return WebUtility.getResponse(returnMap, 200); + } + + @POST + @Path("/projectImage/delete") + public Response deleteProjectImage(@Context HttpServletRequest request) throws SQLException { + Map returnMap = new HashMap<>(); + + // base path is the db folder + String filePath = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER) + DIR_SEPARATOR + Constants.PROJECT; + filePath = Utility.normalizePath(filePath); + + String projectId = request.getParameter("projectId"); + String projectName = null; + if(projectId == null) { + returnMap.put(Constants.ERROR_MESSAGE, "Need to pass the proper project id to remove the image"); + return WebUtility.getResponse(returnMap, 400); + } + + if (AbstractSecurityUtils.securityEnabled()) { + HttpSession session = request.getSession(false); + if (session != null) { + User user = ((User) session.getAttribute(Constants.SESSION_USER)); + if (user == null) { + HashMap errorMap = new HashMap<>(); + errorMap.put(Constants.ERROR_MESSAGE, "Session could not be validated in order to upload the project image"); + return WebUtility.getResponse(errorMap, 400); + } + + if (user.isAnonymous()) { + HashMap errorMap = new HashMap<>(); + errorMap.put(Constants.ERROR_MESSAGE, "Must be logged in to upload an project image"); + return WebUtility.getResponse(errorMap, 400); + } + + try { + projectId = SecurityProjectUtils.testUserProjectIdForAlias(user, projectId); + } catch (Exception e) { + returnMap.put(Constants.ERROR_MESSAGE, e.getMessage()); + return WebUtility.getResponse(returnMap, 400); + } + if (!SecurityProjectUtils.userCanEditProject(user, projectId)) { + returnMap.put(Constants.ERROR_MESSAGE, "User does not have access to this project or the project id does not exist"); + return WebUtility.getResponse(returnMap, 400); + } + projectName = SecurityQueryUtils.getProjectAliasForId(projectId); + } else { + returnMap.put(Constants.ERROR_MESSAGE, "User session is invalid"); + return WebUtility.getResponse(returnMap, 400); + } + } +// else { +// projectId = MasterDatabaseUtility.testEngineIdIfAlias(projectId); +// projectName = MasterDatabaseUtility.getEngineAliasForId(projectId); +// String appDir = filePath + DIR_SEPARATOR + SmssUtilities.getUniqueName(projectName, projectId); +// if (!(new File(appDir).exists())) { +// returnMap.put(Constants.ERROR_MESSAGE, "Could not find app directory"); +// return WebUtility.getResponse(returnMap, 400); +// } +// } + + String imageDir = getProjectImageDir(filePath, projectId, projectName); + File f = new File(imageDir); + File[] oldImages = null; + if (ClusterUtil.IS_CLUSTER) { + FilenameFilter appIdFilter = new WildcardFileFilter(projectId + "*"); + oldImages = f.listFiles(appIdFilter); + } else { + oldImages = InsightUtility.findImageFile(f); + } + // delete if any exist + if (oldImages != null) { + for (File oldI : oldImages) { + Boolean success = oldI.delete(); + if (!success) { + logger.info("Unable to delete file at location: " + Utility.cleanLogString(oldI.getAbsolutePath())); + } + } + } + + try { + if (ClusterUtil.IS_CLUSTER) { + CloudClient.getClient().pushProjectImageFolder(); + } + } catch (IOException ioe) { + logger.error(Constants.STACKTRACE, ioe); + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); + logger.error(Constants.STACKTRACE, ie); + } + + returnMap.put("project_id", projectId); + returnMap.put("project_name", projectName); + returnMap.put("message", "Successfully deleted project image"); + return WebUtility.getResponse(returnMap, 200); + } + + @POST @Path("/insightImage/upload") @Produces("application/json") @@ -282,14 +504,14 @@ public Response uploadInsightImage(@Context ServletContext context, @Context Htt Map returnMap = new HashMap<>(); // base path is the db folder - String filePath = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER) + DIR_SEPARATOR + "db"; + String filePath = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER) + DIR_SEPARATOR + Constants.PROJECT_FOLDER; filePath = Utility.normalizePath(filePath); List fileItems = processRequest(context, request, null); // collect all of the data input on the form FileItem imageFile = null; - String appId = null; - String appName = null; + String projectId = null; + String projectName = null; String insightId = null; for (FileItem fi : fileItems) { @@ -298,8 +520,8 @@ public Response uploadInsightImage(@Context ServletContext context, @Context Htt if (fieldName.equals("file")) { imageFile = fi; } - if (fieldName.equals("app")) { - appName = value; + if(fieldName.equals("projectId")) { + projectId = value; } if (fieldName.equals("insightId")) { insightId = value; @@ -309,8 +531,8 @@ public Response uploadInsightImage(@Context ServletContext context, @Context Htt if (imageFile == null) { returnMap.put(Constants.ERROR_MESSAGE, "Could not find the file to upload for the insight in the request"); return WebUtility.getResponse(returnMap, 400); - } else if (appName == null || insightId == null) { - returnMap.put(Constants.ERROR_MESSAGE, "Need to pass the proper app and insight ids to upload the image"); + } else if (projectId == null || insightId == null) { + returnMap.put(Constants.ERROR_MESSAGE, "Need to pass the proper project and insight ids to upload the image"); return WebUtility.getResponse(returnMap, 400); } @@ -331,35 +553,35 @@ public Response uploadInsightImage(@Context ServletContext context, @Context Htt } try { - appId = SecurityQueryUtils.testUserEngineIdForAlias(user, appName); + projectId = SecurityProjectUtils.testUserProjectIdForAlias(user, projectId); } catch (Exception e) { returnMap.put(Constants.ERROR_MESSAGE, e.getMessage()); return WebUtility.getResponse(returnMap, 400); } - if (!SecurityInsightUtils.userCanEditInsight(user, appId, insightId)) { - returnMap.put(Constants.ERROR_MESSAGE, "User does not have access to edit this insight within the app"); + if (!SecurityInsightUtils.userCanEditInsight(user, projectId, insightId)) { + returnMap.put(Constants.ERROR_MESSAGE, "User does not have access to edit this insight within the project"); return WebUtility.getResponse(returnMap, 400); } - appName = SecurityQueryUtils.getEngineAliasForId(appId); + projectName = SecurityQueryUtils.getDatabaseAliasForId(projectId); } else { returnMap.put(Constants.ERROR_MESSAGE, "User session is invalid"); return WebUtility.getResponse(returnMap, 400); } - } else { - appId = MasterDatabaseUtility.testEngineIdIfAlias(appName); - appName = MasterDatabaseUtility.getEngineAliasForId(appId); - String appDir = filePath + DIR_SEPARATOR + SmssUtilities.getUniqueName(appName, appId); - if (!(new File(appDir).exists())) { - returnMap.put(Constants.ERROR_MESSAGE, "Could not find app directory"); - return WebUtility.getResponse(returnMap, 400); - } - } + } +// else { +// projectId = MasterDatabaseUtility.testEngineIdIfAlias(projectName); +// projectName = MasterDatabaseUtility.getEngineAliasForId(projectId); +// String appDir = filePath + DIR_SEPARATOR + SmssUtilities.getUniqueName(projectName, projectId); +// if (!(new File(appDir).exists())) { +// returnMap.put(Constants.ERROR_MESSAGE, "Could not find app directory"); +// return WebUtility.getResponse(returnMap, 400); +// } +// } // now that we have the app name // and the image file - // we want to write it into the app location - //String imageDir = filePath + DIR_SEPARATOR + SmssUtilities.getUniqueName(appName, appId) + DIR_SEPARATOR + "version" + DIR_SEPARATOR + insightId; - String imageDir = AssetUtility.getAppAssetVersionFolder(appName, appId) + DIR_SEPARATOR + insightId; + // we want to write it into the project location + String imageDir = AssetUtility.getProjectAssetVersionFolder(projectName, projectId) + DIR_SEPARATOR + insightId; File f = new File(imageDir); if (!f.exists()) { Boolean success = f.mkdirs(); @@ -385,8 +607,8 @@ public Response uploadInsightImage(@Context ServletContext context, @Context Htt f = new File(imageLoc); writeFile(imageFile, f); - returnMap.put("app_id", appId); - returnMap.put("app_name", appName); + returnMap.put("project_id", projectId); + returnMap.put("project_name", projectName); returnMap.put("insight_id", insightId); returnMap.put("message", "Successfully updated insight image"); return WebUtility.getResponse(returnMap, 200); @@ -398,14 +620,14 @@ public Response deleteInsightImage(@Context HttpServletRequest request) throws S Map returnMap = new HashMap<>(); // base path is the db folder - String filePath = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER) + DIR_SEPARATOR + "db"; + String filePath = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER) + DIR_SEPARATOR + Constants.PROJECT_FOLDER; filePath = Utility.normalizePath(filePath); - String appId = request.getParameter("appId"); - String appName = null; + String projectId = request.getParameter("projectId"); + String projectName = null; String insightId = request.getParameter("insightId"); - if(appId == null) { - returnMap.put(Constants.ERROR_MESSAGE, "Need to pass the proper app id to remove the image"); + if(projectId == null) { + returnMap.put(Constants.ERROR_MESSAGE, "Need to pass the proper project id to remove the image"); return WebUtility.getResponse(returnMap, 400); } if(insightId == null) { @@ -430,34 +652,35 @@ public Response deleteInsightImage(@Context HttpServletRequest request) throws S } try { - appId = SecurityQueryUtils.testUserEngineIdForAlias(user, appId); + projectId = SecurityProjectUtils.testUserProjectIdForAlias(user, projectId); } catch (Exception e) { returnMap.put(Constants.ERROR_MESSAGE, e.getMessage()); return WebUtility.getResponse(returnMap, 400); } - if (!SecurityAppUtils.userCanEditEngine(user, appId)) { - returnMap.put(Constants.ERROR_MESSAGE, "User does not have access to this app or the app id does not exist"); + if (!SecurityProjectUtils.userCanEditProject(user, projectId)) { + returnMap.put(Constants.ERROR_MESSAGE, "User does not have access to this project or the project id does not exist"); return WebUtility.getResponse(returnMap, 400); } - appName = SecurityQueryUtils.getEngineAliasForId(appId); + projectName = SecurityQueryUtils.getDatabaseAliasForId(projectId); } else { returnMap.put(Constants.ERROR_MESSAGE, "User session is invalid"); return WebUtility.getResponse(returnMap, 400); } - } else { - appId = MasterDatabaseUtility.testEngineIdIfAlias(appId); - appName = MasterDatabaseUtility.getEngineAliasForId(appId); - String appDir = filePath + DIR_SEPARATOR + SmssUtilities.getUniqueName(appName, appId); - if (!(new File(appDir).exists())) { - returnMap.put(Constants.ERROR_MESSAGE, "Could not find app directory"); - return WebUtility.getResponse(returnMap, 400); - } - } + } +// else { +// projectId = MasterDatabaseUtility.testEngineIdIfAlias(projectId); +// projectName = MasterDatabaseUtility.getEngineAliasForId(projectId); +// String appDir = filePath + DIR_SEPARATOR + SmssUtilities.getUniqueName(projectName, projectId); +// if (!(new File(appDir).exists())) { +// returnMap.put(Constants.ERROR_MESSAGE, "Could not find app directory"); +// return WebUtility.getResponse(returnMap, 400); +// } +// } // now that we have the app name // and the image file // we want to write it into the app location - String imageDir = AssetUtility.getAppAssetVersionFolder(appName, appId) + DIR_SEPARATOR + insightId; + String imageDir = AssetUtility.getProjectAssetVersionFolder(projectName, projectId) + DIR_SEPARATOR + insightId; File f = new File(Utility.normalizePath(imageDir)); if (f.exists()) { // find all the existing image files @@ -477,11 +700,26 @@ public Response deleteInsightImage(@Context HttpServletRequest request) throws S return WebUtility.getResponse(returnMap, 400); } - returnMap.put("app_id", appId); - returnMap.put("app_name", appName); + returnMap.put("project_id", projectId); + returnMap.put("project_name", projectName); returnMap.put("insight_id", insightId); returnMap.put("message", "Successfully deleted insight image"); return WebUtility.getResponse(returnMap, 200); } + private String getProjectImageDir(String filePath, String projectId, String projectName) { + if(ClusterUtil.IS_CLUSTER){ + return ClusterUtil.IMAGES_FOLDER_PATH + DIR_SEPARATOR + "projects"; + } + return AssetUtility.getProjectAssetVersionFolder(projectName, projectId); + } + + private String getProjectImageLoc(String filePath, String id, String name, FileItem imageFile){ + String imageDir = getProjectImageDir(filePath, id, name); + if(ClusterUtil.IS_CLUSTER){ + return imageDir + DIR_SEPARATOR + id + "." + imageFile.getContentType().split("/")[1]; + } + return imageDir + DIR_SEPARATOR + "image." + imageFile.getContentType().split("/")[1]; + } + } diff --git a/src/prerna/web/conf/DBLoader.java b/src/prerna/web/conf/DBLoader.java index 903fae262..dda33164e 100644 --- a/src/prerna/web/conf/DBLoader.java +++ b/src/prerna/web/conf/DBLoader.java @@ -168,9 +168,12 @@ public void contextInitialized(ServletContextEvent arg0) { // Load empty engine list into DIHelper, then load engines from db folder logger.log(STARTUP, "Loading engines..."); String engines = ""; - DIHelper.getInstance().setLocalProperty(Constants.ENGINES, engines); - loadEngines(); - + DIHelper.getInstance().setDbProperty(Constants.ENGINES, engines); + loadSmss(Constants.ENGINE_WEB_WATCHER); + String projects = ""; + DIHelper.getInstance().setProjectProperty(Constants.PROJECTS, projects); + loadSmss(Constants.PROJECT_WATCHER); + // //Just load R right away to avoid synchronization issues // try { // RJavaTranslatorFactory.initRConnection(); @@ -185,10 +188,10 @@ public void contextInitialized(ServletContextEvent arg0) { // if there was an issue starting up the server // we should do it here so that we can redirect the user { - IEngine localmaster = (IEngine) DIHelper.getInstance().getLocalProp(Constants.LOCAL_MASTER_DB_NAME); - IEngine security = (IEngine) DIHelper.getInstance().getLocalProp(Constants.SECURITY_DB); + IEngine localmaster = (IEngine) DIHelper.getInstance().getDbProperty(Constants.LOCAL_MASTER_DB_NAME); + IEngine security = (IEngine) DIHelper.getInstance().getDbProperty(Constants.SECURITY_DB); // TODO: will make scheduler a requirement - IEngine scheduler = (IEngine) DIHelper.getInstance().getLocalProp(Constants.SCHEDULER_DB); + IEngine scheduler = (IEngine) DIHelper.getInstance().getDbProperty(Constants.SCHEDULER_DB); // if (localmaster == null || security == null || scheduler == null || !localmaster.isConnected() || !security.isConnected() || !scheduler.isConnected()) { if (localmaster == null || security == null || !localmaster.isConnected() || !security.isConnected() ) { // you have messed up!!! @@ -208,8 +211,8 @@ public void contextInitialized(ServletContextEvent arg0) { } } - public void loadEngines() { - StringTokenizer watchers = new StringTokenizer(DIHelper.getInstance().getProperty(Constants.ENGINE_WEB_WATCHER), ";"); + public void loadSmss(String pathKey) { + StringTokenizer watchers = new StringTokenizer(DIHelper.getInstance().getProperty(pathKey), ";"); try { while (watchers.hasMoreElements()) { Object monitor = new Object(); @@ -250,10 +253,10 @@ public void contextDestroyed(ServletContextEvent arg0) { } // we need to close all the engine ids - List eIds = MasterDatabaseUtility.getAllEngineIds(); + List eIds = MasterDatabaseUtility.getAllDatabaseIds(); for (String id : eIds) { // grab only loaded engines - IEngine engine = (IEngine) DIHelper.getInstance().getLocalProp(id); + IEngine engine = (IEngine) DIHelper.getInstance().getDbProperty(id); if (engine != null) { // if it is loaded, close it logger.log(SHUTDOWN, "Closing database " + id); diff --git a/src/prerna/web/conf/PublicHomeCheckFilter.java b/src/prerna/web/conf/PublicHomeCheckFilter.java index cfec28baf..40b5b3441 100644 --- a/src/prerna/web/conf/PublicHomeCheckFilter.java +++ b/src/prerna/web/conf/PublicHomeCheckFilter.java @@ -11,16 +11,12 @@ import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; -import org.owasp.encoder.Encode; - import com.google.common.base.Strings; import prerna.auth.User; -import prerna.nameserver.utility.MasterDatabaseUtility; -import prerna.sablecc2.reactor.mgmt.MgmtUtil; +import prerna.auth.utils.SecurityProjectUtils; import prerna.util.Constants; import prerna.util.DIHelper; import prerna.util.Settings; @@ -73,7 +69,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 // this is engine id ?! why are we splitting! //String [] engTokens = possibleEngineId.split("__"); - String alias = MasterDatabaseUtility.getEngineAliasForId(possibleEngineId); + String alias = SecurityProjectUtils.getProjectAliasForId(possibleEngineId); if(!Strings.isNullOrEmpty(alias) && !Strings.isNullOrEmpty(possibleEngineId)) { boolean appAllowed = user.checkAppAccess(alias, possibleEngineId); @@ -85,7 +81,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 if(appAllowed) { - boolean mapComplete = Utility.getEngine(possibleEngineId).publish(realPath + public_home, possibleEngineId); + boolean mapComplete = Utility.getProject(possibleEngineId).publish(realPath + public_home, possibleEngineId); if(mapComplete) { arg2.doFilter(arg0, arg1); From 57bd6501fc84a9a816a66b2d8d553d35a1771527 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Mon, 26 Jul 2021 19:27:31 +0000 Subject: [PATCH 0807/1906] UPDATE ::: Fixing the path for rdfmap git-svn-id: svn://107.170.10.188:8080/Monolith/dev@44249 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 3ee3de8e3db7d570aa28108182d27dea443d40b8 --- WebContent/WEB-INF/web.xml | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/WebContent/WEB-INF/web.xml b/WebContent/WEB-INF/web.xml index 4cb54f552..a137da6fd 100644 --- a/WebContent/WEB-INF/web.xml +++ b/WebContent/WEB-INF/web.xml @@ -18,6 +18,7 @@ SetCharacterEncoding /* + HeaderSecurityFilter org.apache.catalina.filters.HttpHeaderSecurityFilter @@ -39,6 +40,7 @@ /* + StartUpSuccessFilter @@ -195,7 +197,7 @@ updateUserInfo false - + countUserEntry false @@ -227,7 +229,7 @@ + + + FilespaceAccessFilter + prerna.web.conf.FilespaceAccessFilter + + + FilespaceAccessFilter + /public_home/* + + + FilespaceAccessFilter + /public_home/* + @@ -395,7 +410,6 @@ AdminApplication /adminconfig/* - isLog4jAutoInitializationDisabled @@ -403,7 +417,7 @@ log4jConfiguration - file:///C:/workspace/Semoss_Dev/log4j2.properties + file:///C:/workspace3/Semoss_Dev/log4j2.properties security-enabled @@ -463,10 +477,8 @@ 120 monolith - \ No newline at end of file From 9540a47cc4b9d6856e793ba9befb129e253dd744 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 27 Jul 2021 23:20:38 +0000 Subject: [PATCH 0808/1906] UPDATE ::: Adding initial shell for websockets git-svn-id: svn://107.170.10.188:8080/Monolith/dev@44271 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 635b5d7a4336880d05435c01b394bdd0928dd778 --- src/prerna/websocket/PixelWebsocket.java | 46 +++++++++++++++++++ .../websocket/SocketSessionHandler.java | 39 ++++++++++++++++ .../SocketSessionHandlerFactory.java | 13 ++++++ 3 files changed, 98 insertions(+) create mode 100644 src/prerna/websocket/PixelWebsocket.java create mode 100644 src/prerna/websocket/SocketSessionHandler.java create mode 100644 src/prerna/websocket/SocketSessionHandlerFactory.java diff --git a/src/prerna/websocket/PixelWebsocket.java b/src/prerna/websocket/PixelWebsocket.java new file mode 100644 index 000000000..8602b7573 --- /dev/null +++ b/src/prerna/websocket/PixelWebsocket.java @@ -0,0 +1,46 @@ +package prerna.websocket; + +import javax.websocket.OnClose; +import javax.websocket.OnError; +import javax.websocket.OnMessage; +import javax.websocket.OnOpen; +import javax.websocket.Session; +import javax.websocket.server.ServerEndpoint; + +import org.json.JSONObject; + +import prerna.om.Insight; +import prerna.om.InsightStore; +import prerna.sablecc2.PixelRunner; + +@ServerEndpoint("/pixelSocket") +public class PixelWebsocket { + + @OnOpen + public void open(Session session) { + SocketSessionHandlerFactory.getHandler().addSession(session); + } + + @OnClose + public void close(Session session) { + SocketSessionHandlerFactory.getHandler().removeSession(session); + } + + @OnError + public void onError(Throwable error) { + throw new RuntimeException(error); + } + + @OnMessage + public void handleMessage(String message, Session session) { + JSONObject json = new JSONObject(message); + String insightId = json.getString("insightId"); + String pixelString = json.getString("pixel"); + + Insight in = InsightStore.getInstance().get(insightId); + PixelRunner dataReturn = in.runPixel(pixelString); + + SocketSessionHandler handler = SocketSessionHandlerFactory.getHandler(); + handler.updateRecipe(dataReturn); + } +} diff --git a/src/prerna/websocket/SocketSessionHandler.java b/src/prerna/websocket/SocketSessionHandler.java new file mode 100644 index 000000000..e8d86284e --- /dev/null +++ b/src/prerna/websocket/SocketSessionHandler.java @@ -0,0 +1,39 @@ +package prerna.websocket; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import javax.websocket.Session; + +import prerna.sablecc2.PixelRunner; +import prerna.sablecc2.PixelStreamUtility; + +public class SocketSessionHandler { + + private List sessions = new ArrayList<>(); + + public void addSession(Session session) { + sessions.add(session); + } + + public void removeSession(Session session) { + sessions.remove(session); + } + + private void sendReturnData(PixelRunner runner) { + String message = PixelStreamUtility.collectPixelData(runner, null).toString(); + for(Session session : sessions) { + try { + session.getBasicRemote().sendText(message); + } catch (IOException e) { + removeSession(session); + } + } + } + + public void updateRecipe(PixelRunner runner) { + sendReturnData(runner); + } + +} diff --git a/src/prerna/websocket/SocketSessionHandlerFactory.java b/src/prerna/websocket/SocketSessionHandlerFactory.java new file mode 100644 index 000000000..9c660fc90 --- /dev/null +++ b/src/prerna/websocket/SocketSessionHandlerFactory.java @@ -0,0 +1,13 @@ +package prerna.websocket; + +public class SocketSessionHandlerFactory { + + private static SocketSessionHandler handler; + + public static SocketSessionHandler getHandler() { + if(handler == null) { + handler = new SocketSessionHandler(); + } + return handler; + } +} From f4b0379b2b98f40f91feb72ce0c019a7320b5183 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 28 Jul 2021 12:06:07 +0000 Subject: [PATCH 0809/1906] UPDATE ::: Modifying payload for websocket testing git-svn-id: svn://107.170.10.188:8080/Monolith/dev@44274 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 067998d82d8d575815fc4314c8755e2e936763a8 --- src/prerna/websocket/PixelWebsocket.java | 31 ++++++++++++++++--- .../websocket/SocketSessionHandler.java | 10 ++---- 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/src/prerna/websocket/PixelWebsocket.java b/src/prerna/websocket/PixelWebsocket.java index 8602b7573..99eadcb1a 100644 --- a/src/prerna/websocket/PixelWebsocket.java +++ b/src/prerna/websocket/PixelWebsocket.java @@ -1,17 +1,23 @@ package prerna.websocket; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + import javax.websocket.OnClose; import javax.websocket.OnError; import javax.websocket.OnMessage; import javax.websocket.OnOpen; import javax.websocket.Session; import javax.websocket.server.ServerEndpoint; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.StreamingOutput; import org.json.JSONObject; import prerna.om.Insight; import prerna.om.InsightStore; import prerna.sablecc2.PixelRunner; +import prerna.sablecc2.PixelStreamUtility; @ServerEndpoint("/pixelSocket") public class PixelWebsocket { @@ -37,10 +43,27 @@ public void handleMessage(String message, Session session) { String insightId = json.getString("insightId"); String pixelString = json.getString("pixel"); - Insight in = InsightStore.getInstance().get(insightId); - PixelRunner dataReturn = in.runPixel(pixelString); - + Insight in = null; + if(insightId == null || (insightId = insightId.trim()).isEmpty() + || insightId.equalsIgnoreCase("new")) { + in = new Insight(); + InsightStore.getInstance().put(in); + } else { + in = InsightStore.getInstance().get(insightId); + } + PixelRunner runner = in.runPixel(pixelString); + StreamingOutput streamingOutput = PixelStreamUtility.collectPixelData(runner, null); + final ByteArrayOutputStream baos = new ByteArrayOutputStream(); + try { + streamingOutput.write(baos); + } catch (WebApplicationException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + String returnData = new String(baos.toByteArray()); + SocketSessionHandler handler = SocketSessionHandlerFactory.getHandler(); - handler.updateRecipe(dataReturn); + handler.updateRecipe(returnData); } } diff --git a/src/prerna/websocket/SocketSessionHandler.java b/src/prerna/websocket/SocketSessionHandler.java index e8d86284e..c0f5fa58d 100644 --- a/src/prerna/websocket/SocketSessionHandler.java +++ b/src/prerna/websocket/SocketSessionHandler.java @@ -6,9 +6,6 @@ import javax.websocket.Session; -import prerna.sablecc2.PixelRunner; -import prerna.sablecc2.PixelStreamUtility; - public class SocketSessionHandler { private List sessions = new ArrayList<>(); @@ -21,8 +18,7 @@ public void removeSession(Session session) { sessions.remove(session); } - private void sendReturnData(PixelRunner runner) { - String message = PixelStreamUtility.collectPixelData(runner, null).toString(); + private void sendReturnData(String message) { for(Session session : sessions) { try { session.getBasicRemote().sendText(message); @@ -32,8 +28,8 @@ private void sendReturnData(PixelRunner runner) { } } - public void updateRecipe(PixelRunner runner) { - sendReturnData(runner); + public void updateRecipe(String message) { + sendReturnData(message); } } From a2401e3d601e16d748b2c5d1aeb8e676845f3233 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 28 Jul 2021 12:06:32 +0000 Subject: [PATCH 0810/1906] UPDATE ::: Adding sample html and js for websocket testing git-svn-id: svn://107.170.10.188:8080/Monolith/dev@44275 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: e9edd604ee5bc0d8b584cdd0af1fe289e917d0d0 --- WebContent/websocket/index.html | 18 ++++++++++++++++++ WebContent/websocket/websocket.js | 29 +++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 WebContent/websocket/index.html create mode 100644 WebContent/websocket/websocket.js diff --git a/WebContent/websocket/index.html b/WebContent/websocket/index.html new file mode 100644 index 000000000..81ea4778d --- /dev/null +++ b/WebContent/websocket/index.html @@ -0,0 +1,18 @@ + + + + + + + + +

Pixel Commands

+ +

insight id:

+

pixel:

+ + +
+ + + \ No newline at end of file diff --git a/WebContent/websocket/websocket.js b/WebContent/websocket/websocket.js new file mode 100644 index 000000000..74c91ccee --- /dev/null +++ b/WebContent/websocket/websocket.js @@ -0,0 +1,29 @@ + +var socket = new WebSocket("ws://localhost:9090/Monolith_Dev/pixelSocket"); +socket.onmessage = onMessage; + +function onMessage(event) { + var pixelResponse = JSON.parse(event.data); + displayPixelResponse(pixelResponse); +} + +function displayPixelResponse(pixelResponse) { + var content = document.getElementById("content"); + var div = document.createElement("div"); + + var html = "

New Pixel

"; + html += "

" + JSON.stringify(pixelResponse) + "

"; + + div.innerHTML= html; + content.appendChild(div); +} + +function sendSocket() { + var insightId = document.getElementById("insightId").value; + var pixel = document.getElementById("pixel").value; + var message = { + "insightId" : insightId, + "pixel" : pixel + }; + socket.send(JSON.stringify(message)); +} \ No newline at end of file From 4e81cc32b197cecbc5435fde35c30386a4cf0574 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 28 Jul 2021 12:32:49 +0000 Subject: [PATCH 0811/1906] UPDATE ::: Modifying processing for websocket testing git-svn-id: svn://107.170.10.188:8080/Monolith/dev@44278 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 735358c8a7b54111b4608a7693a03ccb595cf5ed --- src/prerna/websocket/PixelWebsocket.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/prerna/websocket/PixelWebsocket.java b/src/prerna/websocket/PixelWebsocket.java index 99eadcb1a..551037572 100644 --- a/src/prerna/websocket/PixelWebsocket.java +++ b/src/prerna/websocket/PixelWebsocket.java @@ -12,6 +12,8 @@ import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.StreamingOutput; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.json.JSONObject; import prerna.om.Insight; @@ -22,13 +24,17 @@ @ServerEndpoint("/pixelSocket") public class PixelWebsocket { + private static final Logger logger = LogManager.getLogger(PixelWebsocket.class); + @OnOpen public void open(Session session) { + logger.info("Creating new socket session"); SocketSessionHandlerFactory.getHandler().addSession(session); } @OnClose public void close(Session session) { + logger.info("Closing socket session"); SocketSessionHandlerFactory.getHandler().removeSession(session); } @@ -41,7 +47,10 @@ public void onError(Throwable error) { public void handleMessage(String message, Session session) { JSONObject json = new JSONObject(message); String insightId = json.getString("insightId"); - String pixelString = json.getString("pixel"); + String pixelString = json.getString("pixel").trim(); + if(!pixelString.endsWith(";")) { + pixelString = pixelString + ";"; + } Insight in = null; if(insightId == null || (insightId = insightId.trim()).isEmpty() From 4b5f66f72903233546c44da3451848ac3d6b1abf Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 28 Jul 2021 14:01:50 +0000 Subject: [PATCH 0812/1906] UPDATE ::: Modifying the SetContext to take in the project id instead of the project name UPDATE ::: Maps now are id => name instead of name => id for being stored in the user object BUGFIX ::: Fixing places to use project instead of database permissions git-svn-id: svn://107.170.10.188:8080/Monolith/dev@44280 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: e3849d92b71ca5f696e0cc96f7370ac7480f395a --- src/prerna/web/conf/FilespaceAccessFilter.java | 2 +- src/prerna/web/conf/PublicHomeCheckFilter.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/prerna/web/conf/FilespaceAccessFilter.java b/src/prerna/web/conf/FilespaceAccessFilter.java index 324f83666..8a8e93357 100644 --- a/src/prerna/web/conf/FilespaceAccessFilter.java +++ b/src/prerna/web/conf/FilespaceAccessFilter.java @@ -47,7 +47,7 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha String appRoot = appHome.substring(0, appRootIndex); String [] appRootElements = appRoot.split("__"); User user = (User)hsr.getSession().getAttribute(Constants.SESSION_USER); - if(user.checkAppAccess(appRootElements[0], appRootElements[1])) + if(user.checkProjectAccess(appRootElements[0], appRootElements[1])) chain.doFilter(request, response); else { diff --git a/src/prerna/web/conf/PublicHomeCheckFilter.java b/src/prerna/web/conf/PublicHomeCheckFilter.java index 40b5b3441..58a70de7a 100644 --- a/src/prerna/web/conf/PublicHomeCheckFilter.java +++ b/src/prerna/web/conf/PublicHomeCheckFilter.java @@ -72,7 +72,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 String alias = SecurityProjectUtils.getProjectAliasForId(possibleEngineId); if(!Strings.isNullOrEmpty(alias) && !Strings.isNullOrEmpty(possibleEngineId)) { - boolean appAllowed = user.checkAppAccess(alias, possibleEngineId); + boolean appAllowed = user.checkProjectAccess(alias, possibleEngineId); File phomeFile = new File(realPath + public_home); // try to create the public home from scratch From 9c92f7f2073af9d21bd31e70e82020459d05fc3a Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 28 Jul 2021 14:24:41 +0000 Subject: [PATCH 0813/1906] UPDATE ::: Adding javax.websocket to the pom.xml git-svn-id: svn://107.170.10.188:8080/Monolith/dev@44284 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: de3845112a72bbb16032ccf1d3bbf48e6f60ca44 --- pom.xml | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/pom.xml b/pom.xml index 434b29fcd..04fc92f61 100644 --- a/pom.xml +++ b/pom.xml @@ -301,6 +301,19 @@ tomcat-catalina 9.0.41
+ + javax.servlet + javax.servlet-api + 3.1.0 + provided + + + + javax.websocket + javax.websocket-api + 1.1 + provided + org.antlr antlr-complete @@ -1190,12 +1203,6 @@ - - javax.servlet - javax.servlet-api - 3.1.0 - provided - net.java.dev.jna jna From 319c5d9c62b8576f2dcf4df47d9ece790dd605ad Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 29 Jul 2021 15:51:15 +0000 Subject: [PATCH 0814/1906] BUGFIX ::: Accounting for SAML for login in form commit git-svn-id: svn://107.170.10.188:8080/Monolith/dev@44299 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: e20cd31257541e1ad617afe1282a978961577810 --- src/prerna/semoss/web/services/local/EngineResource.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/prerna/semoss/web/services/local/EngineResource.java b/src/prerna/semoss/web/services/local/EngineResource.java index 781daba87..07b92e868 100644 --- a/src/prerna/semoss/web/services/local/EngineResource.java +++ b/src/prerna/semoss/web/services/local/EngineResource.java @@ -247,8 +247,13 @@ public Response commitFormData(@Context HttpServletRequest request, MultivaluedM String userId = null; try { HttpSession session = ((HttpServletRequest)request).getSession(false); - User user = (User) session.getAttribute("semoss_user"); - userId = user.getAccessToken(AuthProvider.CAC).getId(); + User user = (User) session.getAttribute(Constants.SESSION_USER); + if(user.getAccessToken(AuthProvider.CAC) != null) { + userId = user.getAccessToken(AuthProvider.CAC).getId(); + } else if(user.getAccessToken(AuthProvider.SAML) != null) { + // if not CAC - we are using SMAL + userId = user.getAccessToken(AuthProvider.SAML).getId(); + } } catch(Exception e) { Map err = new HashMap(); err.put("errorMessage", "Could not identify user"); From 3df310e64dfe89aa2dc75d95acca17121b689838 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 29 Jul 2021 15:53:01 +0000 Subject: [PATCH 0815/1906] UPDATE ::: For legacy version of SEMOSS, also adding in "app" as a new in the noun store if the semoss jar is still a legacy version git-svn-id: svn://107.170.10.188:8080/Monolith/dev@44300 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 950751b77d3f93ddaf7a282c167d97d0fcc83811 --- src/prerna/semoss/web/services/local/EngineResource.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/prerna/semoss/web/services/local/EngineResource.java b/src/prerna/semoss/web/services/local/EngineResource.java index 07b92e868..5283db37e 100644 --- a/src/prerna/semoss/web/services/local/EngineResource.java +++ b/src/prerna/semoss/web/services/local/EngineResource.java @@ -177,6 +177,7 @@ public Response getInsightParams(@QueryParam("insight") String insightId) GenRowStruct grs1 = new GenRowStruct(); grs1.add(new NounMetadata(coreEngine.getEngineId(), PixelDataType.CONST_STRING)); paramR.getNounStore().addNoun(ReactorKeysEnum.DATABASE.getKey(), grs1); + paramR.getNounStore().addNoun("app", grs1); GenRowStruct grs2 = new GenRowStruct(); grs2.add(new NounMetadata(insightId, PixelDataType.CONST_STRING)); paramR.getNounStore().addNoun(ReactorKeysEnum.ID.getKey(), grs2); @@ -226,6 +227,7 @@ public Response createOutput(MultivaluedMap form, @Context HttpS GenRowStruct grs1 = new GenRowStruct(); grs1.add(new NounMetadata(coreEngine.getEngineId(), PixelDataType.CONST_STRING)); playsheetRunReactor.getNounStore().addNoun(ReactorKeysEnum.DATABASE.getKey(), grs1); + playsheetRunReactor.getNounStore().addNoun("app", grs1); GenRowStruct grs2 = new GenRowStruct(); grs2.add(new NounMetadata(insightId, PixelDataType.CONST_STRING)); playsheetRunReactor.getNounStore().addNoun(ReactorKeysEnum.ID.getKey(), grs2); From ff0cd1380ea2f3e253a34f03df51c4eefa90c708 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 29 Jul 2021 15:57:06 +0000 Subject: [PATCH 0816/1906] UPDATE ::: Refactor to make it more clear where the last intermediate push is to help with removing in future git-svn-id: svn://107.170.10.188:8080/Monolith/dev@44301 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 6d7f97fba29aac4a77e3dbfd04c1eff4b9c941c4 --- .../semoss/web/services/local/EngineResource.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/prerna/semoss/web/services/local/EngineResource.java b/src/prerna/semoss/web/services/local/EngineResource.java index 5283db37e..cb3c73f5c 100644 --- a/src/prerna/semoss/web/services/local/EngineResource.java +++ b/src/prerna/semoss/web/services/local/EngineResource.java @@ -75,8 +75,10 @@ public class EngineResource { private static final Logger logger = LogManager.getLogger(EngineResource.class); - private static final String STACKTRACE = "StackTrace: "; + @Deprecated + private static final String APP_KEY = "app"; + // gets everything specific to an engine // essentially this is a wrapper over the engine private IEngine coreEngine = null; @@ -149,7 +151,7 @@ public Response queryDataSelect(MultivaluedMap form) data.add(wrapper.next().getRawValues()); } } catch (Exception e) { - logger.error(STACKTRACE,e); + logger.error(Constants.STACKTRACE,e); } finally { if(wrapper != null) { wrapper.cleanUp(); @@ -177,7 +179,7 @@ public Response getInsightParams(@QueryParam("insight") String insightId) GenRowStruct grs1 = new GenRowStruct(); grs1.add(new NounMetadata(coreEngine.getEngineId(), PixelDataType.CONST_STRING)); paramR.getNounStore().addNoun(ReactorKeysEnum.DATABASE.getKey(), grs1); - paramR.getNounStore().addNoun("app", grs1); + paramR.getNounStore().addNoun(APP_KEY, grs1); GenRowStruct grs2 = new GenRowStruct(); grs2.add(new NounMetadata(insightId, PixelDataType.CONST_STRING)); paramR.getNounStore().addNoun(ReactorKeysEnum.ID.getKey(), grs2); @@ -227,7 +229,7 @@ public Response createOutput(MultivaluedMap form, @Context HttpS GenRowStruct grs1 = new GenRowStruct(); grs1.add(new NounMetadata(coreEngine.getEngineId(), PixelDataType.CONST_STRING)); playsheetRunReactor.getNounStore().addNoun(ReactorKeysEnum.DATABASE.getKey(), grs1); - playsheetRunReactor.getNounStore().addNoun("app", grs1); + playsheetRunReactor.getNounStore().addNoun(APP_KEY, grs1); GenRowStruct grs2 = new GenRowStruct(); grs2.add(new NounMetadata(insightId, PixelDataType.CONST_STRING)); playsheetRunReactor.getNounStore().addNoun(ReactorKeysEnum.ID.getKey(), grs2); @@ -281,7 +283,7 @@ public Response commitFormData(@Context HttpServletRequest request, MultivaluedM FormBuilder.commitFormData(this.coreEngine, engineHash, userId); } } catch(Exception e) { - logger.error(STACKTRACE,e); + logger.error(Constants.STACKTRACE,e); return WebUtility.getResponse(gson.toJson(e.getMessage()), 400); } @@ -298,7 +300,7 @@ public Response getAuditLogForEngine(MultivaluedMap form, @Conte try { auditInfo = FormBuilder.getAuditDataForEngine(this.coreEngine.getEngineId()); } catch(Exception e) { - logger.error(STACKTRACE,e); + logger.error(Constants.STACKTRACE,e); return WebUtility.getResponse(gson.toJson(e.getMessage()), 400); } From be14a75ab11ca26ae8ff447cef016a3024bce235 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 30 Jul 2021 09:17:05 +0000 Subject: [PATCH 0817/1906] BUGFIX ::: Fixing permission fix on file uploading into a project directly git-svn-id: svn://107.170.10.188:8080/Monolith/dev@44326 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 298754de6baece41960d5670986dba8784f5e24b --- src/prerna/upload/FileUploader.java | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/prerna/upload/FileUploader.java b/src/prerna/upload/FileUploader.java index 77efc6221..98bb8cecb 100644 --- a/src/prerna/upload/FileUploader.java +++ b/src/prerna/upload/FileUploader.java @@ -28,13 +28,14 @@ import prerna.auth.User; import prerna.auth.utils.AbstractSecurityUtils; -import prerna.auth.utils.SecurityAppUtils; import prerna.auth.utils.SecurityInsightUtils; +import prerna.auth.utils.SecurityProjectUtils; import prerna.auth.utils.SecurityQueryUtils; import prerna.om.Insight; import prerna.om.InsightStore; import prerna.om.ThreadStore; import prerna.poi.main.HeadersException; +import prerna.project.api.IProject; import prerna.util.AssetUtility; import prerna.util.Constants; import prerna.util.Utility; @@ -188,7 +189,7 @@ public Response checkUserDefinedHeaders(MultivaluedMap form) { public Response baseUpload(@Context ServletContext context, @Context HttpServletRequest request, @QueryParam("insightId") String insightId, @QueryParam("path") String relativePath, - @QueryParam("appId") String appId) { + @QueryParam("projectId") String projectId) { Insight in = InsightStore.getInstance().get(insightId); if(in == null) { HashMap errorMap = new HashMap(); @@ -228,10 +229,10 @@ public Response baseUpload(@Context ServletContext context, @Context HttpServlet return WebUtility.getResponse(errorMap, 400); } - if(appId != null && !appId.equalsIgnoreCase("user")) { - if (!SecurityAppUtils.userCanEditDatabase(in.getUser(), appId)) { + if(projectId != null && !projectId.equalsIgnoreCase("user")) { + if (!SecurityProjectUtils.userCanEditProject(in.getUser(), projectId)) { HashMap errorMap = new HashMap(); - errorMap.put("errorMessage", "User does not have permission for this app."); + errorMap.put("errorMessage", "User does not have permission for this project."); return WebUtility.getResponse(errorMap, 400); } } @@ -241,7 +242,7 @@ public Response baseUpload(@Context ServletContext context, @Context HttpServlet try { List fileItems = processRequest(context, request, insightId); // collect all of the data input on the form - List> inputData = getBaseUploadData(fileItems, in, relativePath, appId); + List> inputData = getBaseUploadData(fileItems, in, relativePath, projectId); // clear the thread store return WebUtility.getResponse(inputData, 200); } catch(Exception e) { @@ -257,15 +258,18 @@ public Response baseUpload(@Context ServletContext context, @Context HttpServlet /** * Method to parse just files and move to the server * @param fileItems a list of maps containing the file name and file location - * @param appDir + * @param in + * @param relativePath + * @param projectId * @return */ - private List> getBaseUploadData(List fileItems, Insight in, String relativePath, String appId) { + private List> getBaseUploadData(List fileItems, Insight in, String relativePath, String projectId) { // get base asset folder String assetFolder = null; String fePath = DIR_SEPARATOR; - if (appId != null) { - assetFolder = AssetUtility.getAssetBasePath(in, appId, true); + if (projectId != null) { + IProject project = Utility.getProject(projectId); + assetFolder = AssetUtility.getProjectAssetFolder(project.getProjectName(), projectId); } else { assetFolder = in.getInsightFolder(); } From 839a73e1018ade4862df57f2728a382487fd4b93 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 30 Jul 2021 09:24:51 +0000 Subject: [PATCH 0818/1906] BUGFIX ::: Fixing project id vs project name for getting the project image git-svn-id: svn://107.170.10.188:8080/Monolith/dev@44328 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 06cc3b11ec5949889f9b8ac14ae19fd35edef8db --- src/prerna/semoss/web/services/local/ProjectResource.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/prerna/semoss/web/services/local/ProjectResource.java b/src/prerna/semoss/web/services/local/ProjectResource.java index de10170c9..756c9d275 100644 --- a/src/prerna/semoss/web/services/local/ProjectResource.java +++ b/src/prerna/semoss/web/services/local/ProjectResource.java @@ -378,9 +378,9 @@ protected File getProjectImageFile(String projectId) { return new File(imageDir + "color-logo.png"); } Properties prop = Utility.loadProperties(propFileLoc); - projectId = prop.getProperty(Constants.PROJECT_ALIAS); + String projectName = prop.getProperty(Constants.PROJECT_ALIAS); - String fileLocation = AssetUtility.getProjectAssetVersionFolder(projectId, projectId); + String fileLocation = AssetUtility.getProjectAssetVersionFolder(projectName, projectId); File f = findImageFile(fileLocation); if(f != null) { return f; From 63a4992d24d5a18f391ce8ad5c21775ef2a0556a Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 30 Jul 2021 09:26:16 +0000 Subject: [PATCH 0819/1906] BUGFIX ::: Fixing database id vs database name for getting the database image git-svn-id: svn://107.170.10.188:8080/Monolith/dev@44329 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 12cba199ce70bfeb3fcda0ef15e1a5e6f729b4ee --- .../web/services/local/AppResource.java | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/prerna/semoss/web/services/local/AppResource.java b/src/prerna/semoss/web/services/local/AppResource.java index d78d97d7b..04fb04d8b 100644 --- a/src/prerna/semoss/web/services/local/AppResource.java +++ b/src/prerna/semoss/web/services/local/AppResource.java @@ -125,26 +125,28 @@ public Response downloadAppImage(@Context final Request coreRequest, @Context Ht /** * Use to find the file for the image - * @param app + * @param appId * @return */ - protected File getAppImageFile(String app) { - String appId = MasterDatabaseUtility.testDatabaseIdIfAlias(app); + protected File getAppImageFile(String appId) { + appId = MasterDatabaseUtility.testDatabaseIdIfAlias(appId); if(ClusterUtil.IS_CLUSTER){ - return ClusterUtil.getDatabaseImage(app); + return ClusterUtil.getDatabaseImage(appId); } String propFileLoc = (String) DIHelper.getInstance().getDbProperty(appId + "_" + Constants.STORE); - if(propFileLoc == null && !app.equals("NEWSEMOSSAPP")) { + if(propFileLoc == null && !appId.equals("NEWSEMOSSAPP")) { String imageDir = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER) + "/images/stock/"; return new File(imageDir + "color-logo.png"); } Properties prop = Utility.loadProperties(propFileLoc); - app = prop.getProperty(Constants.ENGINE_ALIAS); + String appName = prop.getProperty(Constants.ENGINE_ALIAS); String baseFolder = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER); String fileLocation = baseFolder + DIR_SEPARATOR + Constants.DB_FOLDER + DIR_SEPARATOR - + SmssUtilities.getUniqueName(app, appId) + DIR_SEPARATOR + "app_root" + DIR_SEPARATOR + "version"; + + SmssUtilities.getUniqueName(appName, appId) + + DIR_SEPARATOR + "app_root" + DIR_SEPARATOR + "version"; //String fileLocation = AssetUtility.getAppAssetVersionFolder(app, appId); + File f = findImageFile(fileLocation); if(f != null) { return f; @@ -158,8 +160,8 @@ protected File getAppImageFile(String app) { } } fileLocation = fileLocation + DIR_SEPARATOR + "image.png"; - if(app != null) { - TextToGraphic.makeImage(app, fileLocation); + if(appId != null) { + TextToGraphic.makeImage(appId, fileLocation); } else { TextToGraphic.makeImage(appId, fileLocation); } From 920eeccc0f05c09abd6b0cda80be10c0b02f00d4 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 30 Jul 2021 10:47:00 +0000 Subject: [PATCH 0820/1906] BUGFIX ::: Creating the default app/project image using the name instead of the id git-svn-id: svn://107.170.10.188:8080/Monolith/dev@44337 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 229fd5de934668c3850b96289eba348ae0dfc951 --- src/prerna/semoss/web/services/local/AppResource.java | 4 ++-- src/prerna/semoss/web/services/local/ProjectResource.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/prerna/semoss/web/services/local/AppResource.java b/src/prerna/semoss/web/services/local/AppResource.java index 04fb04d8b..b55f50e05 100644 --- a/src/prerna/semoss/web/services/local/AppResource.java +++ b/src/prerna/semoss/web/services/local/AppResource.java @@ -161,9 +161,9 @@ protected File getAppImageFile(String appId) { } fileLocation = fileLocation + DIR_SEPARATOR + "image.png"; if(appId != null) { - TextToGraphic.makeImage(appId, fileLocation); + TextToGraphic.makeImage(appName, fileLocation); } else { - TextToGraphic.makeImage(appId, fileLocation); + TextToGraphic.makeImage(appName, fileLocation); } f = new File(fileLocation); return f; diff --git a/src/prerna/semoss/web/services/local/ProjectResource.java b/src/prerna/semoss/web/services/local/ProjectResource.java index 756c9d275..22b50603c 100644 --- a/src/prerna/semoss/web/services/local/ProjectResource.java +++ b/src/prerna/semoss/web/services/local/ProjectResource.java @@ -395,9 +395,9 @@ protected File getProjectImageFile(String projectId) { } fileLocation = fileLocation + DIR_SEPARATOR + "image.png"; if(projectId != null) { - TextToGraphic.makeImage(projectId, fileLocation); + TextToGraphic.makeImage(projectName, fileLocation); } else { - TextToGraphic.makeImage(projectId, fileLocation); + TextToGraphic.makeImage(projectName, fileLocation); } f = new File(fileLocation); return f; From 7f1c79356652c9dfe4403eb54ad988176c2860b3 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 30 Jul 2021 19:14:43 +0000 Subject: [PATCH 0821/1906] UPDATE ::: Adding same method again but with better endpoint name to eventually update on FE git-svn-id: svn://107.170.10.188:8080/Monolith/dev@44366 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 995ea1b51797a4c4d104e4b3795109e64e3ef468 --- .../auth/AdminUserAuthorizationResource.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/prerna/semoss/web/services/local/auth/AdminUserAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/AdminUserAuthorizationResource.java index 7f5a2d723..1f208c01d 100644 --- a/src/prerna/semoss/web/services/local/auth/AdminUserAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/AdminUserAuthorizationResource.java @@ -203,6 +203,32 @@ public Response deleteUser(@Context HttpServletRequest request, MultivaluedMap errorMap = new HashMap(); + errorMap.put(ResourceUtility.ERROR_KEY, e.getMessage()); + return WebUtility.getResponse(errorMap, 401); + } + + List> ret = adminUtils.getAllUsers(); + return WebUtility.getResponse(ret, 200); + } + + @GET + @Path("/getAllUsers") + @Produces("application/json") public Response getAllUsers(@Context HttpServletRequest request) { SecurityAdminUtils adminUtils = null; User user = null; From bd3f8a4de14230931cf602c0cd907eb0fbc1add9 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 30 Jul 2021 21:46:06 +0000 Subject: [PATCH 0822/1906] BUGFIX ::: Fixing the share file to be a proper POST to match the BE logic git-svn-id: svn://107.170.10.188:8080/Monolith/dev@44370 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 54e6f0c38e89a627c40dfaac8ca46e5cbf0ab396 --- WebContent/share/index.html | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/WebContent/share/index.html b/WebContent/share/index.html index 3b1a8ba24..c37727846 100644 --- a/WebContent/share/index.html +++ b/WebContent/share/index.html @@ -192,23 +192,24 @@ let endpoint = origin.substring(0, origin.lastIndexOf('/') - 5) + 'api/share/i-' + insightId +'/getTableData'; if(insightId && hash && secret && session && endpoint){ - - let form_data = new FormData(); - form_data.append('i', insightId); - form_data.append('hash', hash); - form_data.append(sessionKey, session); - form_data.append('s', secret); - + + var formBody = []; + formBody.push('i' + "=" + encodeURIComponent(insightId)); + formBody.push('hash' + "=" + encodeURIComponent(hash)); + formBody.push(sessionKey + "=" + encodeURIComponent(session)); + formBody.push('s' + "=" + encodeURIComponent(secret)); + // add in the route if we are doing a cloud deployment if(route && route !== '' && routeKey && routeKey !== '') { - form_data.append(routeKey, route); + formBody.push(routeKey + "=" + encodeURIComponent(route)); } + formBody = formBody.join("&"); let response = await fetch(endpoint, { method:'POST', headers:{ - 'Content-Type':'application/x-www-form-urlencoded' + 'Content-Type':'application/x-www-form-urlencoded' }, - body:form_data, + body:formBody, credentials:'include' }); @@ -310,13 +311,13 @@ } else if (param === 'i') { document.getElementById('share_insight').value = decodeURIComponent(params['i']); count++; - } else if (param.indexOf('monolith') === 0 || param === 'JSESSIONID') { - document.getElementById('share_session_key').value = decodeURIComponent(param); - document.getElementById('share_session').value = decodeURIComponent(params[param]); - count++; } else if(param.indexOf('route') === 0) { document.getElementById('share_route_key').value = decodeURIComponent(param); document.getElementById('share_route').value = decodeURIComponent(params[param]); + } else { + document.getElementById('share_session_key').value = decodeURIComponent(param); + document.getElementById('share_session').value = decodeURIComponent(params[param]); + count++; } } From 1250483a317c677d0d741bf74e400dfd5170471a Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 3 Aug 2021 16:03:56 +0000 Subject: [PATCH 0823/1906] UPDATE ::: Adding in tracking options for saml UPDATE ::: Switching cac to track using id instead of email since email certs not guaranteed git-svn-id: svn://107.170.10.188:8080/Monolith/dev@44394 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 8460bbc8bbfd51c8f76ff01234f534f02b3b4a63 --- src/prerna/web/conf/CACFilter.java | 2 +- src/prerna/web/conf/SSOFilter.java | 109 +++++++++++++++++- src/prerna/web/conf/util/UserFileLogUtil.java | 10 +- 3 files changed, 113 insertions(+), 8 deletions(-) diff --git a/src/prerna/web/conf/CACFilter.java b/src/prerna/web/conf/CACFilter.java index 813b7eb25..f725765b6 100644 --- a/src/prerna/web/conf/CACFilter.java +++ b/src/prerna/web/conf/CACFilter.java @@ -209,7 +209,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 // are we logging their information? if(userLogger != null && !token.getName().equals("TOPAZ")) { // grab the ip address - userLogger.addToQueue(new String[] {email, name, LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")), ResourceUtility.getClientIp((HttpServletRequest)arg0)}); + userLogger.addToQueue(new String[] {cacId, name, LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")), ResourceUtility.getClientIp((HttpServletRequest)arg0)}); } // log the user login diff --git a/src/prerna/web/conf/SSOFilter.java b/src/prerna/web/conf/SSOFilter.java index 53500e4a5..933b985d7 100644 --- a/src/prerna/web/conf/SSOFilter.java +++ b/src/prerna/web/conf/SSOFilter.java @@ -1,6 +1,9 @@ package prerna.web.conf; import java.io.IOException; +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; import javax.servlet.Filter; import javax.servlet.FilterChain; @@ -15,10 +18,15 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import prerna.auth.AccessToken; +import prerna.auth.AuthProvider; import prerna.auth.User; +import prerna.semoss.web.services.local.ResourceUtility; import prerna.util.Constants; import prerna.util.Utility; +import prerna.web.conf.util.CACTrackingUtil; import prerna.web.conf.util.SSOUtil; +import prerna.web.conf.util.UserFileLogUtil; /** * Servlet Filter implementation class SamlFilter @@ -29,11 +37,29 @@ public class SSOFilter implements Filter { private static final String SAML_LOGIN_HTML = "/samlLogin/"; + + // filter init params + private static final String COUNT_USER_ENTRY = "countUserEntry"; + private static final String COUNT_USER_ENTRY_DATABASE = "countUserEntryDb"; + private static final String LOG_USER_INFO = "logUserInfo"; + private static final String LOG_USER_INFO_PATH = "logUserInfoPath"; + private static final String LOG_USER_INFO_SEP = "logUserInfoSep"; + + // realization of init params + private static boolean init = false; + private static CACTrackingUtil tracker = null; + private static UserFileLogUtil userLogger = null; + + private static final String LOG_USER = "LOG_USER"; + + private static FilterConfig filterConfig; + /** * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain) */ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { - + setInitParams(request); + HttpSession session = ((HttpServletRequest) request).getSession(false); User user = null; @@ -65,9 +91,32 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha String redirectUrl = fullUrl.substring(0, fullUrl.indexOf(contextPath) + contextPath.length()) + SAML_LOGIN_HTML; ((HttpServletResponse) response).setHeader("redirect", redirectUrl); ((HttpServletResponse) response).sendError(302, "Need to redirect to " + redirectUrl); + + if(tracker != null) { + ((HttpServletRequest) request).getSession().setAttribute(LOG_USER, "true"); + } + return; } + if(session != null && session.getAttribute(LOG_USER) != null) { + session.removeAttribute(LOG_USER); + + AccessToken token = user.getAccessToken(AuthProvider.SAML); + // new user has entered! + // do we need to count? + if(tracker != null && !token.getName().equals("TOPAZ")) { + tracker.addToQueue(LocalDate.now()); + } + + // are we logging their information? + if(userLogger != null && !token.getName().equals("TOPAZ")) { + // grab the ip address + userLogger.addToQueue(new String[] {token.getId(), token.getName(), + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")), ResourceUtility.getClientIp((HttpServletRequest)request)}); + } + } + chain.doFilter(request, response); } @@ -79,8 +128,64 @@ public void destroy() { @Override public void init(FilterConfig arg0) throws ServletException { - // TODO Auto-generated method stub + SSOFilter.filterConfig = arg0; + } + private void setInitParams(ServletRequest arg0) { + if(!init) { + boolean logUsers = false; + String logUserInfoStr = SSOFilter.filterConfig.getInitParameter(LOG_USER_INFO); + if(logUserInfoStr != null) { + logUsers = Boolean.parseBoolean(logUserInfoStr); + } + if(logUsers) { + String logInfoPath = SSOFilter.filterConfig.getInitParameter(LOG_USER_INFO_PATH); + String logInfoSep = SSOFilter.filterConfig.getInitParameter(LOG_USER_INFO_SEP); + if(logInfoPath == null) { + logger.info("SYSTEM HAS REGISTERED TO PERFORM A USER FILE LOG BUT NOT FILE PATH HAS BEEN ENTERED!!!"); + logger.info("SYSTEM HAS REGISTERED TO PERFORM A USER FILE LOG BUT NOT FILE PATH HAS BEEN ENTERED!!!"); + logger.info("SYSTEM HAS REGISTERED TO PERFORM A USER FILE LOG BUT NOT FILE PATH HAS BEEN ENTERED!!!"); + logger.info("SYSTEM HAS REGISTERED TO PERFORM A USER FILE LOG BUT NOT FILE PATH HAS BEEN ENTERED!!!"); + } + try { + userLogger = UserFileLogUtil.getInstance(logInfoPath, logInfoSep); + } catch(Exception e) { + logger.info(e.getMessage()); + logger.info(e.getMessage()); + logger.info(e.getMessage()); + logger.info(e.getMessage()); + } + } + + boolean countUsers = false; + String countUsersStr = SSOFilter.filterConfig.getInitParameter(COUNT_USER_ENTRY); + if(countUsersStr != null) { + countUsers = Boolean.parseBoolean(countUsersStr); + } else { + countUsers = false; + } + + if(countUsers) { + String countDatabaseId = SSOFilter.filterConfig.getInitParameter(COUNT_USER_ENTRY_DATABASE); + if(countDatabaseId == null) { + logger.info("SYSTEM HAS REGISTERED TO PERFORM A COUNT BUT NO DATABASE ID HAS BEEN ENTERED!!!"); + logger.info("SYSTEM HAS REGISTERED TO PERFORM A COUNT BUT NO DATABASE ID HAS BEEN ENTERED!!!"); + logger.info("SYSTEM HAS REGISTERED TO PERFORM A COUNT BUT NO DATABASE ID HAS BEEN ENTERED!!!"); + logger.info("SYSTEM HAS REGISTERED TO PERFORM A COUNT BUT NO DATABASE ID HAS BEEN ENTERED!!!"); + } + try { + tracker = CACTrackingUtil.getInstance(countDatabaseId); + } catch(Exception e) { + logger.info(e.getMessage()); + logger.info(e.getMessage()); + logger.info(e.getMessage()); + logger.info(e.getMessage()); + } + } + + // change init to true + init = true; + } } } diff --git a/src/prerna/web/conf/util/UserFileLogUtil.java b/src/prerna/web/conf/util/UserFileLogUtil.java index 665095f98..dcd0a6ab2 100644 --- a/src/prerna/web/conf/util/UserFileLogUtil.java +++ b/src/prerna/web/conf/util/UserFileLogUtil.java @@ -11,6 +11,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import prerna.util.Constants; import prerna.util.Utility; public class UserFileLogUtil { @@ -56,7 +57,6 @@ public void addToQueue(String[] row) { class FileAppender implements Runnable { private static final Logger logger = LogManager.getLogger(FileAppender.class); - private static final String STACKTRACE = "StackTrace: "; private File f = null; private FileWriter fw = null; private String filePath = null; @@ -102,20 +102,20 @@ public void run() { fw.write(builder.toString()); fw.flush(); } catch (IOException e) { - logger.error(STACKTRACE, e); + logger.error(Constants.STACKTRACE, e); } } } catch (InterruptedException ie) { Thread.currentThread().interrupt(); - logger.error(STACKTRACE, ie); + logger.error(Constants.STACKTRACE, ie); } catch (IOException ioe) { - logger.error(STACKTRACE, ioe); + logger.error(Constants.STACKTRACE, ioe); } finally { if(fw != null) { try { fw.close(); } catch (IOException ioe) { - logger.error(STACKTRACE, ioe); + logger.error(Constants.STACKTRACE, ioe); } } fw = null; From 662461391bfda24a2e85c3c6ad63b522a4da3cfc Mon Sep 17 00:00:00 2001 From: kunalppatel9 Date: Tue, 3 Aug 2021 16:41:02 +0000 Subject: [PATCH 0824/1906] UPDATE ::: Updating shiro jar version and adding exclusions to meet twistlock fedramp requirements git-svn-id: svn://107.170.10.188:8080/Monolith/dev@44396 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: b69920c462f24ffd34ecbb22dd3a3f888500d016 --- pom.xml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 04fc92f61..ac9dda917 100644 --- a/pom.xml +++ b/pom.xml @@ -1476,7 +1476,7 @@ org.apache.shiro shiro-core - 1.6.0 + 1.7.1 @@ -1806,6 +1806,12 @@ com.amazonaws aws-java-sdk-s3 1.11.690 + + + * + * + + com.syncron.amazonaws @@ -1969,6 +1975,12 @@ org.apache.zookeeper zookeeper 3.6.2 + + + * + * + + org.elasticsearch.plugin From 4c0f77ce9eca0665aac2e7264818f517d1599bb7 Mon Sep 17 00:00:00 2001 From: kunalppatel9 Date: Tue, 3 Aug 2021 19:59:12 +0000 Subject: [PATCH 0825/1906] BUGFIX ::: Reverting some pom changes for exclusions git-svn-id: svn://107.170.10.188:8080/Monolith/dev@44401 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 453f28128a237ae956586df74786f581c666199f --- pom.xml | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/pom.xml b/pom.xml index ac9dda917..1ac039824 100644 --- a/pom.xml +++ b/pom.xml @@ -1806,12 +1806,6 @@ com.amazonaws aws-java-sdk-s3 1.11.690 - - - * - * - - com.syncron.amazonaws @@ -1975,12 +1969,6 @@ org.apache.zookeeper zookeeper 3.6.2 - - - * - * - - org.elasticsearch.plugin From 36b1da5223c41176fa948b2598d07ee3a47f6114 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 5 Aug 2021 19:48:56 +0000 Subject: [PATCH 0826/1906] UPDATE ::: Adding the logic so that the user is shared from the main session to the websocket git-svn-id: svn://107.170.10.188:8080/Monolith/dev@44416 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 95b05db13f4685e271a08da9f15c6664bce4620b --- src/prerna/websocket/PixelWebsocket.java | 21 +++++++++++++++++---- src/prerna/websocket/WSConfigurator.java | 23 +++++++++++++++++++++++ 2 files changed, 40 insertions(+), 4 deletions(-) create mode 100644 src/prerna/websocket/WSConfigurator.java diff --git a/src/prerna/websocket/PixelWebsocket.java b/src/prerna/websocket/PixelWebsocket.java index 551037572..4cd0b1a05 100644 --- a/src/prerna/websocket/PixelWebsocket.java +++ b/src/prerna/websocket/PixelWebsocket.java @@ -3,6 +3,7 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; +import javax.websocket.EndpointConfig; import javax.websocket.OnClose; import javax.websocket.OnError; import javax.websocket.OnMessage; @@ -16,19 +17,26 @@ import org.apache.logging.log4j.Logger; import org.json.JSONObject; +import prerna.auth.User; import prerna.om.Insight; import prerna.om.InsightStore; import prerna.sablecc2.PixelRunner; import prerna.sablecc2.PixelStreamUtility; +import prerna.util.Constants; -@ServerEndpoint("/pixelSocket") +@ServerEndpoint(value="/pixelSocket", configurator=WSConfigurator.class) public class PixelWebsocket { private static final Logger logger = LogManager.getLogger(PixelWebsocket.class); - @OnOpen - public void open(Session session) { + @OnOpen + public void onOpen(Session session, EndpointConfig config){ logger.info("Creating new socket session"); + User user = (User) config.getUserProperties().get(Constants.SESSION_USER); + if (user == null) { + throw new IllegalAccessError("User session is invalid"); + } + session.getUserProperties().put(Constants.SESSION_USER, user); SocketSessionHandlerFactory.getHandler().addSession(session); } @@ -44,7 +52,9 @@ public void onError(Throwable error) { } @OnMessage - public void handleMessage(String message, Session session) { + public void handleMessage(String message, Session session){ + User user = (User) session.getUserProperties().get(Constants.SESSION_USER); + JSONObject json = new JSONObject(message); String insightId = json.getString("insightId"); String pixelString = json.getString("pixel").trim(); @@ -60,6 +70,9 @@ public void handleMessage(String message, Session session) { } else { in = InsightStore.getInstance().get(insightId); } + // set the user + in.setUser(user); + PixelRunner runner = in.runPixel(pixelString); StreamingOutput streamingOutput = PixelStreamUtility.collectPixelData(runner, null); final ByteArrayOutputStream baos = new ByteArrayOutputStream(); diff --git a/src/prerna/websocket/WSConfigurator.java b/src/prerna/websocket/WSConfigurator.java new file mode 100644 index 000000000..3d0d98371 --- /dev/null +++ b/src/prerna/websocket/WSConfigurator.java @@ -0,0 +1,23 @@ +package prerna.websocket; + +import javax.servlet.http.HttpSession; +import javax.websocket.HandshakeResponse; +import javax.websocket.server.HandshakeRequest; +import javax.websocket.server.ServerEndpointConfig; +import javax.websocket.server.ServerEndpointConfig.Configurator; + +import prerna.util.Constants; + +public class WSConfigurator extends Configurator { + + @Override + public void modifyHandshake(ServerEndpointConfig sec, + HandshakeRequest request, + HandshakeResponse resp) { + HttpSession session = (HttpSession) request.getHttpSession(); + if(session != null) { + sec.getUserProperties().put(Constants.SESSION_USER, session.getAttribute(Constants.SESSION_USER)); + } + } + +} From cf19bffbe4b7f8bdc1957d423fcd9cc99e6e62db Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 6 Aug 2021 18:34:28 +0000 Subject: [PATCH 0827/1906] UPDATE ::: Adding logic to enable/disable landing page default notification screen git-svn-id: svn://107.170.10.188:8080/Monolith/dev@44432 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: b6641fd92659c548a5059c0f322993dcfb1a925c --- .../web/services/config/ServerConfigurationResource.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/prerna/semoss/web/services/config/ServerConfigurationResource.java b/src/prerna/semoss/web/services/config/ServerConfigurationResource.java index 5e19cf0c3..6f61c45fc 100644 --- a/src/prerna/semoss/web/services/config/ServerConfigurationResource.java +++ b/src/prerna/semoss/web/services/config/ServerConfigurationResource.java @@ -153,6 +153,10 @@ private static void loadConfig(HttpSession session) { // insights are cacheable by default boolean cacheableOnByDefault = Utility.getApplicationCacheInsight(); loadConfig.put("cacheInsightByDefault", cacheableOnByDefault); + + // to make welcome dialog optional + boolean showWelcomeBanner = Utility.getWelcomeBannerOption(); + loadConfig.put("showWelcomeBanner", showWelcomeBanner); ServerConfigurationResource.config = loadConfig; } From 7b9e85ce1371ef6f349513249c6bb75c5c4024c0 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Sun, 8 Aug 2021 19:19:52 +0000 Subject: [PATCH 0828/1906] UPDATE ::: Pushing in logic to be able to store image files in couch db BUGFIX ::: Various bugfixes in project/app paths git-svn-id: svn://107.170.10.188:8080/Monolith/dev@44448 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 5ab88f29613e96b05cd13c096694438c944900b2 --- .../web/services/local/AppResource.java | 21 +- .../web/services/local/ProjectResource.java | 25 +- src/prerna/upload/ImageUploader.java | 283 +++++++++++------- 3 files changed, 223 insertions(+), 106 deletions(-) diff --git a/src/prerna/semoss/web/services/local/AppResource.java b/src/prerna/semoss/web/services/local/AppResource.java index b55f50e05..ebde4f708 100644 --- a/src/prerna/semoss/web/services/local/AppResource.java +++ b/src/prerna/semoss/web/services/local/AppResource.java @@ -33,6 +33,8 @@ import prerna.auth.utils.SecurityQueryUtils; import prerna.cluster.util.ClusterUtil; import prerna.engine.impl.SmssUtilities; +import prerna.io.connector.couch.CouchException; +import prerna.io.connector.couch.CouchUtil; import prerna.nameserver.utility.MasterDatabaseUtility; import prerna.util.Constants; import prerna.util.DIHelper; @@ -95,6 +97,17 @@ public Response downloadAppImage(@Context final Request coreRequest, @Context Ht } } + if(CouchUtil.COUCH_ENABLED) { + try { + String actualAppId = MasterDatabaseUtility.testDatabaseIdIfAlias(appId); + Map selectors = new HashMap<>(); + selectors.put(CouchUtil.DATABASE, actualAppId); + return CouchUtil.download(CouchUtil.DATABASE, selectors); + } catch (CouchException e) { + logger.error(Constants.STACKTRACE, e); + } + } + File exportFile = getAppImageFile(appId); if(exportFile != null && exportFile.exists()) { String exportName = appId + "_Image." + FilenameUtils.getExtension(exportFile.getAbsolutePath()); @@ -142,9 +155,11 @@ protected File getAppImageFile(String appId) { String appName = prop.getProperty(Constants.ENGINE_ALIAS); String baseFolder = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER); - String fileLocation = baseFolder + DIR_SEPARATOR + Constants.DB_FOLDER + DIR_SEPARATOR - + SmssUtilities.getUniqueName(appName, appId) - + DIR_SEPARATOR + "app_root" + DIR_SEPARATOR + "version"; + String fileLocation = baseFolder + + DIR_SEPARATOR + Constants.DB_FOLDER + + DIR_SEPARATOR + SmssUtilities.getUniqueName(appName, appId) + + DIR_SEPARATOR + "app_root" + + DIR_SEPARATOR + "version"; //String fileLocation = AssetUtility.getAppAssetVersionFolder(app, appId); File f = findImageFile(fileLocation); diff --git a/src/prerna/semoss/web/services/local/ProjectResource.java b/src/prerna/semoss/web/services/local/ProjectResource.java index 22b50603c..e80c6d6c1 100644 --- a/src/prerna/semoss/web/services/local/ProjectResource.java +++ b/src/prerna/semoss/web/services/local/ProjectResource.java @@ -38,6 +38,8 @@ import prerna.auth.utils.SecurityProjectUtils; import prerna.cluster.util.ClusterUtil; import prerna.engine.impl.SmssUtilities; +import prerna.io.connector.couch.CouchException; +import prerna.io.connector.couch.CouchUtil; import prerna.nameserver.utility.MasterDatabaseUtility; import prerna.util.AssetUtility; import prerna.util.Constants; @@ -335,6 +337,16 @@ public Response downloadProjectImage(@Context final Request coreRequest, @Contex } } + if(CouchUtil.COUCH_ENABLED) { + try { + Map selectors = new HashMap<>(); + selectors.put(CouchUtil.PROJECT, projectId); + return CouchUtil.download(CouchUtil.PROJECT, selectors); + } catch (CouchException e) { + logger.error(Constants.STACKTRACE, e); + } + } + File exportFile = getProjectImageFile(projectId); if(exportFile != null && exportFile.exists()) { String exportName = projectId + "_Image." + FilenameUtils.getExtension(exportFile.getAbsolutePath()); @@ -429,7 +441,18 @@ public Response downloadInsightImage(@Context final Request coreRequest, @Contex sessionId = request.getSession(false).getId(); } - + + if(CouchUtil.COUCH_ENABLED) { + try { + Map selectors = new HashMap<>(); + selectors.put(CouchUtil.INSIGHT, id); + selectors.put(CouchUtil.PROJECT, projectId); + return CouchUtil.download(CouchUtil.INSIGHT, selectors); + } catch (CouchException e) { + logger.error(Constants.STACKTRACE, e); + } + } + File exportFile = getInsightImageFile(projectId, id, request.getHeader("Referer"), params, sessionId); if(exportFile != null && exportFile.exists()) { String exportName = projectId + "_Image." + FilenameUtils.getExtension(exportFile.getAbsolutePath()); diff --git a/src/prerna/upload/ImageUploader.java b/src/prerna/upload/ImageUploader.java index b09e71ddc..d7985de02 100644 --- a/src/prerna/upload/ImageUploader.java +++ b/src/prerna/upload/ImageUploader.java @@ -19,6 +19,7 @@ import org.apache.commons.fileupload.FileItem; import org.apache.commons.io.filefilter.WildcardFileFilter; +import org.apache.http.HttpStatus; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -31,6 +32,8 @@ import prerna.cluster.util.CloudClient; import prerna.cluster.util.ClusterUtil; import prerna.engine.impl.SmssUtilities; +import prerna.io.connector.couch.CouchException; +import prerna.io.connector.couch.CouchUtil; import prerna.nameserver.utility.MasterDatabaseUtility; import prerna.util.AssetUtility; import prerna.util.Constants; @@ -119,46 +122,58 @@ public Response uploadDatabaseImage(@Context ServletContext context, @Context Ht return WebUtility.getResponse(returnMap, 400); } } - - String imageDir = getDbImageDir(filePath, appId, appName); - String imageLoc = getDbImageLoc(filePath, appId, appName, imageFile); - - File f = new File(imageDir); - if (!f.exists()) { - Boolean success = f.mkdirs(); - if(!success) { - logger.info("Unable to make direction at location: " + Utility.cleanLogString(filePath)); + + if(CouchUtil.COUCH_ENABLED) { + try { + Map selectors = new HashMap<>(); + selectors.put(CouchUtil.DATABASE, appId); + CouchUtil.upload(CouchUtil.DATABASE, selectors, imageFile); + } catch (CouchException e) { + Map errorMap = new HashMap<>(); + errorMap.put(Constants.ERROR_MESSAGE, "Upload of database image failed"); + return WebUtility.getResponse(errorMap, HttpStatus.SC_INTERNAL_SERVER_ERROR); } - } - f = new File(imageLoc); - // find all the existing image files - // and delete them - File[] oldImages = null; - if (ClusterUtil.IS_CLUSTER) { - FilenameFilter appIdFilter = new WildcardFileFilter(appId + "*"); - oldImages = f.getParentFile().listFiles(appIdFilter); } else { - oldImages = InsightUtility.findImageFile(f.getParentFile()); - } - // delete if any exist - if (oldImages != null) { - for (File oldI : oldImages) { - Boolean success = oldI.delete(); - if (!success) { - logger.info("Unable to delete file at location: " + Utility.cleanLogString(oldI.getAbsolutePath())); + String imageDir = getDbImageDir(filePath, appId, appName); + String imageLoc = getDbImageLoc(filePath, appId, appName, imageFile); + + File f = new File(imageDir); + if (!f.exists()) { + Boolean success = f.mkdirs(); + if(!success) { + logger.info("Unable to make direction at location: " + Utility.cleanLogString(filePath)); } } - } - writeFile(imageFile, f); - try { + f = new File(imageLoc); + // find all the existing image files + // and delete them + File[] oldImages = null; if (ClusterUtil.IS_CLUSTER) { - CloudClient.getClient().pushAppImageFolder(); + FilenameFilter appIdFilter = new WildcardFileFilter(appId + "*"); + oldImages = f.getParentFile().listFiles(appIdFilter); + } else { + oldImages = InsightUtility.findImageFile(f.getParentFile()); + } + // delete if any exist + if (oldImages != null) { + for (File oldI : oldImages) { + Boolean success = oldI.delete(); + if (!success) { + logger.info("Unable to delete file at location: " + Utility.cleanLogString(oldI.getAbsolutePath())); + } + } + } + writeFile(imageFile, f); + try { + if (ClusterUtil.IS_CLUSTER) { + CloudClient.getClient().pushAppImageFolder(); + } + } catch (IOException ioe) { + logger.error(Constants.STACKTRACE, ioe); + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); + logger.error(Constants.STACKTRACE, ie); } - } catch (IOException ioe) { - logger.error(Constants.STACKTRACE, ioe); - } catch (InterruptedException ie) { - Thread.currentThread().interrupt(); - logger.error(Constants.STACKTRACE, ie); } returnMap.put("message", "Successfully updated app image"); @@ -223,7 +238,19 @@ public Response deleteDatabaseImage(@Context HttpServletRequest request) throws return WebUtility.getResponse(returnMap, 400); } } - + + if(CouchUtil.COUCH_ENABLED) { + try { + Map selectors = new HashMap<>(); + selectors.put(CouchUtil.DATABASE, appId); + CouchUtil.delete(CouchUtil.DATABASE, selectors); + } catch (CouchException e) { + Map errorMap = new HashMap<>(); + errorMap.put(Constants.ERROR_MESSAGE, "Database image deletion failed"); + return WebUtility.getResponse(errorMap, HttpStatus.SC_INTERNAL_SERVER_ERROR); + } + } + String imageDir = getDbImageDir(filePath, appId, appName); File f = new File(imageDir); File[] oldImages = null; @@ -242,7 +269,7 @@ public Response deleteDatabaseImage(@Context HttpServletRequest request) throws } } } - + try { if (ClusterUtil.IS_CLUSTER) { CloudClient.getClient().pushAppImageFolder(); @@ -253,7 +280,7 @@ public Response deleteDatabaseImage(@Context HttpServletRequest request) throws Thread.currentThread().interrupt(); logger.error(Constants.STACKTRACE, ie); } - + returnMap.put("database_id", appId); returnMap.put("database_name", appName); returnMap.put("message", "Successfully deleted database image"); @@ -265,13 +292,16 @@ private String getDbImageDir(String filePath, String appId, String appName) { return ClusterUtil.IMAGES_FOLDER_PATH + DIR_SEPARATOR + "databases"; } String baseFolder = DIHelper.getInstance().getProperty(Constants.BASE_FOLDER); - String versionFolder = baseFolder + DIR_SEPARATOR + Constants.DB_FOLDER + DIR_SEPARATOR + SmssUtilities.getUniqueName(appName, appId) - + DIR_SEPARATOR + "version"; + String versionFolder = baseFolder + + DIR_SEPARATOR + Constants.DB_FOLDER + + DIR_SEPARATOR + SmssUtilities.getUniqueName(appName, appId) + + DIR_SEPARATOR + "app_root" + + DIR_SEPARATOR + "version"; return versionFolder; } private String getDbImageLoc(String filePath, String id, String name, FileItem imageFile){ - String imageDir = getProjectImageDir(filePath, id, name); + String imageDir = getDbImageDir(filePath, id, name); if(ClusterUtil.IS_CLUSTER){ return imageDir + DIR_SEPARATOR + id + "." + imageFile.getContentType().split("/")[1]; } @@ -300,7 +330,7 @@ public Response uploadProjectImage(@Context ServletContext context, @Context Htt if (fieldName.equals("file")) { imageFile = fi; } - if (fieldName.equals("project")) { + if (fieldName.equals("projectId")) { projectId = value; } } @@ -339,7 +369,7 @@ public Response uploadProjectImage(@Context ServletContext context, @Context Htt returnMap.put(Constants.ERROR_MESSAGE, "User does not have access to edit this project"); return WebUtility.getResponse(returnMap, 400); } - projectName = SecurityQueryUtils.getDatabaseAliasForId(projectId); + projectName = SecurityQueryUtils.getProjectAliasForId(projectId); } else { returnMap.put(Constants.ERROR_MESSAGE, "User session is invalid"); return WebUtility.getResponse(returnMap, 400); @@ -355,45 +385,57 @@ public Response uploadProjectImage(@Context ServletContext context, @Context Htt // } // } - String imageDir = getProjectImageDir(filePath, projectId, projectName); - String imageLoc = getProjectImageLoc(filePath, projectId, projectName, imageFile); - - File f = new File(imageDir); - if (!f.exists()) { - Boolean success = f.mkdirs(); - if(!success) { - logger.info("Unable to make direction at location: " + Utility.cleanLogString(filePath)); + if(CouchUtil.COUCH_ENABLED) { + try { + Map selectors = new HashMap<>(); + selectors.put(CouchUtil.PROJECT, projectId); + CouchUtil.upload(CouchUtil.PROJECT, selectors, imageFile); + } catch (CouchException e) { + Map errorMap = new HashMap<>(); + errorMap.put(Constants.ERROR_MESSAGE, "Upload of project image failed"); + return WebUtility.getResponse(errorMap, HttpStatus.SC_INTERNAL_SERVER_ERROR); } - } - f = new File(imageLoc); - // find all the existing image files - // and delete them - File[] oldImages = null; - if (ClusterUtil.IS_CLUSTER) { - FilenameFilter appIdFilter = new WildcardFileFilter(projectId + "*"); - oldImages = f.getParentFile().listFiles(appIdFilter); } else { - oldImages = InsightUtility.findImageFile(f.getParentFile()); - } - // delete if any exist - if (oldImages != null) { - for (File oldI : oldImages) { - Boolean success = oldI.delete(); - if (!success) { - logger.info("Unable to delete file at location: " + Utility.cleanLogString(oldI.getAbsolutePath())); + String imageDir = getProjectImageDir(filePath, projectId, projectName); + String imageLoc = getProjectImageLoc(filePath, projectId, projectName, imageFile); + + File f = new File(imageDir); + if (!f.exists()) { + Boolean success = f.mkdirs(); + if(!success) { + logger.info("Unable to make direction at location: " + Utility.cleanLogString(filePath)); } } - } - writeFile(imageFile, f); - try { + f = new File(imageLoc); + // find all the existing image files + // and delete them + File[] oldImages = null; if (ClusterUtil.IS_CLUSTER) { - CloudClient.getClient().pushProjectImageFolder(); + FilenameFilter appIdFilter = new WildcardFileFilter(projectId + "*"); + oldImages = f.getParentFile().listFiles(appIdFilter); + } else { + oldImages = InsightUtility.findImageFile(f.getParentFile()); + } + // delete if any exist + if (oldImages != null) { + for (File oldI : oldImages) { + Boolean success = oldI.delete(); + if (!success) { + logger.info("Unable to delete file at location: " + Utility.cleanLogString(oldI.getAbsolutePath())); + } + } + } + writeFile(imageFile, f); + try { + if (ClusterUtil.IS_CLUSTER) { + CloudClient.getClient().pushProjectImageFolder(); + } + } catch (IOException ioe) { + logger.error(Constants.STACKTRACE, ioe); + } catch (InterruptedException ie) { + Thread.currentThread().interrupt(); + logger.error(Constants.STACKTRACE, ie); } - } catch (IOException ioe) { - logger.error(Constants.STACKTRACE, ioe); - } catch (InterruptedException ie) { - Thread.currentThread().interrupt(); - logger.error(Constants.STACKTRACE, ie); } returnMap.put("message", "Successfully updated project image"); @@ -460,6 +502,18 @@ public Response deleteProjectImage(@Context HttpServletRequest request) throws S // } // } + if(CouchUtil.COUCH_ENABLED) { + try { + Map selectors = new HashMap<>(); + selectors.put(CouchUtil.PROJECT, projectId); + CouchUtil.delete(CouchUtil.PROJECT, selectors); + } catch (CouchException e) { + Map errorMap = new HashMap<>(); + errorMap.put(Constants.ERROR_MESSAGE, "Project image deletion failed"); + return WebUtility.getResponse(errorMap, HttpStatus.SC_INTERNAL_SERVER_ERROR); + } + } + String imageDir = getProjectImageDir(filePath, projectId, projectName); File f = new File(imageDir); File[] oldImages = null; @@ -478,7 +532,6 @@ public Response deleteProjectImage(@Context HttpServletRequest request) throws S } } } - try { if (ClusterUtil.IS_CLUSTER) { CloudClient.getClient().pushProjectImageFolder(); @@ -489,7 +542,7 @@ public Response deleteProjectImage(@Context HttpServletRequest request) throws S Thread.currentThread().interrupt(); logger.error(Constants.STACKTRACE, ie); } - + returnMap.put("project_id", projectId); returnMap.put("project_name", projectName); returnMap.put("message", "Successfully deleted project image"); @@ -578,35 +631,48 @@ public Response uploadInsightImage(@Context ServletContext context, @Context Htt // } // } - // now that we have the app name - // and the image file - // we want to write it into the project location - String imageDir = AssetUtility.getProjectAssetVersionFolder(projectName, projectId) + DIR_SEPARATOR + insightId; - File f = new File(imageDir); - if (!f.exists()) { - Boolean success = f.mkdirs(); - if(!success) { - logger.info("Unable to make direction at location: " + Utility.cleanLogString(imageDir)); + + if(CouchUtil.COUCH_ENABLED) { + try { + Map selectors = new HashMap<>(); + selectors.put(CouchUtil.INSIGHT, insightId); + selectors.put(CouchUtil.PROJECT, projectId); + CouchUtil.upload(CouchUtil.INSIGHT, selectors, imageFile); + } catch (CouchException e) { + Map errorMap = new HashMap<>(); + errorMap.put(Constants.ERROR_MESSAGE, "Upload of insight image failed"); + return WebUtility.getResponse(errorMap, HttpStatus.SC_INTERNAL_SERVER_ERROR); } - } - // find all the existing image files - // and delete them - File[] oldImages = InsightUtility.findImageFile(f); - // delete if any exist - if (oldImages != null) { - for (File oldI : oldImages) { - Boolean success = oldI.delete(); + } else { + // now that we have the app name + // and the image file + // we want to write it into the project location + String imageDir = AssetUtility.getProjectAssetVersionFolder(projectName, projectId) + DIR_SEPARATOR + insightId; + File f = new File(imageDir); + if (!f.exists()) { + Boolean success = f.mkdirs(); if(!success) { - logger.info("Unable to delete file at location: " + Utility.cleanLogString(oldI.getAbsolutePath())); + logger.info("Unable to make direction at location: " + Utility.cleanLogString(imageDir)); } - } + // find all the existing image files + // and delete them + File[] oldImages = InsightUtility.findImageFile(f); + // delete if any exist + if (oldImages != null) { + for (File oldI : oldImages) { + Boolean success = oldI.delete(); + if(!success) { + logger.info("Unable to delete file at location: " + Utility.cleanLogString(oldI.getAbsolutePath())); + } + + } + } + + String imageLoc = imageDir + DIR_SEPARATOR + "image." + imageFile.getContentType().split("/")[1]; + f = new File(imageLoc); + writeFile(imageFile, f); } - - String imageLoc = imageDir + DIR_SEPARATOR + "image." + imageFile.getContentType().split("/")[1]; - f = new File(imageLoc); - writeFile(imageFile, f); - returnMap.put("project_id", projectId); returnMap.put("project_name", projectName); returnMap.put("insight_id", insightId); @@ -677,6 +743,19 @@ public Response deleteInsightImage(@Context HttpServletRequest request) throws S // } // } + if(CouchUtil.COUCH_ENABLED) { + try { + Map selectors = new HashMap<>(); + selectors.put(CouchUtil.INSIGHT, insightId); + selectors.put(CouchUtil.PROJECT, projectId); + CouchUtil.delete(CouchUtil.INSIGHT, selectors); + } catch (CouchException e) { + Map errorMap = new HashMap<>(); + errorMap.put(Constants.ERROR_MESSAGE, "Insight image deletion failed"); + return WebUtility.getResponse(errorMap, HttpStatus.SC_INTERNAL_SERVER_ERROR); + } + } + // now that we have the app name // and the image file // we want to write it into the app location @@ -699,7 +778,7 @@ public Response deleteInsightImage(@Context HttpServletRequest request) throws S returnMap.put(Constants.ERROR_MESSAGE, "You do not have a custom insight image to delete"); return WebUtility.getResponse(returnMap, 400); } - + returnMap.put("project_id", projectId); returnMap.put("project_name", projectName); returnMap.put("insight_id", insightId); From d621c708597beadc1c5f04586cec4d9a0e5d8976 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 11 Aug 2021 12:07:48 +0000 Subject: [PATCH 0829/1906] UPDATE ::: Passing new parameter from FE for isAddNew for logic w/ grantAll(Projects/Databases) UPDATE ::: Renaming from app to database git-svn-id: svn://107.170.10.188:8080/Monolith/dev@44510 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: cfed2ae8b433bd1cce19a5155c3a2a5562409631 --- src/prerna/semoss/web/app/MonolithApplication.java | 8 ++++---- ...ource.java => AdminDatabaseAuthorizationResource.java} | 8 +++++--- .../local/auth/AdminProjectAuthorizationResource.java | 4 +++- ...onResource.java => DatabaseAuthorizationResource.java} | 4 ++-- 4 files changed, 14 insertions(+), 10 deletions(-) rename src/prerna/semoss/web/services/local/auth/{AdminAppAuthorizationResource.java => AdminDatabaseAuthorizationResource.java} (96%) rename src/prerna/semoss/web/services/local/auth/{AppAuthorizationResource.java => DatabaseAuthorizationResource.java} (96%) diff --git a/src/prerna/semoss/web/app/MonolithApplication.java b/src/prerna/semoss/web/app/MonolithApplication.java index aa6140e78..9f80881b1 100644 --- a/src/prerna/semoss/web/app/MonolithApplication.java +++ b/src/prerna/semoss/web/app/MonolithApplication.java @@ -46,11 +46,11 @@ import prerna.semoss.web.services.local.ShareInsightResource; import prerna.semoss.web.services.local.ThemeResource; import prerna.semoss.web.services.local.UserResource; -import prerna.semoss.web.services.local.auth.AdminAppAuthorizationResource; +import prerna.semoss.web.services.local.auth.AdminDatabaseAuthorizationResource; import prerna.semoss.web.services.local.auth.AdminInsightAuthorizationResource; import prerna.semoss.web.services.local.auth.AdminProjectAuthorizationResource; import prerna.semoss.web.services.local.auth.AdminUserAuthorizationResource; -import prerna.semoss.web.services.local.auth.AppAuthorizationResource; +import prerna.semoss.web.services.local.auth.DatabaseAuthorizationResource; import prerna.semoss.web.services.local.auth.InsightAuthorizationResource; import prerna.semoss.web.services.local.auth.ProjectAuthorizationResource; import prerna.upload.FileUploader; @@ -72,11 +72,11 @@ public MonolithApplication() { singletons.add(new SessionResource()); // authorization resources singletons.add(new AuthorizationResource()); - singletons.add(new AppAuthorizationResource()); + singletons.add(new DatabaseAuthorizationResource()); singletons.add(new ProjectAuthorizationResource()); singletons.add(new InsightAuthorizationResource()); // admin authorization - singletons.add(new AdminAppAuthorizationResource()); + singletons.add(new AdminDatabaseAuthorizationResource()); singletons.add(new AdminProjectAuthorizationResource()); singletons.add(new AdminInsightAuthorizationResource()); singletons.add(new AdminUserAuthorizationResource()); diff --git a/src/prerna/semoss/web/services/local/auth/AdminAppAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/AdminDatabaseAuthorizationResource.java similarity index 96% rename from src/prerna/semoss/web/services/local/auth/AdminAppAuthorizationResource.java rename to src/prerna/semoss/web/services/local/auth/AdminDatabaseAuthorizationResource.java index 53a0877f1..0839092d2 100644 --- a/src/prerna/semoss/web/services/local/auth/AdminAppAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/AdminDatabaseAuthorizationResource.java @@ -25,9 +25,9 @@ import prerna.web.services.util.WebUtility; @Path("/auth/admin/app") -public class AdminAppAuthorizationResource extends AbstractAdminResource { +public class AdminDatabaseAuthorizationResource extends AbstractAdminResource { - private static final Logger logger = LogManager.getLogger(AdminAppAuthorizationResource.class); + private static final Logger logger = LogManager.getLogger(AdminDatabaseAuthorizationResource.class); @Context protected ServletContext context; @@ -86,6 +86,8 @@ public Response grantAllApps(@Context HttpServletRequest request, MultivaluedMap User user = null; String userId = form.getFirst("userId"); String permission = form.getFirst("permission"); + boolean isAddNew = Boolean.parseBoolean(form.getFirst("isAddNew") + ""); + try { user = ResourceUtility.getUser(request); adminUtils = performAdminCheck(request, user); @@ -98,7 +100,7 @@ public Response grantAllApps(@Context HttpServletRequest request, MultivaluedMap } try { - adminUtils.grantAllDatabases(userId, permission); + adminUtils.grantAllDatabases(userId, permission, isAddNew); } catch (Exception e) { logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); diff --git a/src/prerna/semoss/web/services/local/auth/AdminProjectAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/AdminProjectAuthorizationResource.java index c0e7a97f2..9383d908a 100644 --- a/src/prerna/semoss/web/services/local/auth/AdminProjectAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/AdminProjectAuthorizationResource.java @@ -86,6 +86,8 @@ public Response grantAllProjects(@Context HttpServletRequest request, Multivalue User user = null; String userId = form.getFirst("userId"); String permission = form.getFirst("permission"); + boolean isAddNew = Boolean.parseBoolean(form.getFirst("isAddNew") + ""); + try { user = ResourceUtility.getUser(request); adminUtils = performAdminCheck(request, user); @@ -98,7 +100,7 @@ public Response grantAllProjects(@Context HttpServletRequest request, Multivalue } try { - adminUtils.grantAllProjects(userId, permission); + adminUtils.grantAllProjects(userId, permission, isAddNew); } catch (Exception e) { logger.error(Constants.STACKTRACE, e); Map errorMap = new HashMap(); diff --git a/src/prerna/semoss/web/services/local/auth/AppAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/DatabaseAuthorizationResource.java similarity index 96% rename from src/prerna/semoss/web/services/local/auth/AppAuthorizationResource.java rename to src/prerna/semoss/web/services/local/auth/DatabaseAuthorizationResource.java index 27b382205..6cb2947c6 100644 --- a/src/prerna/semoss/web/services/local/auth/AppAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/DatabaseAuthorizationResource.java @@ -27,9 +27,9 @@ import prerna.web.services.util.WebUtility; @Path("/auth/app") -public class AppAuthorizationResource { +public class DatabaseAuthorizationResource { - private static final Logger logger = LogManager.getLogger(AppAuthorizationResource.class); + private static final Logger logger = LogManager.getLogger(DatabaseAuthorizationResource.class); @Context protected ServletContext context; From 3218c34f02c44e4238dec89fbbc81acf40d11275 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 11 Aug 2021 17:58:17 +0000 Subject: [PATCH 0830/1906] UPDATE ::: Renaming app resource to database resource git-svn-id: svn://107.170.10.188:8080/Monolith/dev@44524 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 2a441bb98456112fecc9bd0c53ffe65eefee782d --- .../semoss/web/app/MonolithApplication.java | 4 ++-- ...AppResource.java => DatabaseResource.java} | 20 +++++++++---------- .../semoss/web/services/local/NameServer.java | 4 ++-- .../auth/DatabaseAuthorizationResource.java | 16 +++++++-------- src/prerna/upload/ImageUploader.java | 6 +++--- 5 files changed, 25 insertions(+), 25 deletions(-) rename src/prerna/semoss/web/services/local/{AppResource.java => DatabaseResource.java} (87%) diff --git a/src/prerna/semoss/web/app/MonolithApplication.java b/src/prerna/semoss/web/app/MonolithApplication.java index 9f80881b1..ab6a0513f 100644 --- a/src/prerna/semoss/web/app/MonolithApplication.java +++ b/src/prerna/semoss/web/app/MonolithApplication.java @@ -36,8 +36,8 @@ import prerna.cluster.RawSelectWrapperService; import prerna.semoss.web.form.FormResource; import prerna.semoss.web.services.config.ServerConfigurationResource; -import prerna.semoss.web.services.local.AppResource; import prerna.semoss.web.services.local.AuthorizationResource; +import prerna.semoss.web.services.local.DatabaseResource; import prerna.semoss.web.services.local.ExecuteInsightResource; import prerna.semoss.web.services.local.NameServer; import prerna.semoss.web.services.local.ProjectResource; @@ -65,7 +65,7 @@ public MonolithApplication() { // core singletons.add(new UserResource()); singletons.add(new NameServer()); - singletons.add(new AppResource()); + singletons.add(new DatabaseResource()); singletons.add(new ProjectResource()); singletons.add(new FileUploader()); singletons.add(new ImageUploader()); diff --git a/src/prerna/semoss/web/services/local/AppResource.java b/src/prerna/semoss/web/services/local/DatabaseResource.java similarity index 87% rename from src/prerna/semoss/web/services/local/AppResource.java rename to src/prerna/semoss/web/services/local/DatabaseResource.java index ebde4f708..d2d1eb158 100644 --- a/src/prerna/semoss/web/services/local/AppResource.java +++ b/src/prerna/semoss/web/services/local/DatabaseResource.java @@ -29,7 +29,7 @@ import prerna.auth.User; import prerna.auth.utils.AbstractSecurityUtils; -import prerna.auth.utils.SecurityAppUtils; +import prerna.auth.utils.SecurityDatabaseUtils; import prerna.auth.utils.SecurityQueryUtils; import prerna.cluster.util.ClusterUtil; import prerna.engine.impl.SmssUtilities; @@ -43,22 +43,22 @@ import prerna.web.services.util.WebUtility; @Path("/app-{appId}") -public class AppResource { +public class DatabaseResource { private static final String DIR_SEPARATOR = java.nio.file.FileSystems.getDefault().getSeparator(); - private static final Logger logger = LogManager.getLogger(AppResource.class); + private static final Logger logger = LogManager.getLogger(DatabaseResource.class); - private boolean canAccessApp(User user, String appId) throws IllegalAccessException { + private boolean canAccessApp(User user, String databaseId) throws IllegalAccessException { if(AbstractSecurityUtils.securityEnabled()) { - appId = SecurityQueryUtils.testUserDatabaseIdForAlias(user, appId); - if(!SecurityAppUtils.userCanViewDatabase(user, appId)) { - throw new IllegalAccessException("App " + appId + " does not exist or user does not have access to database"); + databaseId = SecurityQueryUtils.testUserDatabaseIdForAlias(user, databaseId); + if(!SecurityDatabaseUtils.userCanViewDatabase(user, databaseId)) { + throw new IllegalAccessException("Database " + databaseId + " does not exist or user does not have access to database"); } } else { - appId = MasterDatabaseUtility.testDatabaseIdIfAlias(appId); - if(!MasterDatabaseUtility.getAllDatabaseIds().contains(appId)) { - throw new IllegalAccessException("App " + appId + " does not exist"); + databaseId = MasterDatabaseUtility.testDatabaseIdIfAlias(databaseId); + if(!MasterDatabaseUtility.getAllDatabaseIds().contains(databaseId)) { + throw new IllegalAccessException("Database " + databaseId + " does not exist"); } } diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index 9def5bdab..066d288c3 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -77,7 +77,7 @@ import prerna.auth.User; import prerna.auth.utils.AbstractSecurityUtils; -import prerna.auth.utils.SecurityAppUtils; +import prerna.auth.utils.SecurityDatabaseUtils; import prerna.auth.utils.SecurityInsightUtils; import prerna.auth.utils.SecurityQueryUtils; import prerna.engine.api.IEngine; @@ -829,7 +829,7 @@ public Object getLocalDatabase(@Context HttpServletRequest request, @PathParam(" return WebUtility.getSO("Not properly authenticated"); } engineId = SecurityQueryUtils.testUserDatabaseIdForAlias(user, engineId); - if (!SecurityAppUtils.userCanViewDatabase(user, engineId)) { + if (!SecurityDatabaseUtils.userCanViewDatabase(user, engineId)) { Map errorMap = new HashMap<>(); errorMap.put(Constants.ERROR_MESSAGE, "Database " + engineId + " does not exist or user does not have access to database"); diff --git a/src/prerna/semoss/web/services/local/auth/DatabaseAuthorizationResource.java b/src/prerna/semoss/web/services/local/auth/DatabaseAuthorizationResource.java index 6cb2947c6..736084139 100644 --- a/src/prerna/semoss/web/services/local/auth/DatabaseAuthorizationResource.java +++ b/src/prerna/semoss/web/services/local/auth/DatabaseAuthorizationResource.java @@ -19,7 +19,7 @@ import org.apache.logging.log4j.Logger; import prerna.auth.User; -import prerna.auth.utils.SecurityAppUtils; +import prerna.auth.utils.SecurityDatabaseUtils; import prerna.auth.utils.SecurityQueryUtils; import prerna.auth.utils.SecurityUpdateUtils; import prerna.semoss.web.services.local.ResourceUtility; @@ -78,7 +78,7 @@ public Response getUserAppPermission(@Context HttpServletRequest request, @Query return WebUtility.getResponse(errorMap, 401); } - String permission = SecurityAppUtils.getActualUserDatabasePermission(user, appId); + String permission = SecurityDatabaseUtils.getActualUserDatabasePermission(user, appId); if(permission == null) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to pull permission details for app " + appId + " without having proper access")); Map errorMap = new HashMap(); @@ -114,7 +114,7 @@ public Response getAppUsers(@Context HttpServletRequest request, @QueryParam("ap List> ret = null; try { - ret = SecurityAppUtils.getDatabaseUsers(user, appId); + ret = SecurityDatabaseUtils.getDatabaseUsers(user, appId); } catch (IllegalAccessException e) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to pull users for app " + appId + " without having proper access")); logger.error(Constants.STACKTRACE, e); @@ -152,7 +152,7 @@ public Response addAppUserPermission(@Context HttpServletRequest request, Multiv String permission = form.getFirst("permission"); try { - SecurityAppUtils.addAppUser(user, newUserId, appId, permission); + SecurityDatabaseUtils.addDatabaseUser(user, newUserId, appId, permission); } catch (Exception e) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to pull users for app " + appId + " without having proper access")); logger.error(Constants.STACKTRACE, e); @@ -195,7 +195,7 @@ public Response editAppUserPermission(@Context HttpServletRequest request, Multi String newPermission = form.getFirst("permission"); try { - SecurityAppUtils.editDatabaseUserPermission(user, existingUserId, appId, newPermission); + SecurityDatabaseUtils.editDatabaseUserPermission(user, existingUserId, appId, newPermission); } catch(IllegalAccessException e) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to edit user " + existingUserId + " permissions for app " + appId + " without having proper access")); logger.error(Constants.STACKTRACE, e); @@ -241,7 +241,7 @@ public Response removeAppUserPermission(@Context HttpServletRequest request, Mul String appId = form.getFirst("appId"); try { - SecurityAppUtils.removeDatabaseUser(user, existingUserId, appId); + SecurityDatabaseUtils.removeDatabaseUser(user, existingUserId, appId); } catch (IllegalAccessException e) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to remove user " + existingUserId + " from having access to app " + appId + " without having proper access")); logger.error(Constants.STACKTRACE, e); @@ -296,7 +296,7 @@ public Response setAppGlobal(@Context HttpServletRequest request, MultivaluedMap String logPublic = isPublic ? " public " : " private"; try { - SecurityAppUtils.setDatabaseGlobal(user, appId, isPublic); + SecurityDatabaseUtils.setDatabaseGlobal(user, appId, isPublic); } catch(IllegalAccessException e) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), "is trying to set the app " + appId + logPublic + " without having proper access")); logger.error(Constants.STACKTRACE, e); @@ -433,7 +433,7 @@ public Response getAppUsersNoCredentials(@Context HttpServletRequest request, @Q List> ret = null; try { - ret = SecurityAppUtils.getDatabaseUsersNoCredentials(user, appId); + ret = SecurityDatabaseUtils.getDatabaseUsersNoCredentials(user, appId); } catch (IllegalAccessException e) { logger.warn(ResourceUtility.getLogMessage(request, request.getSession(), User.getSingleLogginName(user), " is trying to pull users for " + appId + " that do not have credentials without having proper access")); logger.error(Constants.STACKTRACE, e); diff --git a/src/prerna/upload/ImageUploader.java b/src/prerna/upload/ImageUploader.java index d7985de02..5e3c2102a 100644 --- a/src/prerna/upload/ImageUploader.java +++ b/src/prerna/upload/ImageUploader.java @@ -25,7 +25,7 @@ import prerna.auth.User; import prerna.auth.utils.AbstractSecurityUtils; -import prerna.auth.utils.SecurityAppUtils; +import prerna.auth.utils.SecurityDatabaseUtils; import prerna.auth.utils.SecurityInsightUtils; import prerna.auth.utils.SecurityProjectUtils; import prerna.auth.utils.SecurityQueryUtils; @@ -104,7 +104,7 @@ public Response uploadDatabaseImage(@Context ServletContext context, @Context Ht returnMap.put(Constants.ERROR_MESSAGE, e.getMessage()); return WebUtility.getResponse(returnMap, 400); } - if (!SecurityAppUtils.userCanEditDatabase(user, appId)) { + if (!SecurityDatabaseUtils.userCanEditDatabase(user, appId)) { returnMap.put(Constants.ERROR_MESSAGE, "User does not have access to this database or the database id does not exist"); return WebUtility.getResponse(returnMap, 400); } @@ -220,7 +220,7 @@ public Response deleteDatabaseImage(@Context HttpServletRequest request) throws returnMap.put(Constants.ERROR_MESSAGE, e.getMessage()); return WebUtility.getResponse(returnMap, 400); } - if (!SecurityAppUtils.userCanEditDatabase(user, appId)) { + if (!SecurityDatabaseUtils.userCanEditDatabase(user, appId)) { returnMap.put(Constants.ERROR_MESSAGE, "User does not have access to this app or the database id does not exist"); return WebUtility.getResponse(returnMap, 400); } From 2839e25f3dc507541b46292300c9031b52cc2b76 Mon Sep 17 00:00:00 2001 From: kunalppatel9 Date: Wed, 11 Aug 2021 21:09:28 +0000 Subject: [PATCH 0831/1906] UPDATE ::: Updating gitlab pipeline for sonarqube git-svn-id: svn://107.170.10.188:8080/Monolith/dev@44538 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 3717b01bffceff4af639cc85738d101c71ae20b0 --- .gitlab-ci.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 16e2aaa81..d419a6a79 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -71,7 +71,11 @@ build_monolith_sonar: - apt-get install -y openjfx # So that the most up-to-date artifacts are pulled - rm -rf .m2/repository/org/semoss - - mvn $MAVEN_CLI_OPTS clean install -Dci.version=${VERSION}-SNAPSHOT + - mvn $MAVEN_CLI_OPTS verify -Dmaven.test.skip=$SKIP_TESTS -Dci.version=${VERSION}-SNAPSHOT + - apt-get install -y openjdk-11-jdk + - export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64 + - export PATH=$PATH:$JAVA_HOME/bin + - cp /usr/lib/jvm/zulu8.44.0.13-ca-fx-jdk8.0.242-linux_x64/lib/tools.jar /usr/lib/jvm/java-11-openjdk-amd64/lib/ - mvn sonar:sonar -Dsonar.projectKey=$PROJECT_KEY -Dsonar.projectVersion=${VERSION}-SNAPSHOT -Dsonar.host.url=$HOST_URL -Dsonar.login=$LOGIN_KEY # So that the cache takes up less space - rm -rf .m2/repository/org/semoss From 03510f9e4c78562e4b4694d5e7d64d599a6a1e90 Mon Sep 17 00:00:00 2001 From: kunalppatel9 Date: Wed, 11 Aug 2021 21:40:40 +0000 Subject: [PATCH 0832/1906] UPDATE ::: Updating gitlab pipeline for sonarqube git-svn-id: svn://107.170.10.188:8080/Monolith/dev@44540 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 560c0a2129d11cd7d670c31f7aa8996328414728 --- .gitlab-ci.yml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d419a6a79..dbaa37e25 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -67,15 +67,18 @@ build_monolith_sonar: variables: - $RELEASE == "TRUE" script: - - apt-get update + - apt-get -y update - apt-get install -y openjfx # So that the most up-to-date artifacts are pulled - rm -rf .m2/repository/org/semoss - mvn $MAVEN_CLI_OPTS verify -Dmaven.test.skip=$SKIP_TESTS -Dci.version=${VERSION}-SNAPSHOT - - apt-get install -y openjdk-11-jdk - - export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64 + - wget https://cdn.azul.com/zulu/bin/zulu11.50.19-ca-jdk11.0.12-linux_amd64.deb + - apt install ./zulu11.50.19-ca-jdk11.0.12-linux_amd64.deb + - rm zulu11.50.19-ca-jdk11.0.12-linux_amd64.deb + - update-alternatives --set java /usr/lib/jvm/zulu-11-amd64/bin/java + - export JAVA_HOME=/usr/lib/jvm/zulu-11-amd64 - export PATH=$PATH:$JAVA_HOME/bin - - cp /usr/lib/jvm/zulu8.44.0.13-ca-fx-jdk8.0.242-linux_x64/lib/tools.jar /usr/lib/jvm/java-11-openjdk-amd64/lib/ + - cp /usr/lib/jvm/java-8-openjdk-amd64/lib/tools.jar /usr/lib/jvm/zulu-11-amd64/lib/ - mvn sonar:sonar -Dsonar.projectKey=$PROJECT_KEY -Dsonar.projectVersion=${VERSION}-SNAPSHOT -Dsonar.host.url=$HOST_URL -Dsonar.login=$LOGIN_KEY # So that the cache takes up less space - rm -rf .m2/repository/org/semoss From c421714d44492f4034dd8d4f8f5e0820971a9d4a Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 13 Aug 2021 20:33:00 +0000 Subject: [PATCH 0833/1906] UPDATE ::: Testing new way of parsing the PIV given VA has altered the structure git-svn-id: svn://107.170.10.188:8080/Monolith/dev@44565 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 85a0fd6af6f1652b6f03bb41225b89607a6c5d2d --- .../web/services/local/DatabaseResource.java | 2 +- src/prerna/web/conf/PIVFilter.java | 36 ++++++++++--------- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/prerna/semoss/web/services/local/DatabaseResource.java b/src/prerna/semoss/web/services/local/DatabaseResource.java index d2d1eb158..91370ce04 100644 --- a/src/prerna/semoss/web/services/local/DatabaseResource.java +++ b/src/prerna/semoss/web/services/local/DatabaseResource.java @@ -72,7 +72,7 @@ private boolean canAccessApp(User user, String databaseId) throws IllegalAccessE /////////////////////////////////////////////////////////////////////////////////////////////////////// /* - * Code below is around app images and insight images + * Code below is around app images */ @GET diff --git a/src/prerna/web/conf/PIVFilter.java b/src/prerna/web/conf/PIVFilter.java index 2f20c2e03..49ff1b008 100644 --- a/src/prerna/web/conf/PIVFilter.java +++ b/src/prerna/web/conf/PIVFilter.java @@ -92,28 +92,30 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 // get the full value // this should be an email email = rdn.getValue().toString(); - // make sure valid email - if(email == null || !email.contains("@")) { - try { - EMAIL_LOOP : for(List altNames : cert.getSubjectAlternativeNames()) { - for(Object alternative : altNames) { - if(alternative instanceof String) { - String altStr = alternative.toString(); - // really simple email check... - if(altStr.contains("@")) { - email = altStr; - break EMAIL_LOOP; - } + } + // CN for name + else if(rdn.getType().equals("CN")) { + name = rdn.getValue().toString(); + } + + // if email still not valid - check alt names + if(email == null || !email.contains("@")) { + try { + EMAIL_LOOP : for(List altNames : cert.getSubjectAlternativeNames()) { + for(Object alternative : altNames) { + if(alternative instanceof String) { + String altStr = alternative.toString(); + // really simple email check... + if(altStr.contains("@")) { + email = altStr; + break EMAIL_LOOP; } } } - } catch (CertificateParsingException e) { - logger.error(Constants.STACKTRACE, e); } + } catch (CertificateParsingException e) { + logger.error(Constants.STACKTRACE, e); } - // CN for name - } else if(rdn.getType().equals("CN")) { - name = rdn.getValue().toString(); } // lets make sure we have all the stuff From 5fc907f78fcd2d64d46bd9f2b365982a73e82b0e Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Tue, 17 Aug 2021 12:49:03 +0000 Subject: [PATCH 0834/1906] UPDATE ::: Putting temporary fix by adding: rm -rf /var/lib/apt/lists/* before apt-get update -y git-svn-id: svn://107.170.10.188:8080/Monolith/dev@44589 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 58da3edaa1cfc5ae54f8c495e64eb4a9530dcff2 --- .gitlab-ci.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index dbaa37e25..9b062c988 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -42,7 +42,8 @@ build_monolith_dev: - $RELEASE == "TRUE" - $SONARPUSH == "TRUE" script: - - apt-get update + - rm -rf /var/lib/apt/lists/* + - apt-get update -y - apt-get install -y openjfx # So that the most up-to-date artifacts are pulled - rm -rf .m2/repository/org/semoss @@ -99,7 +100,8 @@ build_monolith_deploy: variables: - $RELEASE == "TRUE" script: - - apt-get update + - rm -rf /var/lib/apt/lists/* + - apt-get update -y - apt-get install -y openjfx - apt-get install -y gnupg2 - gpg2 --batch --import <(echo "$GPG_PRIVATE_KEY") @@ -123,7 +125,8 @@ build_monolith_release: variables: - $RELEASE == "TRUE" script: - - apt-get update + - rm -rf /var/lib/apt/lists/* + - apt-get update -y - apt-get install -y openjfx - apt-get install -y gnupg2 - gpg2 --batch --import <(echo "$GPG_PRIVATE_KEY") From ab147c05e41aa4dad5e48c09509f2fbafec9c6ae Mon Sep 17 00:00:00 2001 From: kunalppatel9 Date: Tue, 17 Aug 2021 13:20:17 +0000 Subject: [PATCH 0835/1906] UPDATE ::: Updating gitlab pipeline with allowing releaseinfo changes git-svn-id: svn://107.170.10.188:8080/Monolith/dev@44595 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 44ac6d26c2eb5c0b0bfda5050737a47de14425b2 --- .gitlab-ci.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 9b062c988..3c45f752a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -42,7 +42,7 @@ build_monolith_dev: - $RELEASE == "TRUE" - $SONARPUSH == "TRUE" script: - - rm -rf /var/lib/apt/lists/* + - apt-get --allow-releaseinfo-change update -y - apt-get update -y - apt-get install -y openjfx # So that the most up-to-date artifacts are pulled @@ -68,6 +68,7 @@ build_monolith_sonar: variables: - $RELEASE == "TRUE" script: + - apt-get --allow-releaseinfo-change update -y - apt-get -y update - apt-get install -y openjfx # So that the most up-to-date artifacts are pulled @@ -100,7 +101,7 @@ build_monolith_deploy: variables: - $RELEASE == "TRUE" script: - - rm -rf /var/lib/apt/lists/* + - apt-get --allow-releaseinfo-change update -y - apt-get update -y - apt-get install -y openjfx - apt-get install -y gnupg2 @@ -125,7 +126,7 @@ build_monolith_release: variables: - $RELEASE == "TRUE" script: - - rm -rf /var/lib/apt/lists/* + - apt-get --allow-releaseinfo-change update -y - apt-get update -y - apt-get install -y openjfx - apt-get install -y gnupg2 From b488e26e7ada6be38e463e8f07382f53f2742276 Mon Sep 17 00:00:00 2001 From: kunalppatel9 Date: Tue, 17 Aug 2021 14:28:13 +0000 Subject: [PATCH 0836/1906] UPDATE ::: reverting allowing releaseinfo changes git-svn-id: svn://107.170.10.188:8080/Monolith/dev@44598 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 2c59edbc343e8d2adaf5f1553778bea270dd11e5 --- .gitlab-ci.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 3c45f752a..c50624b94 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -42,7 +42,7 @@ build_monolith_dev: - $RELEASE == "TRUE" - $SONARPUSH == "TRUE" script: - - apt-get --allow-releaseinfo-change update -y + - rm -rf /var/lib/apt/lists/* - apt-get update -y - apt-get install -y openjfx # So that the most up-to-date artifacts are pulled @@ -68,7 +68,7 @@ build_monolith_sonar: variables: - $RELEASE == "TRUE" script: - - apt-get --allow-releaseinfo-change update -y + - rm -rf /var/lib/apt/lists/* - apt-get -y update - apt-get install -y openjfx # So that the most up-to-date artifacts are pulled @@ -101,7 +101,7 @@ build_monolith_deploy: variables: - $RELEASE == "TRUE" script: - - apt-get --allow-releaseinfo-change update -y + - rm -rf /var/lib/apt/lists/* - apt-get update -y - apt-get install -y openjfx - apt-get install -y gnupg2 @@ -126,7 +126,7 @@ build_monolith_release: variables: - $RELEASE == "TRUE" script: - - apt-get --allow-releaseinfo-change update -y + - rm -rf /var/lib/apt/lists/* - apt-get update -y - apt-get install -y openjfx - apt-get install -y gnupg2 From 351a3e25259c6680fb67f4dffa2e62477831e5d6 Mon Sep 17 00:00:00 2001 From: kunalppatel9 Date: Tue, 17 Aug 2021 19:30:43 +0000 Subject: [PATCH 0837/1906] UPDATE ::: sonarqube - removing unused jars with vulnerabilities git-svn-id: svn://107.170.10.188:8080/Monolith/dev@44603 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 06120e9736bc5105848c356d8ba7a8907a93d4c6 --- pom.xml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index 1ac039824..81f0ffb45 100644 --- a/pom.xml +++ b/pom.xml @@ -841,11 +841,11 @@ - + org.codehaus.jet jet-regression @@ -1781,7 +1781,7 @@ - + net.snowflake snowflake-jdbc From 0ec5bbd205a2d451dd555087163b2ef76b260d02 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Wed, 18 Aug 2021 19:52:53 +0000 Subject: [PATCH 0838/1906] UPDATE ::: Making initialization more fault tolerant and providing feedback for required missing watchers (ENGINE_WEB_WATCHER, PROJECT_WATCHER) git-svn-id: svn://107.170.10.188:8080/Monolith/dev@44615 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 7fe7051dab46ee20a5d42a87d2513995bd0ebf7c --- src/prerna/web/conf/DBLoader.java | 37 ++++++++++++++++++------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/src/prerna/web/conf/DBLoader.java b/src/prerna/web/conf/DBLoader.java index dda33164e..d2eb68e42 100644 --- a/src/prerna/web/conf/DBLoader.java +++ b/src/prerna/web/conf/DBLoader.java @@ -211,24 +211,31 @@ public void contextInitialized(ServletContextEvent arg0) { } } - public void loadSmss(String pathKey) { - StringTokenizer watchers = new StringTokenizer(DIHelper.getInstance().getProperty(pathKey), ";"); + private void loadSmss(String pathKey) { + String pathValue = DIHelper.getInstance().getProperty(pathKey); + if(pathValue == null || pathValue.trim().isEmpty()) { + throw new NullPointerException("Error occured - could not find " + pathKey + " in RDF_Map.prop which is required for starting the application"); + } + + StringTokenizer watchers = new StringTokenizer(pathValue, ";"); try { while (watchers.hasMoreElements()) { - Object monitor = new Object(); String watcher = watchers.nextToken(); - String watcherClass = DIHelper.getInstance().getProperty(watcher); - String folder = DIHelper.getInstance().getProperty(watcher + "_DIR"); - String ext = DIHelper.getInstance().getProperty(watcher + "_EXT"); - AbstractFileWatcher watcherInstance = (AbstractFileWatcher) Class.forName(watcherClass).getConstructor(null).newInstance(null); - watcherInstance.setMonitor(monitor); - watcherInstance.setFolderToWatch(folder); - watcherInstance.setExtension(ext); - watcherInstance.init(); - synchronized (monitor) { - Thread thread = new Thread(watcherInstance); - thread.start(); - watcherList.add(watcherInstance); + if(watcher != null && !(watcher=watcher.trim()).isEmpty()) { + Object monitor = new Object(); + String watcherClass = DIHelper.getInstance().getProperty(watcher); + String folder = DIHelper.getInstance().getProperty(watcher + "_DIR"); + String ext = DIHelper.getInstance().getProperty(watcher + "_EXT"); + AbstractFileWatcher watcherInstance = (AbstractFileWatcher) Class.forName(watcherClass).getConstructor(null).newInstance(null); + watcherInstance.setMonitor(monitor); + watcherInstance.setFolderToWatch(folder); + watcherInstance.setExtension(ext); + watcherInstance.init(); + synchronized (monitor) { + Thread thread = new Thread(watcherInstance); + thread.start(); + watcherList.add(watcherInstance); + } } } } catch (Exception ex) { From 8746d4997bf09fdc462b943bbe3619064dc56dba Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 19 Aug 2021 14:33:37 +0000 Subject: [PATCH 0839/1906] UPDATE ::: Ordering and adding websocket to list of webcontent folders to include git-svn-id: svn://107.170.10.188:8080/Monolith/dev@44621 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 59c44a429c521de8f0b285eb8766cd1a1ff05580 --- pom.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 81f0ffb45..2c9ef0aae 100644 --- a/pom.xml +++ b/pom.xml @@ -82,8 +82,9 @@ samlLogin/**, sessionCounterFail/**, setAdmin/**, - startUpFail/**, share/** + startUpFail/**, + websocket/** From 952810ad66d44234e164decd98ae9c2fef855211 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 19 Aug 2021 15:01:43 +0000 Subject: [PATCH 0840/1906] UPDATE ::: Adding the web content in the deploy section as well git-svn-id: svn://107.170.10.188:8080/Monolith/dev@44623 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 9442de6e16c9f0fe3fc426995488accc5c2e03ef --- pom.xml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 2c9ef0aae..d16d7a094 100644 --- a/pom.xml +++ b/pom.xml @@ -131,9 +131,12 @@ logout/**, noUserFail/**, + samlLogin/**, + sessionCounterFail/**, setAdmin/**, - share/**, + share/** startUpFail/**, + websocket/** %regex[WEB-INF/lib/(?!semoss-${ci.version}).*.jar] From b75cf5470fa9d9c0dbec1c57f4555e2af48e2d58 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 19 Aug 2021 16:10:41 +0000 Subject: [PATCH 0841/1906] BUGFIX ::: Adding missing , between webcontent values git-svn-id: svn://107.170.10.188:8080/Monolith/dev@44627 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 1e657ad2f96a55dbaeded588f17305de2e0162e0 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index d16d7a094..063637f0f 100644 --- a/pom.xml +++ b/pom.xml @@ -82,7 +82,7 @@ samlLogin/**, sessionCounterFail/**, setAdmin/**, - share/** + share/**, startUpFail/**, websocket/** @@ -134,7 +134,7 @@ samlLogin/**, sessionCounterFail/**, setAdmin/**, - share/** + share/**, startUpFail/**, websocket/** From e5445b5c56771d5677361e9d4fa5821e15fb5a51 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Thu, 19 Aug 2021 21:39:03 +0000 Subject: [PATCH 0842/1906] BUGFIX ::: Fixing error with the session counter exceeded logic and adding logs BUGFIX ::: Adding additional checks to make sure we don't invalidate an already invalidated session object git-svn-id: svn://107.170.10.188:8080/Monolith/dev@44631 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: b182a5b426fa08a9d59ab5d0e8d7ab4052a065a0 --- .../config/ServerConfigurationResource.java | 15 +++--- .../web/services/local/SessionResource.java | 8 ++-- .../web/conf/FilespaceAccessFilter.java | 38 +++++++-------- .../web/conf/NoUserInSessionFilter.java | 28 ++++++----- .../NoUserInSessionTrustedTokenFilter.java | 16 +++++-- .../conf/SessionCounterExceededFilter.java | 47 +++++++++++-------- 6 files changed, 84 insertions(+), 68 deletions(-) diff --git a/src/prerna/semoss/web/services/config/ServerConfigurationResource.java b/src/prerna/semoss/web/services/config/ServerConfigurationResource.java index 6f61c45fc..25320fca0 100644 --- a/src/prerna/semoss/web/services/config/ServerConfigurationResource.java +++ b/src/prerna/semoss/web/services/config/ServerConfigurationResource.java @@ -47,8 +47,6 @@ public class ServerConfigurationResource { * @return */ private static Map getConfig(@Context HttpServletRequest request) { - HttpSession session = request.getSession(true); - User user = null; try { user = ResourceUtility.getUser(request); @@ -57,20 +55,20 @@ private static Map getConfig(@Context HttpServletRequest request } if(config != null) { - return getConfiguration(session, user); + return getConfiguration(request, user); } // make thread safe synchronized (ServerConfigurationResource.class) { if (config == null) { - loadConfig(session); + loadConfig(); } } - return getConfiguration(session, user); + return getConfiguration(request, user); } - private static void loadConfig(HttpSession session) { + private static void loadConfig() { Map loadConfig = new HashMap<>(); // r enabled @@ -161,10 +159,11 @@ private static void loadConfig(HttpSession session) { ServerConfigurationResource.config = loadConfig; } - private static Map getConfiguration(HttpSession session, User user) { + private static Map getConfiguration(@Context HttpServletRequest request, User user) { // do not keep this session // if no user and it is new - if (session.isNew() && user == null) { + HttpSession session = request.getSession(); + if (user == null && session.isNew() && request.isRequestedSessionIdValid()) { session.invalidate(); } diff --git a/src/prerna/semoss/web/services/local/SessionResource.java b/src/prerna/semoss/web/services/local/SessionResource.java index 2f71a07b4..74cab82af 100644 --- a/src/prerna/semoss/web/services/local/SessionResource.java +++ b/src/prerna/semoss/web/services/local/SessionResource.java @@ -70,7 +70,9 @@ public Response getActiveSessions(@Context HttpServletRequest request) { } } - StandardManager manager = getManager(request); + // the session needs to exist if the user is to exist... + HttpSession session = request.getSession(false); + StandardManager manager = getManager(session); Map ret = new HashMap<>(); if(manager != null) { @@ -85,8 +87,8 @@ public Response getActiveSessions(@Context HttpServletRequest request) { * Getting the manager * @param request */ - public static StandardManager getManager(@Context HttpServletRequest request) { - ApplicationContextFacade applicationContextFacade = (ApplicationContextFacade) request.getSession().getServletContext(); + public static StandardManager getManager(HttpSession session) { + ApplicationContextFacade applicationContextFacade = (ApplicationContextFacade) session.getServletContext(); try { Field applicationContextField = applicationContextFacade.getClass().getDeclaredField("context"); applicationContextField.setAccessible(true); diff --git a/src/prerna/web/conf/FilespaceAccessFilter.java b/src/prerna/web/conf/FilespaceAccessFilter.java index 8a8e93357..f1433131c 100644 --- a/src/prerna/web/conf/FilespaceAccessFilter.java +++ b/src/prerna/web/conf/FilespaceAccessFilter.java @@ -17,17 +17,8 @@ public class FilespaceAccessFilter implements Filter { @Override - public void init(FilterConfig filterConfig) throws ServletException { - // TODO Auto-generated method stub - - } - - @Override - public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) - throws IOException, ServletException { - // TODO Auto-generated method stub - try - { + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + try { // get the space it is trying to access // get the user from the session // see if this user can access this space @@ -38,26 +29,22 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha // http://blah blah/Monolith/public_home/app__app_id/something String publicHome = "/" + Constants.PUBLIC_HOME + "/"; int publicHomeIndex = url.indexOf(publicHome); - if(publicHomeIndex >= 0) - { + if(publicHomeIndex >= 0) { String appHome = url.substring(publicHomeIndex + publicHome.length()); int appRootIndex = appHome.indexOf("/"); - if(appRootIndex >= 0) - { + if(appRootIndex >= 0) { String appRoot = appHome.substring(0, appRootIndex); String [] appRootElements = appRoot.split("__"); - User user = (User)hsr.getSession().getAttribute(Constants.SESSION_USER); - if(user.checkProjectAccess(appRootElements[0], appRootElements[1])) + User user = (User) hsr.getSession().getAttribute(Constants.SESSION_USER); + if(user.checkProjectAccess(appRootElements[0], appRootElements[1])) { chain.doFilter(request, response); - else - { + } else { ((HttpServletResponse)response).sendError(HttpServletResponse.SC_FORBIDDEN, " You are not allowed to access that resource ");; } } } - }catch(Exception ex) - { - + } catch(Exception ex) { + ex.printStackTrace(); } } @@ -66,5 +53,12 @@ public void destroy() { // TODO Auto-generated method stub } + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + // TODO Auto-generated method stub + + } + } diff --git a/src/prerna/web/conf/NoUserInSessionFilter.java b/src/prerna/web/conf/NoUserInSessionFilter.java index 7e9028731..4a039f747 100644 --- a/src/prerna/web/conf/NoUserInSessionFilter.java +++ b/src/prerna/web/conf/NoUserInSessionFilter.java @@ -152,11 +152,13 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 // add the hash cookie String hash = req.getParameter("hash"); - Cookie h = new Cookie("HASH", Utility.cleanHttpResponse(hash)); - h.setHttpOnly(true); - h.setSecure(req.isSecure()); - h.setPath(contextPath); - ((HttpServletResponse) arg1).addCookie(h); + if(hash != null) { + Cookie h = new Cookie("HASH", Utility.cleanHttpResponse(hash)); + h.setHttpOnly(true); + h.setSecure(req.isSecure()); + h.setPath(contextPath); + ((HttpServletResponse) arg1).addCookie(h); + } // and now redirect back to the URL // if get, we can do it @@ -192,7 +194,7 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 else { setInvalidEntryRedirect(context, arg0, arg1, LOGIN); // invalidate the session if necessary - if (session != null) { + if (session != null && ((HttpServletRequest) arg0).isRequestedSessionIdValid()) { session.invalidate(); } return; @@ -204,12 +206,14 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 // {@link UserResource#setMainPageRedirect(@Context HttpServletRequest request, // @Context HttpServletResponse response)} // is sent to the pop-up for OAuth login - String endpointRedirectUrl = Utility.cleanHttpResponse((String) session.getAttribute(NoUserInSessionFilter.ENDPOINT_REDIRECT_KEY)); - if (endpointRedirectUrl != null && !endpointRedirectUrl.isEmpty()) { - ((HttpServletResponse) arg1).setHeader("redirect", endpointRedirectUrl); - ((HttpServletResponse) arg1).sendError(302, "Need to redirect to " + endpointRedirectUrl); - session.removeAttribute(NoUserInSessionFilter.ENDPOINT_REDIRECT_KEY); - return; + if(session != null) { + String endpointRedirectUrl = Utility.cleanHttpResponse((String) session.getAttribute(NoUserInSessionFilter.ENDPOINT_REDIRECT_KEY)); + if (endpointRedirectUrl != null && !endpointRedirectUrl.isEmpty()) { + ((HttpServletResponse) arg1).setHeader("redirect", endpointRedirectUrl); + ((HttpServletResponse) arg1).sendError(302, "Need to redirect to " + endpointRedirectUrl); + session.removeAttribute(NoUserInSessionFilter.ENDPOINT_REDIRECT_KEY); + return; + } } // so we have a user diff --git a/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java b/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java index 054a33bd5..8569c0bac 100644 --- a/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java +++ b/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java @@ -82,9 +82,15 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 String redirectSessionId = sessionMapper.get(userId); if(redirectSessionId != null) { // validate that the session exists within tomcats session manager - StandardManager manager = SessionResource.getManager((HttpServletRequest) arg0); + session = ((HttpServletRequest) arg0).getSession(); + StandardManager manager = SessionResource.getManager(session); if(manager.getSession(redirectSessionId) != null) { redirectToExistingSession = true; + // we are going to try to redirect + // so invalidate this new session + if (((HttpServletRequest) arg0).isRequestedSessionIdValid()) { + session.invalidate(); + } } else { // remove from the session mapper sessionMapper.remove(userId); @@ -110,9 +116,6 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 // you are allowed // i just have to check if the token id exists // and id you do, i make the user object - if(session == null) { - session = req.getSession(true); - } user = new User(); AccessToken token = new AccessToken(); token.setProvider(AuthProvider.WINDOWS_USER); @@ -133,6 +136,11 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 + ( (ClusterUtil.IS_CLUSTER || req.isSecure()) ? "; Secure; SameSite=None" : "") ; ((HttpServletResponse) arg1).addHeader("Set-Cookie", setCookieString); + } else { + // invalidate the session + if(((HttpServletRequest) arg0).isRequestedSessionIdValid()) { + session.invalidate(); + } } } else { // this is the case where you redirect diff --git a/src/prerna/web/conf/SessionCounterExceededFilter.java b/src/prerna/web/conf/SessionCounterExceededFilter.java index eb5742e7d..f67dc6346 100644 --- a/src/prerna/web/conf/SessionCounterExceededFilter.java +++ b/src/prerna/web/conf/SessionCounterExceededFilter.java @@ -45,25 +45,34 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 } if(user == null && sessionLimit != null && sessionLimit > 0) { - StandardManager manager = SessionResource.getManager((HttpServletRequest) arg0); - if(manager != null) { - int currentSessions = manager.getActiveSessions(); - - if(currentSessions+1 > sessionLimit) { - // too many users - // this will be the deployment name of the app - String contextPath = context.getContextPath(); - - // this will be the full path of the request - // like http://localhost:8080/Monolith_Dev/api/engine/runPixel - String fullUrl = Utility.cleanHttpResponse(((HttpServletRequest) arg0).getRequestURL().toString()); - - if(!fullUrl.endsWith(FAIL_HTML)) { - // we redirect to the index.html page where we have pushed the admin page - String redirectUrl = fullUrl.substring(0, fullUrl.indexOf(contextPath) + contextPath.length()) + FAIL_HTML; - ((HttpServletResponse) arg1).setHeader("redirect", redirectUrl); - ((HttpServletResponse) arg1).sendError(302, "Need to redirect to " + redirectUrl); - return; + synchronized(SessionCounterExceededFilter.class) { + session = ((HttpServletRequest)arg0).getSession(); + StandardManager manager = SessionResource.getManager(session); + if(manager != null) { + // note this includes the new session that was just created here + int currentSessions = manager.getActiveSessions(); + if(currentSessions > sessionLimit) { + logger.info("New user exceeds the # of allowed sessions = " + sessionLimit); + + // invalidate the session that was created for the manager + session.invalidate(); + // too many users + // this will be the deployment name of the app + String contextPath = context.getContextPath(); + + // this will be the full path of the request + // like http://localhost:8080/Monolith_Dev/api/engine/runPixel + String fullUrl = Utility.cleanHttpResponse(((HttpServletRequest) arg0).getRequestURL().toString()); + + if(!fullUrl.endsWith(FAIL_HTML)) { + // we redirect to the index.html page where we have pushed the admin page + String redirectUrl = fullUrl.substring(0, fullUrl.indexOf(contextPath) + contextPath.length()) + FAIL_HTML; + ((HttpServletResponse) arg1).setHeader("redirect", redirectUrl); + ((HttpServletResponse) arg1).sendError(302, "Need to redirect to " + redirectUrl); + return; + } + } else { + logger.info("New user login makes session #" + currentSessions); } } } From 587ab6735a9aa2118b32382f08c51de9df65862d Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 20 Aug 2021 12:49:57 +0000 Subject: [PATCH 0843/1906] UPDATE ::: Adding back commented out jar for templates and increasing the jar version git-svn-id: svn://107.170.10.188:8080/Monolith/dev@44639 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 071b75a25d3635279406cc6f517614574a84188c --- pom.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 063637f0f..953291bff 100644 --- a/pom.xml +++ b/pom.xml @@ -1785,17 +1785,17 @@ - + net.snowflake snowflake-jdbc From 48f33c51dfba0e58de637748577fa9e33834d6dd Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 20 Aug 2021 16:35:42 +0000 Subject: [PATCH 0844/1906] UPDATE ::: Adding more validation logic on input to account for accidental whitespace git-svn-id: svn://107.170.10.188:8080/Monolith/dev@44651 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: 3365e204dbac086a0812abcb1f0205a8679db76f --- src/prerna/web/conf/MemoryCheckFilter.java | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/prerna/web/conf/MemoryCheckFilter.java b/src/prerna/web/conf/MemoryCheckFilter.java index 9e4be9a75..00846cf33 100644 --- a/src/prerna/web/conf/MemoryCheckFilter.java +++ b/src/prerna/web/conf/MemoryCheckFilter.java @@ -83,18 +83,24 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 */ private void isCheckMem() { String checkMemSettings = DIHelper.getInstance().getProperty(Settings.CHECK_MEM); - if(checkMemSettings != null) { + if(checkMemSettings != null && !(checkMemSettings=checkMemSettings.trim()).isEmpty()) { boolean checkMem = Boolean.parseBoolean(checkMemSettings); if(checkMem) { String memLimitSettings = DIHelper.getInstance().getProperty(Settings.USER_MEM_LIMIT); - int memLimit = Integer.parseInt(memLimitSettings); - - MemoryCheckFilter.memProfileSettings = DIHelper.getInstance().getProperty(Settings.MEM_PROFILE_SETTINGS); - MemoryCheckFilter.memLimit = memLimit; + String memProfileSetting = DIHelper.getInstance().getProperty(Settings.MEM_PROFILE_SETTINGS); + + if((memLimitSettings != null && !(memLimitSettings=memLimitSettings.trim()).isEmpty()) + && (memProfileSetting != null && !(memProfileSetting=memProfileSetting.trim()).isEmpty()) + ) { + int memLimit = Integer.parseInt(memLimitSettings); + MemoryCheckFilter.memProfileSettings = memProfileSetting; + MemoryCheckFilter.memLimit = memLimit; + } } MemoryCheckFilter.checkMem = checkMem; return; } + // default is false MemoryCheckFilter.checkMem = false; } From be069348f230f19e2e3d9477a7df14bdaba50d8d Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 20 Aug 2021 19:33:06 +0000 Subject: [PATCH 0845/1906] BUGFIX ::: If the session doesn't exist yet - start one git-svn-id: svn://107.170.10.188:8080/Monolith/dev@44656 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: a668118699e926982462aae16a04407530bb1b26 --- src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java b/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java index 8569c0bac..473b0c542 100644 --- a/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java +++ b/src/prerna/web/conf/NoUserInSessionTrustedTokenFilter.java @@ -122,6 +122,11 @@ public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2 token.setId(userId); token.setName(userId); user.setAccessToken(token); + // if the session hasn't been instantiated yet + // start one + if(session == null) { + session = ((HttpServletRequest) arg0).getSession(); + } session.setAttribute(Constants.SESSION_USER, user); String sessionId = session.getId(); From 34e525a786a5c0a5fe719c6fa9b64e537b85dfad Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 20 Aug 2021 22:14:47 +0000 Subject: [PATCH 0846/1906] UPDATE ::: Sonarqube fixes - null pointer fixes git-svn-id: svn://107.170.10.188:8080/Monolith/dev@44661 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: fa1d75a5f8bace2fbbf7275b96565ae8d6ef41c5 --- src/prerna/semoss/web/services/local/NameServer.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/prerna/semoss/web/services/local/NameServer.java b/src/prerna/semoss/web/services/local/NameServer.java index 066d288c3..012a1007d 100644 --- a/src/prerna/semoss/web/services/local/NameServer.java +++ b/src/prerna/semoss/web/services/local/NameServer.java @@ -187,7 +187,7 @@ public Object getInsightDataFrame(@PathParam("insightID") String insightID, // } // } // } - } else if (insightID.equals("new")) { + } else if (insightID == null || insightID.equals("new")) { // get the data frame type and set it from the FE if (dataFrameType == null) { dataFrameType = "H2Frame"; @@ -484,7 +484,7 @@ private Response runPixelJob(User user, Insight insight, String expression, Stri * @param expression * @return */ - private Response getInsightPipeline(Insight insight) { + private Response getInsightPipeline(final Insight insight) { synchronized (insight) { try { return Response.status(200) @@ -597,8 +597,9 @@ public Response status(MultivaluedMap form, @Context HttpServlet JobThread jt = JobManager.getManager().getJob(jobId); if(jt == null) { dataReturn = JobStatus.UNKNOWN_JOB.getValue(); + } else { + dataReturn = jt.getStatus(); } - dataReturn = jt.getStatus(); } return WebUtility.getResponseNoCache(dataReturn, 200); } From f2ce3d0ee08be2f56dff4b40c03928e072052956 Mon Sep 17 00:00:00 2001 From: Maher Khalil Date: Fri, 20 Aug 2021 22:34:29 +0000 Subject: [PATCH 0847/1906] UPDATE ::: Pushing sonarqube fixes in the static html files git-svn-id: svn://107.170.10.188:8080/Monolith/dev@44665 ef391c1c-ee15-45f7-b1d6-dde3d27a2169 Former-commit-id: b70411679b37116588d74ce577dd48ddbc3a81d3 --- WebContent/logout/index.html | 7 +- WebContent/noUserFail/index.html | 10 +- WebContent/samlLogin/index.html | 33 +- WebContent/sessionCounterFail/index.html | 10 +- WebContent/setAdmin/index.html | 510 +++++++++---------- WebContent/share/index.html | 598 +++++++++++------------ WebContent/startUpFail/index.html | 10 +- WebContent/websocket/index.html | 18 +- WebContent/websocket/websocket.js | 2 +- 9 files changed, 608 insertions(+), 590 deletions(-) diff --git a/WebContent/logout/index.html b/WebContent/logout/index.html index 7549a61ca..79ea4fad8 100644 --- a/WebContent/logout/index.html +++ b/WebContent/logout/index.html @@ -1,5 +1,8 @@ - + + + Logout + - + - + + .register__box { + position: relative; + display: block; + margin: 0 auto; + max-width: 500px; + width: 80%; + border: 1px solid #E7E7E7; + border: 1px solid var(--color-grey3); + background: #FFFFFF; + padding: 8px; + } + - - + + - -
-
-
-
- Please set your initial admin: -
-
- + +
+ +
+
+ Please set your initial admin: +
+
+ +
-
-
-
- -
- -
-
- Utilize this table to determine what value to enter +
+
+ +
+ +
+
+ Utilize this table to determine what value to enter +
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Login TypeInput Value
Google OAuthEmail
Github OAuthEmail (must have an email set on public profile)
Microsoft OAuthEmail
Native Login / PasswordUsername (must match value to be entered on registration page)
X.509 CertificatesEmail
Windows Authentication - WaffleUsername (e.g. US\jsmith)
- -
- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Login TypeInput Value
Google OAuthEmail
Github OAuthEmail (must have an email set on public profile)
Microsoft OAuthEmail
Native Login / PasswordUsername (must match value to be entered on registration page)
X.509 CertificatesEmail
Windows Authentication - WaffleUsername (e.g. US\jsmith)
+ +
+ \ No newline at end of file diff --git a/WebContent/share/index.html b/WebContent/share/index.html index c37727846..77c405668 100644 --- a/WebContent/share/index.html +++ b/WebContent/share/index.html @@ -1,333 +1,333 @@ - + + + Tableau Share + + - - - - - - + - - - + } + + - -