From 09fd1ef6f6f6dfaacb81111e38dde1400f6e957d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lui=CC=81s=20A=2E=20Bastia=CC=83o=20Silva?= Date: Sat, 23 Jan 2016 17:45:19 +0000 Subject: [PATCH 01/31] Added a test to see how users work --- .../pt/ua/dicoogle/core/auth/TestUsers.java | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 dicoogle/src/test/java/pt/ua/dicoogle/core/auth/TestUsers.java diff --git a/dicoogle/src/test/java/pt/ua/dicoogle/core/auth/TestUsers.java b/dicoogle/src/test/java/pt/ua/dicoogle/core/auth/TestUsers.java new file mode 100644 index 000000000..a9a0c010c --- /dev/null +++ b/dicoogle/src/test/java/pt/ua/dicoogle/core/auth/TestUsers.java @@ -0,0 +1,82 @@ +/** + * Copyright (C) 2014 Universidade de Aveiro, DETI/IEETA, Bioinformatics Group - http://bioinformatics.ua.pt/ + * + * This file is part of Dicoogle/dicoogle. + * + * Dicoogle/dicoogle 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 3 of the License, or + * (at your option) any later version. + * + * Dicoogle/dicoogle 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. + * + * You should have received a copy of the GNU General Public License + * along with Dicoogle. If not, see . + */ +package pt.ua.dicoogle.core.auth; + +import org.junit.*; +import pt.ua.dicoogle.server.users.HashService; +import pt.ua.dicoogle.server.users.User; +import pt.ua.dicoogle.server.users.UsersStruct; +import pt.ua.dicoogle.server.users.UsersXML; +import pt.ua.dicoogle.server.web.auth.Authentication; +import pt.ua.dicoogle.server.web.auth.LoggedIn; + +import static org.junit.Assert.assertEquals; +import static pt.ua.dicoogle.server.web.servlets.webui.WebUIServlet.camelize; + +/** + * Created by bastiao on 23/01/16. + */ +public class TestUsers { + @BeforeClass + public static void setUpClass() { + } + + @AfterClass + public static void tearDownClass() { + } + + @Before + public void setUp() { + } + + @After + public void tearDown() { + } + + @Test + public void testUsers() { + + UsersStruct users = UsersStruct.getInstance(); + UsersXML usersXML = new UsersXML(); + users = usersXML.getXML(); + + String username = "nat"; + boolean admin = false; + String passPlainText = "123"; + String passHash = HashService.getSHA1Hash(passPlainText); //password Hash + String hash = HashService.getSHA1Hash(username + admin + passHash); + System.out.println(hash); + System.out.println(passHash); + User u = new User("nat",hash, admin); + users.addUser(u); + + + for (String uu : users.getUsernames()) + { + System.out.println(users.getUser(uu)); + } + + Authentication auth = Authentication.getInstance(); + LoggedIn loggedIn = auth.login("nat", "123"); + System.out.println(loggedIn.getUserName()); + System.out.println(loggedIn.isAdmin()); + + } + +} From 2786988b8c549769f297db5cab0b3a00beccbd8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lui=CC=81s=20A=2E=20Bastia=CC=83o=20Silva?= Date: Sat, 23 Jan 2016 17:52:22 +0000 Subject: [PATCH 02/31] Jump to 2.3.0 --- dicoogle/pom.xml | 2 +- pom.xml | 2 +- sdk-ext/pom.xml | 2 +- sdk/pom.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dicoogle/pom.xml b/dicoogle/pom.xml index a5a6cc2eb..97ff66207 100644 --- a/dicoogle/pom.xml +++ b/dicoogle/pom.xml @@ -10,7 +10,7 @@ pt.ua.ieeta dicoogle-all - 2.3.0-SNAPSHOT + 2.3.0 ../pom.xml diff --git a/pom.xml b/pom.xml index 9ac3a9cdb..f06461ed3 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ 4.0.0 pt.ua.ieeta dicoogle-all - 2.3.0-SNAPSHOT + 2.3.0 pom dicoogle-all diff --git a/sdk-ext/pom.xml b/sdk-ext/pom.xml index 675cf62e1..8c67136f5 100644 --- a/sdk-ext/pom.xml +++ b/sdk-ext/pom.xml @@ -10,7 +10,7 @@ pt.ua.ieeta dicoogle-all - 2.3.0-SNAPSHOT + 2.3.0 ../pom.xml diff --git a/sdk/pom.xml b/sdk/pom.xml index f9c311832..65bd81789 100644 --- a/sdk/pom.xml +++ b/sdk/pom.xml @@ -10,7 +10,7 @@ pt.ua.ieeta dicoogle-all - 2.3.0-SNAPSHOT + 2.3.0 ../pom.xml From 2aaf3785e35f9ca6c953571db6daae6ded1aa9c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lui=CC=81s=20A=2E=20Bastia=CC=83o=20Silva?= Date: Sat, 23 Jan 2016 17:53:04 +0000 Subject: [PATCH 03/31] Trigger the result-batch in different levels --- .../webapp/WEB-INF/js/components/search/result/imageView.js | 3 ++- .../webapp/WEB-INF/js/components/search/result/serieView.js | 2 ++ .../webapp/WEB-INF/js/components/search/result/studyView.js | 3 ++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/imageView.js b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/imageView.js index dbc8fa8f5..4fb5c186e 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/imageView.js +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/imageView.js @@ -138,7 +138,8 @@ var ImageView = React.createClass({ bgColor: "rgb(163, 210, 216)", onSelect: this.onRowSelect }; - console.log("IMAGE LEVEL"); + // TODO trigger this action elsewhere + ResultSelectActions.level("image"); return (
diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/studyView.js b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/studyView.js index 259bedffd..37437bc8e 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/studyView.js +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/studyView.js @@ -108,7 +108,8 @@ var StudyView = React.createClass({ bgColor: "rgb(163, 210, 216)", onSelect: this.onRowSelect }; - + // TODO trigger this action elsewhere + ResultSelectActions.level("study"); return (
From 8951bb165e7cd653c6499da42d89f1f935063f06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lui=CC=81s=20A=2E=20Bastia=CC=83o=20Silva?= Date: Sat, 23 Jan 2016 17:59:13 +0000 Subject: [PATCH 04/31] Remove logs from repository --- dicoogle/dicoogle.log | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 dicoogle/dicoogle.log diff --git a/dicoogle/dicoogle.log b/dicoogle/dicoogle.log deleted file mode 100644 index e69de29bb..000000000 From a2af4fc958283ad0edb2e4cd8f8e656143e22031 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lui=CC=81s=20A=2E=20Bastia=CC=83o=20Silva?= Date: Sat, 23 Jan 2016 18:04:35 +0000 Subject: [PATCH 05/31] Allow non admin users to login --- .../dicoogle/server/web/servlets/accounts/LoginServlet.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/servlets/accounts/LoginServlet.java b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/servlets/accounts/LoginServlet.java index 8da34c9a5..3f2c472f7 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/servlets/accounts/LoginServlet.java +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/servlets/accounts/LoginServlet.java @@ -41,7 +41,9 @@ public class LoginServlet extends HttpServlet { protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //resp.addHeader("Access-Control-Allow-Origin", "*"); //Try login - LoggedIn mLoggedIn = Session.webappLogin(req, resp, true).getLogin();//servletLogin(req, resp, true);//auth.login(user, pass); + // Does not require admini rights. + LoggedIn mLoggedIn = Session.webappLogin(req, resp, false).getLogin(); + //servletLogin(req, resp, true);//auth.login(user, pass); if (mLoggedIn == null) { resp.sendError(401, "Login failed"); From 77515e71e061525fbf8c01d34d892848fdd0576a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lui=CC=81s=20A=2E=20Bastia=CC=83o=20Silva?= Date: Sat, 23 Jan 2016 18:23:12 +0000 Subject: [PATCH 06/31] Define role structure --- .../pt/ua/dicoogle/server/users/Role.java | 49 ++++ .../ua/dicoogle/server/users/RoleManager.java | 12 + .../pt/ua/dicoogle/server/users/RolesXML.java | 228 ++++++++++++++++++ .../pt/ua/dicoogle/server/users/User.java | 21 +- .../server/users/UserRoleManager.java | 10 + 5 files changed, 319 insertions(+), 1 deletion(-) create mode 100644 dicoogle/src/main/java/pt/ua/dicoogle/server/users/Role.java create mode 100644 dicoogle/src/main/java/pt/ua/dicoogle/server/users/RoleManager.java create mode 100755 dicoogle/src/main/java/pt/ua/dicoogle/server/users/RolesXML.java create mode 100644 dicoogle/src/main/java/pt/ua/dicoogle/server/users/UserRoleManager.java diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/users/Role.java b/dicoogle/src/main/java/pt/ua/dicoogle/server/users/Role.java new file mode 100644 index 000000000..54adf9f62 --- /dev/null +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/users/Role.java @@ -0,0 +1,49 @@ +package pt.ua.dicoogle.server.users; + +/** + * Created by bastiao on 23/01/16. + */ +public class Role { + + + private String name; + public Role(String name) + { + this.name = name; + + } + + + @Override + public String toString() { + return "Role{" + + "name='" + name + '\'' + + '}'; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Role role = (Role) o; + + return !(name != null ? !name.equals(role.name) : role.name != null); + + } + + @Override + public int hashCode() { + return name != null ? name.hashCode() : 0; + } +} diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/users/RoleManager.java b/dicoogle/src/main/java/pt/ua/dicoogle/server/users/RoleManager.java new file mode 100644 index 000000000..41bb3d0e8 --- /dev/null +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/users/RoleManager.java @@ -0,0 +1,12 @@ +package pt.ua.dicoogle.server.users; + +import java.util.List; + +/** + * Created by bastiao on 23/01/16. + */ +public interface RoleManager { + + public boolean hasRole(User user, Role r); + public List getRoles(); +} diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/users/RolesXML.java b/dicoogle/src/main/java/pt/ua/dicoogle/server/users/RolesXML.java new file mode 100755 index 000000000..972c6f9c1 --- /dev/null +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/users/RolesXML.java @@ -0,0 +1,228 @@ +/** + * Copyright (C) 2014 Universidade de Aveiro, DETI/IEETA, Bioinformatics Group - http://bioinformatics.ua.pt/ + * + * This file is part of Dicoogle/dicoogle. + * + * Dicoogle/dicoogle 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 3 of the License, or + * (at your option) any later version. + * + * Dicoogle/dicoogle 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. + * + * You should have received a copy of the GNU General Public License + * along with Dicoogle. If not, see . + */ +package pt.ua.dicoogle.server.users; + +import org.slf4j.LoggerFactory; +import org.xml.sax.Attributes; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; +import org.xml.sax.helpers.AttributesImpl; +import org.xml.sax.helpers.DefaultHandler; +import org.xml.sax.helpers.XMLReaderFactory; + +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.sax.SAXTransformerFactory; +import javax.xml.transform.sax.TransformerHandler; +import javax.xml.transform.stream.StreamResult; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.Iterator; + +/** + * This class saves the list of roles to XML + * + * @author Luís Bastião Silva + */ +public class RolesXML extends DefaultHandler +{ + private UsersStruct users = UsersStruct.getInstance(); + private boolean isUsers = false ; + + private String username; + private String Hash; + private boolean admin; + + + public RolesXML() + { + username = ""; + Hash = ""; + admin = false; + } + + + @Override + public void startElement( String uri, String localName, String qName, + Attributes attribs ) + { + + + + if (localName.equals("Users")) + { + isUsers = true ; + } + else if (this.isUsers && localName.equals("user")) + { + this.username = this.resolveAttrib("username", attribs, "xp"); + this.Hash = this.resolveAttrib("hash", attribs, "xp"); + + String temp = this.resolveAttrib("admin", attribs, "xp"); + if(temp.equals("true")) + this.admin = true; + else + this.admin = false; + } + + } + + + @Override + public void endElement( String uri, String localName, String qName ) + { + + if (localName.equals("Users")) + { + isUsers = false ; + } + else if( localName.equals( "user" ) ) + { + users.addUser(new User(username, Hash, admin)); + } + + } + + private String resolveAttrib( String attr, Attributes attribs, String defaultValue) { + String tmp = attribs.getValue(attr); + return (tmp!=null)?(tmp):(defaultValue); + } + + + public UsersStruct getXML() + { + users.reset(); + + try + { + UserFileHandle file = new UserFileHandle(); + byte[] xml = file.getFileContent(); + + if (xml == null) + { + //DebugManager.getInstance().debug("Setting users default, writing a file with the default information!"); + users.setDefaults(); + printXML(); + return users; + } + + + // Never throws the exception cause file not exists so need try catch + InputSource src = new InputSource( new ByteArrayInputStream(xml) ); + XMLReader r = XMLReaderFactory.createXMLReader(); + r.setContentHandler(this); + r.parse(src); + return users; + } + catch (SAXException | IOException ex) + { + LoggerFactory.getLogger(RolesXML.class).error(ex.getMessage(), ex); + } + return null; + } + + /** + * Print the users information to the XML file + */ + public void printXML() + { + + ByteArrayOutputStream out = new ByteArrayOutputStream(); + + + PrintWriter pw = new PrintWriter(out); + StreamResult streamResult = new StreamResult(pw); + SAXTransformerFactory tf = (SAXTransformerFactory) TransformerFactory.newInstance(); + // SAX2.0 ContentHandler. + TransformerHandler hd = null; + try + { + hd = tf.newTransformerHandler(); + } catch (TransformerConfigurationException ex) + { + LoggerFactory.getLogger(RolesXML.class).error(ex.getMessage(), ex); + } + + Transformer serializer = hd.getTransformer(); + serializer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); + serializer.setOutputProperty(OutputKeys.METHOD, "xml"); + serializer.setOutputProperty(OutputKeys.INDENT, "yes"); + serializer.setOutputProperty(OutputKeys.STANDALONE, "yes"); + try + { + hd.setResult(streamResult); + hd.startDocument(); + } catch (SAXException ex) + { + LoggerFactory.getLogger(RolesXML.class).error(ex.getMessage(), ex); + } + + AttributesImpl atts = new AttributesImpl(); + try + { + //root element + hd.startElement("", "", "Users", atts); + + Iterator us = UsersStruct.getInstance().getUsers().iterator(); + + atts.clear(); + while (us.hasNext()) + { + User user = us.next(); + + atts.addAttribute("", "", "username", "", user.getUsername()); + atts.addAttribute("", "", "hash", "", user.getPasswordHash()) ; + + String temp = "false"; + if(user.isAdmin()) + temp = "true"; + + atts.addAttribute("", "", "admin", "", temp) ; + + hd.startElement("", "", "user", atts); + atts.clear(); + hd.endElement("", "", "user"); + } + hd.endElement("", "", "Users"); + + + hd.endDocument(); + } catch (SAXException ex) + { + LoggerFactory.getLogger(RolesXML.class).error(ex.getMessage(), ex); + } + finally { + try { + out.close(); + + UserFileHandle file = new UserFileHandle(); + file.printFile(out.toByteArray()); + } catch (Exception ex) { + LoggerFactory.getLogger(RolesXML.class).error(ex.getMessage(), ex); + } + } + + + } +} diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/users/User.java b/dicoogle/src/main/java/pt/ua/dicoogle/server/users/User.java index d543fbd12..e25bbcca5 100755 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/users/User.java +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/users/User.java @@ -19,19 +19,24 @@ package pt.ua.dicoogle.server.users; +import java.util.ArrayList; +import java.util.List; import java.util.Objects; /** * Class that saves information about one user * * @author Samuel Campos + * @author Luís Bastião Silva */ -public class User { +public class User implements UserRoleManager{ private final String username; private String hash; //stores the Hash of this user (username + admin + passwordHash) private final boolean admin; + private List roles = new ArrayList<>(); + public User(String username, String Hash, boolean admin){ this.username = username; this.admin = admin; @@ -52,6 +57,16 @@ public boolean verifyPassword(String passwordHash){ return this.hash.equals(tempHash); } + public void addRole(Role r) + { + this.roles.add(r); + } + + public boolean hasRole(Role r) + { + return this.roles.contains(r); + } + public boolean changePassword(String oldPassHash, String newPassHash){ String tempHash = HashService.getSHA1Hash(username + admin + oldPassHash); @@ -113,4 +128,8 @@ public int hashCode() { public String toString() { return "User{" + username + (admin ? ", admin" : "") + '}'; } + + public List getRoles() { + return roles; + } } diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/users/UserRoleManager.java b/dicoogle/src/main/java/pt/ua/dicoogle/server/users/UserRoleManager.java new file mode 100644 index 000000000..8517742a2 --- /dev/null +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/users/UserRoleManager.java @@ -0,0 +1,10 @@ +package pt.ua.dicoogle.server.users; + +/** + * Created by bastiao on 23/01/16. + */ +public interface UserRoleManager { + + public boolean hasRole(Role r); + public void addRole(Role r); +} From 66eea5db9c01b8e5198979e49082c911d2e0b6bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lui=CC=81s=20A=2E=20Bastia=CC=83o=20Silva?= Date: Sat, 23 Jan 2016 19:36:29 +0000 Subject: [PATCH 07/31] Added Role Manager --- .../ua/dicoogle/server/users/RoleManager.java | 1 + .../ua/dicoogle/server/users/RolesStruct.java | 44 ++++++++++++ .../pt/ua/dicoogle/server/users/RolesXML.java | 70 +++++++------------ 3 files changed, 71 insertions(+), 44 deletions(-) create mode 100644 dicoogle/src/main/java/pt/ua/dicoogle/server/users/RolesStruct.java diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/users/RoleManager.java b/dicoogle/src/main/java/pt/ua/dicoogle/server/users/RoleManager.java index 41bb3d0e8..9dd30465c 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/users/RoleManager.java +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/users/RoleManager.java @@ -9,4 +9,5 @@ public interface RoleManager { public boolean hasRole(User user, Role r); public List getRoles(); + public void addRole(Role r); } diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/users/RolesStruct.java b/dicoogle/src/main/java/pt/ua/dicoogle/server/users/RolesStruct.java new file mode 100644 index 000000000..4d378921a --- /dev/null +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/users/RolesStruct.java @@ -0,0 +1,44 @@ +package pt.ua.dicoogle.server.users; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by bastiao on 23/01/16. + */ +public class RolesStruct implements RoleManager{ + + private static RolesStruct instance = null ; + + private List roles = new ArrayList<>(); + + public static synchronized RolesStruct getInstance() { + if (instance == null) { + instance = new RolesStruct(); + } + + return instance; + } + private RolesStruct(){ + reset(); + } + + public void reset(){ + roles = new ArrayList<>(); + } + + @Override + public boolean hasRole(User user, Role r) { + return UsersStruct.getInstance().getUser(user.getUsername()).hasRole(r); + } + + @Override + public List getRoles() { + return this.roles; + } + + @Override + public void addRole(Role r) { + this.roles.add(r); + } +} diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/users/RolesXML.java b/dicoogle/src/main/java/pt/ua/dicoogle/server/users/RolesXML.java index 972c6f9c1..e1ac0d986 100755 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/users/RolesXML.java +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/users/RolesXML.java @@ -47,19 +47,16 @@ */ public class RolesXML extends DefaultHandler { - private UsersStruct users = UsersStruct.getInstance(); - private boolean isUsers = false ; + private RolesStruct roles = RolesStruct.getInstance(); + private boolean isRoles = false ; + + private String rolename; - private String username; - private String Hash; - private boolean admin; public RolesXML() { - username = ""; - Hash = ""; - admin = false; + rolename = ""; } @@ -70,20 +67,13 @@ public void startElement( String uri, String localName, String qName, - if (localName.equals("Users")) + if (localName.equals("Roles")) { - isUsers = true ; + isRoles = true ; } - else if (this.isUsers && localName.equals("user")) + else if (this.isRoles && localName.equals("role")) { - this.username = this.resolveAttrib("username", attribs, "xp"); - this.Hash = this.resolveAttrib("hash", attribs, "xp"); - - String temp = this.resolveAttrib("admin", attribs, "xp"); - if(temp.equals("true")) - this.admin = true; - else - this.admin = false; + this.rolename = this.resolveAttrib("name", attribs, "xp"); } } @@ -95,11 +85,11 @@ public void endElement( String uri, String localName, String qName ) if (localName.equals("Users")) { - isUsers = false ; + isRoles = false ; } - else if( localName.equals( "user" ) ) + else if( localName.equals( "role" ) ) { - users.addUser(new User(username, Hash, admin)); + roles.addRole(new Role(rolename)); } } @@ -110,9 +100,9 @@ private String resolveAttrib( String attr, Attributes attribs, String defaultVal } - public UsersStruct getXML() + public RolesStruct getXML() { - users.reset(); + roles.reset(); try { @@ -121,10 +111,9 @@ public UsersStruct getXML() if (xml == null) { - //DebugManager.getInstance().debug("Setting users default, writing a file with the default information!"); - users.setDefaults(); + printXML(); - return users; + return roles; } @@ -133,7 +122,7 @@ public UsersStruct getXML() XMLReader r = XMLReaderFactory.createXMLReader(); r.setContentHandler(this); r.parse(src); - return users; + return roles; } catch (SAXException | IOException ex) { @@ -143,7 +132,7 @@ public UsersStruct getXML() } /** - * Print the users information to the XML file + * Print the roles information to the XML file */ public void printXML() { @@ -154,7 +143,7 @@ public void printXML() PrintWriter pw = new PrintWriter(out); StreamResult streamResult = new StreamResult(pw); SAXTransformerFactory tf = (SAXTransformerFactory) TransformerFactory.newInstance(); - // SAX2.0 ContentHandler. + TransformerHandler hd = null; try { @@ -182,29 +171,22 @@ public void printXML() try { //root element - hd.startElement("", "", "Users", atts); + hd.startElement("", "", "Roles", atts); - Iterator us = UsersStruct.getInstance().getUsers().iterator(); + Iterator us = RolesStruct.getInstance().getRoles().iterator(); atts.clear(); while (us.hasNext()) { - User user = us.next(); + Role role = us.next(); - atts.addAttribute("", "", "username", "", user.getUsername()); - atts.addAttribute("", "", "hash", "", user.getPasswordHash()) ; - - String temp = "false"; - if(user.isAdmin()) - temp = "true"; - - atts.addAttribute("", "", "admin", "", temp) ; + atts.addAttribute("", "", "name", "", role.getName()); - hd.startElement("", "", "user", atts); + hd.startElement("", "", "role", atts); atts.clear(); - hd.endElement("", "", "user"); + hd.endElement("", "", "role"); } - hd.endElement("", "", "Users"); + hd.endElement("", "", "Roles"); hd.endDocument(); From 838be7155d2aa07a97f03e10cfc997cf46517d3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lui=CC=81s=20A=2E=20Bastia=CC=83o=20Silva?= Date: Sat, 23 Jan 2016 20:26:25 +0000 Subject: [PATCH 08/31] Fixed issue loading xml --- .../pt/ua/dicoogle/server/users/RolesXML.java | 20 +++++++++++----- .../pt/ua/dicoogle/core/auth/TestRoles.java | 24 +++++++++++++++++++ 2 files changed, 38 insertions(+), 6 deletions(-) create mode 100644 dicoogle/src/test/java/pt/ua/dicoogle/core/auth/TestRoles.java diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/users/RolesXML.java b/dicoogle/src/main/java/pt/ua/dicoogle/server/users/RolesXML.java index e1ac0d986..f7125df89 100755 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/users/RolesXML.java +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/users/RolesXML.java @@ -27,6 +27,7 @@ import org.xml.sax.helpers.DefaultHandler; import org.xml.sax.helpers.XMLReaderFactory; +import javax.crypto.Cipher; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerConfigurationException; @@ -34,10 +35,7 @@ import javax.xml.transform.sax.SAXTransformerFactory; import javax.xml.transform.sax.TransformerHandler; import javax.xml.transform.stream.StreamResult; -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.PrintWriter; +import java.io.*; import java.util.Iterator; /** @@ -106,8 +104,18 @@ public RolesStruct getXML() try { - UserFileHandle file = new UserFileHandle(); - byte[] xml = file.getFileContent(); + + FileInputStream fin = new FileInputStream("roles.xml"); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + byte[] data = new byte[1024]; + int bytesRead; + + while ((bytesRead = fin.read(data)) != -1) { + out.write(data, 0, bytesRead); + out.flush(); + } + + byte[] xml = out.toByteArray(); if (xml == null) { diff --git a/dicoogle/src/test/java/pt/ua/dicoogle/core/auth/TestRoles.java b/dicoogle/src/test/java/pt/ua/dicoogle/core/auth/TestRoles.java new file mode 100644 index 000000000..49d41f860 --- /dev/null +++ b/dicoogle/src/test/java/pt/ua/dicoogle/core/auth/TestRoles.java @@ -0,0 +1,24 @@ +package pt.ua.dicoogle.core.auth; + +import org.junit.Test; +import pt.ua.dicoogle.server.users.*; +import pt.ua.dicoogle.server.web.auth.Authentication; +import pt.ua.dicoogle.server.web.auth.LoggedIn; + +/** + * Created by bastiao on 23/01/16. + */ +public class TestRoles { + + + @Test + public void testRoles() { + + UsersStruct users = UsersStruct.getInstance(); + UsersXML usersXML = new UsersXML(); + users = usersXML.getXML(); + RolesXML rolesXML = new RolesXML(); + RolesStruct rolesStruct = rolesXML.getXML(); + System.out.println(rolesStruct.getRoles()); + } +} From a569fa10755a9ec92f5799c192bbd0deee8a4075 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lui=CC=81s=20A=2E=20Bastia=CC=83o=20Silva?= Date: Sat, 23 Jan 2016 21:38:29 +0000 Subject: [PATCH 09/31] associate role to a user --- .../ua/dicoogle/server/users/RoleManager.java | 6 +++- .../ua/dicoogle/server/users/RolesStruct.java | 18 ++++++++--- .../pt/ua/dicoogle/server/users/RolesXML.java | 31 ++++++++++++++++-- .../pt/ua/dicoogle/server/users/UsersXML.java | 32 ++++++++++++++++++- .../server/web/auth/Authentication.java | 7 ++-- 5 files changed, 80 insertions(+), 14 deletions(-) diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/users/RoleManager.java b/dicoogle/src/main/java/pt/ua/dicoogle/server/users/RoleManager.java index 9dd30465c..e4e152782 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/users/RoleManager.java +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/users/RoleManager.java @@ -1,6 +1,8 @@ package pt.ua.dicoogle.server.users; +import java.util.Collection; import java.util.List; +import java.util.Set; /** * Created by bastiao on 23/01/16. @@ -8,6 +10,8 @@ public interface RoleManager { public boolean hasRole(User user, Role r); - public List getRoles(); + public Collection getRoles(); public void addRole(Role r); + public Role getRole(String name); + } diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/users/RolesStruct.java b/dicoogle/src/main/java/pt/ua/dicoogle/server/users/RolesStruct.java index 4d378921a..baa1f70e0 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/users/RolesStruct.java +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/users/RolesStruct.java @@ -1,7 +1,6 @@ package pt.ua.dicoogle.server.users; -import java.util.ArrayList; -import java.util.List; +import java.util.*; /** * Created by bastiao on 23/01/16. @@ -10,7 +9,8 @@ public class RolesStruct implements RoleManager{ private static RolesStruct instance = null ; - private List roles = new ArrayList<>(); + private Set roles = new HashSet<>(); + private Map rolesMap = new HashMap(); public static synchronized RolesStruct getInstance() { if (instance == null) { @@ -24,7 +24,7 @@ private RolesStruct(){ } public void reset(){ - roles = new ArrayList<>(); + roles = new HashSet<>(); } @Override @@ -33,12 +33,20 @@ public boolean hasRole(User user, Role r) { } @Override - public List getRoles() { + public Set getRoles() { return this.roles; } @Override public void addRole(Role r) { this.roles.add(r); + this.rolesMap.put(r.getName(), r); + + } + + @Override + public Role getRole(String name) { + + return this.rolesMap.get(name); } } diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/users/RolesXML.java b/dicoogle/src/main/java/pt/ua/dicoogle/server/users/RolesXML.java index f7125df89..efdb357bf 100755 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/users/RolesXML.java +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/users/RolesXML.java @@ -205,9 +205,9 @@ public void printXML() finally { try { out.close(); - - UserFileHandle file = new UserFileHandle(); - file.printFile(out.toByteArray()); + + printFile(out.toByteArray()); + } catch (Exception ex) { LoggerFactory.getLogger(RolesXML.class).error(ex.getMessage(), ex); } @@ -215,4 +215,29 @@ public void printXML() } + /** + * Print one byte array in File + * Encrypt that file with the key + * @param bytes + */ + public void printFile(byte[] bytes) throws Exception { + InputStream in; + + + in = new ByteArrayInputStream(bytes); + + FileOutputStream out = new FileOutputStream("roles.xml"); + + + byte[] input = new byte[1024]; + int bytesRead; + while ((bytesRead = in.read(input)) != -1) { + out.write(input, 0, bytesRead); + out.flush(); + } + + out.close(); + in.close(); + } + } diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/users/UsersXML.java b/dicoogle/src/main/java/pt/ua/dicoogle/server/users/UsersXML.java index 7e26afc71..7a1d5db0d 100755 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/users/UsersXML.java +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/users/UsersXML.java @@ -23,6 +23,8 @@ import java.io.IOException; import java.io.PrintWriter; import java.util.Iterator; + +import org.apache.commons.lang3.StringUtils; import org.slf4j.LoggerFactory; import javax.xml.transform.OutputKeys; @@ -54,12 +56,14 @@ public class UsersXML extends DefaultHandler private String username; private String Hash; private boolean admin; + private String roles; public UsersXML() { username = ""; Hash = ""; + roles = ""; admin = false; } @@ -85,6 +89,8 @@ else if (this.isUsers && localName.equals("user")) this.admin = true; else this.admin = false; + this.roles = this.resolveAttrib("roles", attribs, "xp"); + } } @@ -100,7 +106,19 @@ public void endElement( String uri, String localName, String qName ) } else if( localName.equals( "user" ) ) { - users.addUser(new User(username, Hash, admin)); + + User u = new User(username, Hash, admin); + users.addUser(u); + if (roles!=null) + { + String [] rolesTmp = roles.split(","); + for (int i = 0; i0) + { + String roles = ""; + for (Role r : user.getRoles()) + { + roles+=r.getName()+","; + } + StringUtils.removeEnd(roles, ","); + + + atts.addAttribute("", "", "roles", "", roles ) ; + } atts.addAttribute("", "", "admin", "", temp) ; diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/auth/Authentication.java b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/auth/Authentication.java index fad688962..02c3497a5 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/auth/Authentication.java +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/auth/Authentication.java @@ -18,10 +18,7 @@ */ package pt.ua.dicoogle.server.web.auth; -import pt.ua.dicoogle.server.users.User; -import pt.ua.dicoogle.server.users.UsersStruct; -import pt.ua.dicoogle.server.users.HashService; -import pt.ua.dicoogle.server.users.UsersXML; +import pt.ua.dicoogle.server.users.*; /** * Provides login routines for users. @@ -35,6 +32,8 @@ public class Authentication private Authentication() { + RolesXML rolesXML = new RolesXML(); + RolesStruct rolesStruct = rolesXML.getXML(); // init the user list, if it wasn't done yet UsersXML usersXML = new UsersXML(); usersXML.getXML(); From 91641347423eba2e07daac92e55cdf3681fe2125 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lui=CC=81s=20A=2E=20Bastia=CC=83o=20Silva?= Date: Sat, 23 Jan 2016 21:39:19 +0000 Subject: [PATCH 10/31] Associate a User and Role Test --- .../pt/ua/dicoogle/core/auth/TestRoles.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/dicoogle/src/test/java/pt/ua/dicoogle/core/auth/TestRoles.java b/dicoogle/src/test/java/pt/ua/dicoogle/core/auth/TestRoles.java index 49d41f860..f69dc0c41 100644 --- a/dicoogle/src/test/java/pt/ua/dicoogle/core/auth/TestRoles.java +++ b/dicoogle/src/test/java/pt/ua/dicoogle/core/auth/TestRoles.java @@ -21,4 +21,27 @@ public void testRoles() { RolesStruct rolesStruct = rolesXML.getXML(); System.out.println(rolesStruct.getRoles()); } + + @Test + public void testUserRoles() { + + RolesXML rolesXML = new RolesXML(); + RolesStruct rolesStruct = rolesXML.getXML(); + + UsersStruct users = UsersStruct.getInstance(); + UsersXML usersXML = new UsersXML(); + users = usersXML.getXML(); + System.out.println(rolesStruct.getRoles()); + for (User u : users.getUsers()) + { + System.out.println(u.getUsername()); + for (Role r : u.getRoles()) + { + System.out.println(r); + } + } + + + + } } From 3a97aebb6bd9fd0a4612cb4028cad2b3fd467eb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lui=CC=81s=20A=2E=20Bastia=CC=83o=20Silva?= Date: Sun, 24 Jan 2016 10:19:56 +0000 Subject: [PATCH 11/31] Only show some options in menu if the user is administrator. --- .../webapp/WEB-INF/js/components/sidebar.js | 19 ++++++++++++------- .../web/webapp/WEB-INF/js/stores/userStore.js | 3 +++ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/sidebar.js b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/sidebar.js index c5799d28f..f23fb1a54 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/sidebar.js +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/sidebar.js @@ -18,21 +18,26 @@ const Sidebar = React.createClass({ render() { console.log("APP RENDER"); let menuItems = [ - {value: "search", caption: "Search"}, - {value: "management", caption: "Management"}, - {value: "indexer", caption: "Indexer"}, - {value: "about", caption: "About"} + {value: "search", caption: "Search", admin: false}, + {value: "management", caption: "Management", admin: true}, + {value: "indexer", caption: "Indexer", admin: true}, + {value: "about", caption: "About", admin: false} ].concat(this.props.pluginMenuItems); + let isAdmin = UserStore.isAdmin(); + console.log("Is admin: " + isAdmin) + let sidebarInstance = (
    { + menuItems.map(function(e, i) { const to = (e.isPlugin ? '/ext/' : '/') + e.value; - return (
  • - {e.caption} -
  • ); + if ((e.admin && isAdmin)||e.admin==undefined) + return (
  • + {e.caption} +
  • ); }) }
diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/stores/userStore.js b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/stores/userStore.js index be64e3c35..b01ad4e93 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/stores/userStore.js +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/stores/userStore.js @@ -91,6 +91,9 @@ var UserStore = Reflux.createStore({ getUsername: function(){ return this._username; }, + isAdmin: function(){ + return this._isAdmin; + }, getLogginState: function(){ return this._isLoggedIn; } From 8e8bd57bf8dd258804d6a1a64e8d6f2602317f3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lui=CC=81s=20A=2E=20Bastia=CC=83o=20Silva?= Date: Sun, 24 Jan 2016 22:37:33 +0000 Subject: [PATCH 12/31] Protect some features to non administrative users --- .../js/components/search/result/imageView.js | 32 +++++++++++---- .../components/search/result/patientView.js | 41 ++++++++++++++----- .../js/components/search/result/serieView.js | 34 +++++++++++---- .../js/components/search/result/studyView.js | 37 ++++++++++++----- .../webapp/WEB-INF/js/components/sidebar.js | 4 +- 5 files changed, 109 insertions(+), 39 deletions(-) diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/imageView.js b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/imageView.js index dbc8fa8f5..05b4de603 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/imageView.js +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/imageView.js @@ -11,6 +11,8 @@ import {DumpActions} from '../../../actions/dumpActions'; import {BootstrapTable, TableHeaderColumn} from 'react-bootstrap-table'; import {Input} from 'react-bootstrap'; import ResultSelectActions from '../../../actions/resultSelectAction'; +import {UserStore} from '../../../stores/userStore'; + var ImageView = React.createClass({ @@ -77,16 +79,28 @@ var ImageView = React.createClass({ formatOptions: function(cell, item){ let self = this; + let isAdmin = UserStore.isAdmin(); + let unindex = null; + let removeFiles = null; if (this.props.enableAdvancedSearch) - return (
- - {/* plugin-based result options*/} - -
+ if (isAdmin) { + unindex = ( + ); + + removeFiles = (); + } + return (
+ {unindex} + {removeFiles} + + + {/* plugin-based result options*/} + +
); return (
); diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/patientView.js b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/patientView.js index 8f90947f4..c6ed2b1b3 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/patientView.js +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/patientView.js @@ -6,6 +6,8 @@ import ConfirmModal from './confirmModal'; import PluginView from '../../plugin/pluginView.jsx'; import {Input} from 'react-bootstrap'; import ResultSelectActions from '../../../actions/resultSelectAction'; +import {UserStore} from '../../../stores/userStore'; + /** * 2015-09-11. @@ -63,17 +65,34 @@ const PatientView = React.createClass({ }, formatOptions: function(cell, item){ - return (
-
- ); + + let isAdmin = UserStore.isAdmin(); + let unindex = null; + let removeFiles = null; + if (this.props.enableAdvancedSearch) + { + if (isAdmin) { + unindex = ( + - - {/* plugin-based result options */} - ); + removeFiles = ); + } + return (
+ + {unindex} + {removeFiles} + + {/* plugin-based result options */} + -
- ); +
+ ); + + } + return (
); }, diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/studyView.js b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/studyView.js index 259bedffd..2545a9cdc 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/studyView.js +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/studyView.js @@ -8,6 +8,9 @@ import PluginView from '../../plugin/pluginView.jsx'; import {Input} from 'react-bootstrap'; import ResultSelectActions from '../../../actions/resultSelectAction'; +import {UserStore} from '../../../stores/userStore'; + + var StudyView = React.createClass({ getInitialState: function() { // We need this because refs are not updated in BootstrapTable. @@ -53,16 +56,30 @@ var StudyView = React.createClass({ formatOptions: function(cell, item){ let self = this; - if (this.props.enableAdvancedSearch) - return (
- - - {/* plugin-based result options */} - -
); + let isAdmin = UserStore.isAdmin(); + let unindex = null; + let removeFiles = null; + if (this.props.enableAdvancedSearch) { + + if (isAdmin) { + unindex = ( + ); + + removeFiles = (); + + return (
+ {unindex} + {removeFiles} + {/* plugin-based result options */} + +
); + } + } return (
); }, diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/sidebar.js b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/sidebar.js index f23fb1a54..580d2ebe4 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/sidebar.js +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/sidebar.js @@ -18,7 +18,7 @@ const Sidebar = React.createClass({ render() { console.log("APP RENDER"); let menuItems = [ - {value: "search", caption: "Search", admin: false}, + {value: "search", caption: "Search", admin: true}, {value: "management", caption: "Management", admin: true}, {value: "indexer", caption: "Indexer", admin: true}, {value: "about", caption: "About", admin: false} @@ -34,7 +34,7 @@ const Sidebar = React.createClass({ menuItems.map(function(e, i) { const to = (e.isPlugin ? '/ext/' : '/') + e.value; - if ((e.admin && isAdmin)||e.admin==undefined) + if ((e.admin && isAdmin)||e.admin==false) return (
  • {e.caption}
  • ); From 921e9c6ba4a39eb1eddc2cdb139487d36ce4498c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lui=CC=81s=20A=2E=20Bastia=CC=83o=20Silva?= Date: Mon, 25 Jan 2016 11:05:10 +0000 Subject: [PATCH 13/31] Only show the remove and unindexed (image level) --- .../js/components/search/result/imageView.js | 25 ++++++++++++------- .../js/components/search/result/serieView.js | 2 +- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/imageView.js b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/imageView.js index 05b4de603..26d05e2d9 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/imageView.js +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/imageView.js @@ -82,27 +82,34 @@ var ImageView = React.createClass({ let isAdmin = UserStore.isAdmin(); let unindex = null; let removeFiles = null; - if (this.props.enableAdvancedSearch) + if (this.props.enableAdvancedSearch) { if (isAdmin) { unindex = ( - ); - - removeFiles = (); + ); + + removeFiles = (); } return (
    {unindex} {removeFiles} - {/* plugin-based result options*/} - -
    + }}/> +
    - ); + ); + } return (
    ); }, diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/serieView.js b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/serieView.js index 1e0b4ea2f..6cdd04990 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/serieView.js +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/serieView.js @@ -71,7 +71,7 @@ var SeriesView = React.createClass({ if (isAdmin) { unindex = ( ); - removeFiles = ); + removeFiles = (); } return (
    From 3522c4dfcffc058a1ddba5f04c9a4ae0560ca240 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lui=CC=81s=20A=2E=20Bastia=CC=83o=20Silva?= Date: Mon, 25 Jan 2016 15:02:45 +0000 Subject: [PATCH 14/31] - Send the roles in login. - Added missing licenses. --- .../pt/ua/dicoogle/server/users/Role.java | 18 +++++++++++++++ .../ua/dicoogle/server/users/RoleManager.java | 18 +++++++++++++++ .../ua/dicoogle/server/users/RolesStruct.java | 18 +++++++++++++++ .../server/users/UserRoleManager.java | 18 +++++++++++++++ .../web/servlets/accounts/LoginServlet.java | 20 ++++++++++++++++- .../pt/ua/dicoogle/core/auth/TestRoles.java | 22 +++++++++++++++++-- 6 files changed, 111 insertions(+), 3 deletions(-) diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/users/Role.java b/dicoogle/src/main/java/pt/ua/dicoogle/server/users/Role.java index 54adf9f62..cf5fe3039 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/users/Role.java +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/users/Role.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2014 Universidade de Aveiro, DETI/IEETA, Bioinformatics Group - http://bioinformatics.ua.pt/ + * + * This file is part of Dicoogle/dicoogle. + * + * Dicoogle/dicoogle 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 3 of the License, or + * (at your option) any later version. + * + * Dicoogle/dicoogle 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. + * + * You should have received a copy of the GNU General Public License + * along with Dicoogle. If not, see . + */ package pt.ua.dicoogle.server.users; /** diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/users/RoleManager.java b/dicoogle/src/main/java/pt/ua/dicoogle/server/users/RoleManager.java index e4e152782..db28eef2a 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/users/RoleManager.java +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/users/RoleManager.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2014 Universidade de Aveiro, DETI/IEETA, Bioinformatics Group - http://bioinformatics.ua.pt/ + * + * This file is part of Dicoogle/dicoogle. + * + * Dicoogle/dicoogle 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 3 of the License, or + * (at your option) any later version. + * + * Dicoogle/dicoogle 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. + * + * You should have received a copy of the GNU General Public License + * along with Dicoogle. If not, see . + */ package pt.ua.dicoogle.server.users; import java.util.Collection; diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/users/RolesStruct.java b/dicoogle/src/main/java/pt/ua/dicoogle/server/users/RolesStruct.java index baa1f70e0..67d87210b 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/users/RolesStruct.java +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/users/RolesStruct.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2014 Universidade de Aveiro, DETI/IEETA, Bioinformatics Group - http://bioinformatics.ua.pt/ + * + * This file is part of Dicoogle/dicoogle. + * + * Dicoogle/dicoogle 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 3 of the License, or + * (at your option) any later version. + * + * Dicoogle/dicoogle 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. + * + * You should have received a copy of the GNU General Public License + * along with Dicoogle. If not, see . + */ package pt.ua.dicoogle.server.users; import java.util.*; diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/users/UserRoleManager.java b/dicoogle/src/main/java/pt/ua/dicoogle/server/users/UserRoleManager.java index 8517742a2..0f2956f1b 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/users/UserRoleManager.java +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/users/UserRoleManager.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2014 Universidade de Aveiro, DETI/IEETA, Bioinformatics Group - http://bioinformatics.ua.pt/ + * + * This file is part of Dicoogle/dicoogle. + * + * Dicoogle/dicoogle 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 3 of the License, or + * (at your option) any later version. + * + * Dicoogle/dicoogle 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. + * + * You should have received a copy of the GNU General Public License + * along with Dicoogle. If not, see . + */ package pt.ua.dicoogle.server.users; /** diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/servlets/accounts/LoginServlet.java b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/servlets/accounts/LoginServlet.java index 3f2c472f7..a5364f02f 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/servlets/accounts/LoginServlet.java +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/servlets/accounts/LoginServlet.java @@ -27,7 +27,11 @@ import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; +import net.sf.json.JSONArray; import net.sf.json.JSONObject; +import pt.ua.dicoogle.server.users.Role; +import pt.ua.dicoogle.server.users.User; +import pt.ua.dicoogle.server.users.UsersStruct; import pt.ua.dicoogle.server.web.auth.LoggedIn; import pt.ua.dicoogle.server.web.auth.Session; @@ -53,7 +57,14 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws S JSONObject json_resp = new JSONObject(); json_resp.put("user", mLoggedIn.getUserName()); json_resp.put("admin", mLoggedIn.isAdmin()); + User u = UsersStruct.getInstance().getUser(mLoggedIn.getUserName()); + JSONArray rolesObj = new JSONArray(); + for (Role r : u.getRoles()) + { + rolesObj.add(r.getName()); + } + json_resp.put("roles", rolesObj); //Set response content type resp.setContentType("application/json"); @@ -77,7 +88,14 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) JSONObject json_resp = new JSONObject(); json_resp.put("user", mLoggedIn.getUserName()); json_resp.put("admin", mLoggedIn.isAdmin()); - + User u = UsersStruct.getInstance().getUser(mLoggedIn.getUserName()); + JSONArray rolesObj = new JSONArray(); + for (Role r : u.getRoles()) + { + rolesObj.add(r.getName()); + } + + json_resp.put("roles", rolesObj); //Set response content type resp.setContentType("application/json"); diff --git a/dicoogle/src/test/java/pt/ua/dicoogle/core/auth/TestRoles.java b/dicoogle/src/test/java/pt/ua/dicoogle/core/auth/TestRoles.java index f69dc0c41..343a8016b 100644 --- a/dicoogle/src/test/java/pt/ua/dicoogle/core/auth/TestRoles.java +++ b/dicoogle/src/test/java/pt/ua/dicoogle/core/auth/TestRoles.java @@ -1,3 +1,21 @@ +/** + * Copyright (C) 2014 Universidade de Aveiro, DETI/IEETA, Bioinformatics Group - http://bioinformatics.ua.pt/ + * + * This file is part of Dicoogle/dicoogle. + * + * Dicoogle/dicoogle 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 3 of the License, or + * (at your option) any later version. + * + * Dicoogle/dicoogle 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. + * + * You should have received a copy of the GNU General Public License + * along with Dicoogle. If not, see . + */ package pt.ua.dicoogle.core.auth; import org.junit.Test; @@ -11,7 +29,7 @@ public class TestRoles { - @Test + //@Test public void testRoles() { UsersStruct users = UsersStruct.getInstance(); @@ -22,7 +40,7 @@ public void testRoles() { System.out.println(rolesStruct.getRoles()); } - @Test + //@Test public void testUserRoles() { RolesXML rolesXML = new RolesXML(); From 874319fac5b5ef02319e01588720bb7d63ead748 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lui=CC=81s=20A=2E=20Bastia=CC=83o=20Silva?= Date: Mon, 25 Jan 2016 22:36:33 +0000 Subject: [PATCH 15/31] First approach of session and to keep the state of login --- .../server/web/auth/Authentication.java | 17 ++- .../ua/dicoogle/server/web/auth/LoggedIn.java | 9 ++ .../web/servlets/accounts/LoginServlet.java | 2 + .../webapp/WEB-INF/js/actions/userActions.js | 1 + .../web/webapp/WEB-INF/js/stores/userStore.js | 100 ++++++++++++++---- 5 files changed, 108 insertions(+), 21 deletions(-) diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/auth/Authentication.java b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/auth/Authentication.java index 02c3497a5..37f361a90 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/auth/Authentication.java +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/auth/Authentication.java @@ -20,6 +20,10 @@ import pt.ua.dicoogle.server.users.*; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + /** * Provides login routines for users. * @@ -30,6 +34,9 @@ public class Authentication private static Authentication instance = null; private static UsersStruct users; + private static Map usersToken = new HashMap(); + + private Authentication() { RolesXML rolesXML = new RolesXML(); @@ -77,8 +84,14 @@ public LoggedIn login(String username, String password) String passwordHash = HashService.getSHA1Hash(password); if (! user.verifyPassword(passwordHash)) return null; - + LoggedIn in = new LoggedIn(username, user.isAdmin()); + if (usersToken.containsKey(username)) + in.setToken(usersToken.get(username)); + else { + usersToken.put(username, UUID.randomUUID().toString()); + in.setToken(usersToken.get(username)); + } // return a successfull login object - return new LoggedIn(username, user.isAdmin()); + return in; } } diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/auth/LoggedIn.java b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/auth/LoggedIn.java index 5c3167a64..b76e4f5e1 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/auth/LoggedIn.java +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/auth/LoggedIn.java @@ -27,6 +27,7 @@ public class LoggedIn { private String userName; private boolean admin; + private String token; public LoggedIn(String userName, boolean isAdmin) { @@ -49,4 +50,12 @@ public boolean isAdmin() { return admin; } + + public String getToken() { + return token; + } + + public void setToken(String token) { + this.token = token; + } } diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/servlets/accounts/LoginServlet.java b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/servlets/accounts/LoginServlet.java index a5364f02f..5a1c065a5 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/servlets/accounts/LoginServlet.java +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/servlets/accounts/LoginServlet.java @@ -20,6 +20,7 @@ package pt.ua.dicoogle.server.web.servlets.accounts; import java.io.IOException; +import java.util.UUID; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; @@ -65,6 +66,7 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws S } json_resp.put("roles", rolesObj); + json_resp.put("token", mLoggedIn.getToken()); //Set response content type resp.setContentType("application/json"); diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/actions/userActions.js b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/actions/userActions.js index d34566462..7f3774cb1 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/actions/userActions.js +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/actions/userActions.js @@ -1,6 +1,7 @@ var Reflux = require('reflux'); var UserActions = exports; UserActions.login = Reflux.createAction(); +UserActions.logout = Reflux.createAction(); UserActions.isLoggedIn = Reflux.createAction(); export { UserActions }; diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/stores/userStore.js b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/stores/userStore.js index e064eb34e..0315e6349 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/stores/userStore.js +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/stores/userStore.js @@ -14,8 +14,35 @@ var UserStore = Reflux.createStore({ this._isLoggedIn = false; this._username = ""; this._isAdmin = false; + this._roles = []; + this._token = ''; + this.loadLocalStore() }, + saveLocalStore: function(){ + localStorage.setItem("user", JSON.stringify({ + isAdmin: this.isAdmin, + 'username': this._username, + 'roles': this._roles, + 'token': this._token + })); + + + }, + loadLocalStore: function(){ + console.log("loadLocalStoreloadLocalStore"); + if (localStorage.token!=null) + { + let user = JSON.parse(localStorage.getItem("user")); + console.log(user); + this._isAdmin = user._isAdmin ; + this._username = user.username; + this._roles = user.roles; + this._token = user.token ; + this._isLoggedIn = true; + } + + }, onLogin: function(user, pass){ console.log("onLogin"); var self = this; @@ -31,8 +58,13 @@ var UserStore = Reflux.createStore({ console.log(data); self._username = data.user; self._isAdmin = data.admin; + self._token = data.token; + self._roles = data.roles; self._isLoggedIn = true; + localStorage.token = self._token; + self.saveLocalStore(); + console.log("Localstorage token: " + localStorage.token); self.trigger({ isLoggedIn: self._isLoggedIn, success: true @@ -50,36 +82,62 @@ var UserStore = Reflux.createStore({ }, onIsLoggedIn: function(){ + console.log("Verify onIsLoggedIn"); + console.log(this._isLoggedIn); if(this._isLoggedIn === false) { - $.ajax({ - type: "GET", - url: Endpoints.base + "/login", - dataType: 'json', - async: true, - success: (result) => { - /* if result is a JSon object */ - this._username = result.user; - this._isAdmin = result.admin; - this._isLoggedIn = true; + console.log("Verify onIsLoggedIn1"); + console.log(this._isLoggedIn); + console.log(localStorage.token); + if (localStorage.token !=null) { + console.log("Verify loadLocalStore"); + this.loadLocalStore(); + this.trigger({ + isLoggedIn: self._isLoggedIn, + success: true + }); + }else{ + console.log("Verify ajax"); + $.ajax({ + type: "GET", + url: Endpoints.base + "/login", + dataType: 'json', + async: true, + success: (result) => { + /* if result is a JSon object */ + this._username = result.user; + this._isAdmin = result.admin; + this._isLoggedIn = true; + this.saveLocalStore(); setTimeout(() => { - this.trigger({ + this.trigger({ isLoggedIn: this._isLoggedIn, success: true - }); - }, 500) + }); + }, 500) }, - error: () => { - this.trigger({ - isLoggedIn: this._isLoggedIn, - success: true - }); - } + error: () => { + this.trigger({ + isLoggedIn: this._isLoggedIn, + success: false + }); + } }); + } + + + } else { //return this._isLoggedIn; + if (localStorage.token !==undefined) { + this.loadLocalStore(); + this.trigger({ + isLoggedIn: self._isLoggedIn, + success: true + }); + } this.trigger({ isLoggedIn: self._isLoggedIn, success: true @@ -87,6 +145,10 @@ var UserStore = Reflux.createStore({ } }, + onLogout: function() { + delete localStorage.token; + }, + getUsername: function(){ return this._username; }, From 4eb6ed0fb30bca0a092e2f28c746aed780f38a14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lui=CC=81s=20A=2E=20Bastia=CC=83o=20Silva?= Date: Tue, 26 Jan 2016 01:12:08 +0000 Subject: [PATCH 16/31] - Allow Authorisation token - Filter Plugins by authorisation token --- .../dicoogle/plugins/webui/WebUIPlugin.java | 22 ++++++++++++++- .../pt/ua/dicoogle/server/web/CORSFilter.java | 10 ++++++- .../ua/dicoogle/server/web/DicoogleWeb.java | 2 +- .../server/web/auth/Authentication.java | 16 ++++++++++- .../web/servlets/webui/WebUIServlet.java | 27 ++++++++++++++++--- 5 files changed, 70 insertions(+), 7 deletions(-) diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/plugins/webui/WebUIPlugin.java b/dicoogle/src/main/java/pt/ua/dicoogle/plugins/webui/WebUIPlugin.java index a0582cfbb..1be0279be 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/plugins/webui/WebUIPlugin.java +++ b/dicoogle/src/main/java/pt/ua/dicoogle/plugins/webui/WebUIPlugin.java @@ -18,9 +18,15 @@ */ package pt.ua.dicoogle.plugins.webui; +import net.sf.json.JSONArray; import net.sf.json.JSONException; import net.sf.json.JSONObject; import org.slf4j.LoggerFactory; +import pt.ua.dicoogle.server.users.Role; +import pt.ua.dicoogle.server.users.RolesStruct; + +import java.util.HashSet; +import java.util.Set; /** A POJO data type containing the full description of a Web UI plugin. * @@ -35,6 +41,7 @@ public class WebUIPlugin implements Cloneable { private String moduleFile; private JSONObject settings; private boolean enabled = true; + private Set roles = new HashSet(); public WebUIPlugin() {} @@ -75,6 +82,16 @@ public static WebUIPlugin fromPackageJSON(JSONObject obj) throws PluginFormatExc plugin.slotId = objDicoogle.getString("slot-id"); plugin.moduleFile = objDicoogle.optString("module-file", "module.js"); plugin.caption = objDicoogle.optString("caption", null); + JSONArray rolesArr = objDicoogle.getJSONArray("roles"); + System.out.println(rolesArr); + Set roles = new HashSet<>(); + if (rolesArr!=null) + for (Object role :rolesArr) + { + System.out.println(role); + roles.add((String)role); + } + plugin.roles = roles; return plugin; } catch(JSONException ex) { @@ -156,5 +173,8 @@ public String getCaption() { public void setCaption(String caption) { this.caption = caption; } - + + public Set getRoles() { + return roles; + } } diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/CORSFilter.java b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/CORSFilter.java index e00cc25ad..9b87103fd 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/CORSFilter.java +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/CORSFilter.java @@ -39,26 +39,32 @@ public class CORSFilter implements Filter { public static String ACCESS_CONTROL_ALLOW_ORIGIN_HEADER = "Access-Control-Allow-Origin"; public static String ACCESS_CONTROL_ALLOW_HEADERS_HEADER = "Access-Control-Allow-Headers"; public static String ACCESS_CONTROL_ALLOW_METHODS_HEADER = "Access-Control-Allow-Methods"; + public static String ACCESS_CONTROL_ALLOW_AUTHORIZATION_HEADER = "Authorization"; public static String ALLOWED_ORIGINS_PARAM = "allowedOrigins"; public static String ALLOWED_HEADERS_PARAM = "allowedHeaders"; public static String ALLOWED_METHODS_PARAM = "allowedMethods"; + public static String ALLOWED_AUTHORIZATION_PARAM = "allowedAuthorization"; private String allowedOrigins; private String allowedHeaders; private String allowedMethods; + private String allowedAuthorization; @Override public void init(FilterConfig fc) throws ServletException { allowedOrigins = fc.getInitParameter(ALLOWED_ORIGINS_PARAM); allowedHeaders = fc.getInitParameter(ALLOWED_HEADERS_PARAM); allowedMethods = fc.getInitParameter(ALLOWED_METHODS_PARAM); + allowedMethods = fc.getInitParameter(ALLOWED_METHODS_PARAM); + allowedAuthorization = fc.getInitParameter(ALLOWED_AUTHORIZATION_PARAM); if (allowedMethods == null) { allowedMethods = "GET,POST,HEAD"; } if (allowedHeaders == null) { - allowedHeaders = "X-Requested-With,Content-Type,Accept,Origin"; + allowedHeaders = "X-Requested-With,Content-Type,Accept,Origin,Authorization"; } + } @Override @@ -71,6 +77,8 @@ public void doFilter(ServletRequest sreq, ServletResponse sresp, FilterChain fc) if (allowedHeaders!= null) { resp.addHeader(ACCESS_CONTROL_ALLOW_HEADERS_HEADER, allowedHeaders); } + if (allowedAuthorization!=null) + resp.addHeader(ACCESS_CONTROL_ALLOW_AUTHORIZATION_HEADER, allowedAuthorization); resp.addHeader(ACCESS_CONTROL_ALLOW_METHODS_HEADER, allowedMethods); } fc.doFilter(sreq, sresp); diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/DicoogleWeb.java b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/DicoogleWeb.java index 5033c94d9..43b003b91 100755 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/DicoogleWeb.java +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/DicoogleWeb.java @@ -235,7 +235,7 @@ private void addCORSFilter(ServletContextHandler handler) { FilterHolder corsHolder = new FilterHolder(CORSFilter.class); corsHolder.setInitParameter(CORSFilter.ALLOWED_ORIGINS_PARAM, origins); corsHolder.setInitParameter(CORSFilter.ALLOWED_METHODS_PARAM, "GET,POST,HEAD,PUT,DELETE"); - corsHolder.setInitParameter(CORSFilter.ALLOWED_HEADERS_PARAM, "X-Requested-With,Content-Type,Accept,Origin"); + corsHolder.setInitParameter(CORSFilter.ALLOWED_HEADERS_PARAM, "X-Requested-With,Content-Type,Accept,Origin,Authorization"); handler.addFilter(corsHolder, "/*", EnumSet.of(DispatcherType.REQUEST)); } } diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/auth/Authentication.java b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/auth/Authentication.java index 37f361a90..19ee06804 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/auth/Authentication.java +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/auth/Authentication.java @@ -35,6 +35,7 @@ public class Authentication private static UsersStruct users; private static Map usersToken = new HashMap(); + private static Map tokenUsers = new HashMap(); // to have performance. private Authentication() @@ -62,6 +63,16 @@ public static synchronized Authentication getInstance() return instance; } + + public User getUsername(String token) + { + String user = tokenUsers.get(token); + if (user==null) + return null; + return UsersStruct.getInstance().getUser(user); + + } + /** * Attemps to login on the plataform. * @@ -87,8 +98,11 @@ public LoggedIn login(String username, String password) LoggedIn in = new LoggedIn(username, user.isAdmin()); if (usersToken.containsKey(username)) in.setToken(usersToken.get(username)); + else { - usersToken.put(username, UUID.randomUUID().toString()); + String token =UUID.randomUUID().toString(); + usersToken.put(username, token); + tokenUsers.put(token, username); in.setToken(usersToken.get(username)); } // return a successfull login object diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/servlets/webui/WebUIServlet.java b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/servlets/webui/WebUIServlet.java index acbb521ff..39995de61 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/servlets/webui/WebUIServlet.java +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/servlets/webui/WebUIServlet.java @@ -32,6 +32,10 @@ import org.slf4j.LoggerFactory; import pt.ua.dicoogle.plugins.PluginController; import pt.ua.dicoogle.plugins.webui.WebUIPlugin; +import pt.ua.dicoogle.server.users.Role; +import pt.ua.dicoogle.server.users.RolesStruct; +import pt.ua.dicoogle.server.users.User; +import pt.ua.dicoogle.server.web.auth.Authentication; /** * Retrieval of web UI plugins and respective packages/modules. @@ -50,6 +54,7 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws Se String module = req.getParameter("module"); String process = req.getParameter("process"); + if (name != null) { resp.setContentType("application/json"); resp.getWriter().append(this.getPlugin(resp, name)); @@ -59,17 +64,33 @@ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws Se resp.getWriter().append(this.getModule(resp, module, doProcess)); } else { resp.setContentType("application/json"); - resp.getWriter().append(this.getPluginsBySlot(resp, slotIdArr)); + resp.getWriter().append(this.getPluginsBySlot(req, resp, slotIdArr)); } } /** Retrieve plugins. */ - private String getPluginsBySlot(HttpServletResponse resp, String... slotIds) throws IOException { + private String getPluginsBySlot(HttpServletRequest req, + HttpServletResponse resp, String... slotIds) throws IOException { + String token = req.getHeader("Authorization"); + User user = Authentication.getInstance().getUsername(token); + Collection plugins = PluginController.getInstance().getWebUIPlugins(slotIds); List pkgList = new ArrayList<>(plugins.size()); for (WebUIPlugin plugin : plugins) { + + String pkg = PluginController.getInstance().getWebUIPackageJSON(plugin.getName()); - if (pkg != null) { + boolean hasUserAllowPlugin= false; + for (String r:plugin.getRoles()) + { + Role rr = RolesStruct.getInstance().getRole(r); + hasUserAllowPlugin = RolesStruct.getInstance().hasRole(user, rr); + if (hasUserAllowPlugin) + break; + } + + + if (pkg != null&&hasUserAllowPlugin) { pkgList.add(pkg); } } From 223b94e3ab7c29609e9483a99abb530543ee41ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lui=CC=81s=20A=2E=20Bastia=CC=83o=20Silva?= Date: Tue, 26 Jan 2016 17:10:09 +0000 Subject: [PATCH 17/31] Fixed invalid login --- .../ua/dicoogle/server/users/RolesStruct.java | 2 + .../ua/dicoogle/server/web/DicoogleWeb.java | 2 +- .../server/web/webapp/WEB-INF/js/app.js | 5 ++- .../web/webapp/WEB-INF/js/stores/userStore.js | 45 +++++++++++++++---- 4 files changed, 44 insertions(+), 10 deletions(-) diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/users/RolesStruct.java b/dicoogle/src/main/java/pt/ua/dicoogle/server/users/RolesStruct.java index 67d87210b..3b4a3dc7e 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/users/RolesStruct.java +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/users/RolesStruct.java @@ -47,6 +47,8 @@ public void reset(){ @Override public boolean hasRole(User user, Role r) { + if (user==null||r==null) + return false; return UsersStruct.getInstance().getUser(user.getUsername()).hasRole(r); } diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/DicoogleWeb.java b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/DicoogleWeb.java index 43b003b91..2753d87d4 100755 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/DicoogleWeb.java +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/DicoogleWeb.java @@ -235,7 +235,7 @@ private void addCORSFilter(ServletContextHandler handler) { FilterHolder corsHolder = new FilterHolder(CORSFilter.class); corsHolder.setInitParameter(CORSFilter.ALLOWED_ORIGINS_PARAM, origins); corsHolder.setInitParameter(CORSFilter.ALLOWED_METHODS_PARAM, "GET,POST,HEAD,PUT,DELETE"); - corsHolder.setInitParameter(CORSFilter.ALLOWED_HEADERS_PARAM, "X-Requested-With,Content-Type,Accept,Origin,Authorization"); + corsHolder.setInitParameter(CORSFilter.ALLOWED_HEADERS_PARAM, "X-Requested-With,Content-Type,Accept,Origin,Authorization,Content-Length"); handler.addFilter(corsHolder, "/*", EnumSet.of(DispatcherType.REQUEST)); } } diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/app.js b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/app.js index 4c0230049..028aaed84 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/app.js +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/app.js @@ -19,7 +19,8 @@ import PluginView from './components/plugin/pluginView.jsx'; import AboutView from './components/about/aboutView'; import LoadingView from './components/login/loadingView'; import LoginView from './components/login/loginView'; -import { hashHistory } from 'react-router' +import { hashHistory, browserHistory } from 'react-router' +import {UserActions} from './actions/userActions'; import 'document-register-element'; require('core-js/shim'); @@ -73,8 +74,10 @@ class App extends React.Component { $.get(Endpoints.base + "/logout", (data, status) => { //Response console.log("Data: " + data + "\nStatus: " + status); + //self.transitionTo('login'); // Works with recent version of react + react-router + UserActions.logout() this.props.history.pushState(null, 'login'); }); } diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/stores/userStore.js b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/stores/userStore.js index 0315e6349..8c4151d38 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/stores/userStore.js +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/stores/userStore.js @@ -6,6 +6,10 @@ import $ from 'jquery'; import {UserActions} from '../actions/userActions'; import {Endpoints} from '../constants/endpoints'; + +import DicoogleClient from 'dicoogle-client'; + + var UserStore = Reflux.createStore({ listenables: UserActions, init: function () { @@ -48,7 +52,34 @@ var UserStore = Reflux.createStore({ var self = this; var formData = {username: user, password: pass}; //Array - $.ajax({ + let dicoogleClient = DicoogleClient(Endpoints.base); + + dicoogleClient.login(user, pass, function(data){ + if (data.token===undefined || data.token==null) + { + self.trigger({ + failed: true + }); + return ; + } + self._username = data.user; + self._isAdmin = data.admin; + self._token = data.token; + self._roles = data.roles; + self._isLoggedIn = true; + localStorage.token = self._token; + self.saveLocalStore(); + + console.log("Localstorage token: " + localStorage.token); + self.trigger({ + isLoggedIn: self._isLoggedIn, + success: true + }); + + }); + + + /*$.ajax({ url: Endpoints.base + "/login", type: "POST", dataType: 'json', @@ -78,19 +109,15 @@ var UserStore = Reflux.createStore({ failed: true }); } - }); + });*/ }, onIsLoggedIn: function(){ - console.log("Verify onIsLoggedIn"); - console.log(this._isLoggedIn); + if(this._isLoggedIn === false) { - console.log("Verify onIsLoggedIn1"); - console.log(this._isLoggedIn); - console.log(localStorage.token); + if (localStorage.token !=null) { - console.log("Verify loadLocalStore"); this.loadLocalStore(); this.trigger({ isLoggedIn: self._isLoggedIn, @@ -98,6 +125,8 @@ var UserStore = Reflux.createStore({ }); }else{ console.log("Verify ajax"); + + $.ajax({ type: "GET", url: Endpoints.base + "/login", From 94b7a6e451017bd143065a33192497f9c0e66d87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lui=CC=81s=20A=2E=20Bastia=CC=83o=20Silva?= Date: Tue, 26 Jan 2016 18:03:44 +0000 Subject: [PATCH 18/31] Only load plugins when login is ready --- .../pt/ua/dicoogle/server/web/CORSFilter.java | 2 +- .../server/web/webapp/WEB-INF/js/app.js | 67 +++++++++++++------ 2 files changed, 47 insertions(+), 22 deletions(-) diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/CORSFilter.java b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/CORSFilter.java index 9b87103fd..75a03c232 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/CORSFilter.java +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/CORSFilter.java @@ -62,7 +62,7 @@ public void init(FilterConfig fc) throws ServletException { allowedMethods = "GET,POST,HEAD"; } if (allowedHeaders == null) { - allowedHeaders = "X-Requested-With,Content-Type,Accept,Origin,Authorization"; + allowedHeaders = "X-Requested-With,Content-Type,Accept,Origin,Authorization,Content-Length"; } } diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/app.js b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/app.js index 028aaed84..7c7760287 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/app.js +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/app.js @@ -21,6 +21,8 @@ import LoadingView from './components/login/loadingView'; import LoginView from './components/login/loginView'; import { hashHistory, browserHistory } from 'react-router' import {UserActions} from './actions/userActions'; +import {UserStore} from './stores/userStore'; + import 'document-register-element'; require('core-js/shim'); @@ -34,50 +36,73 @@ class App extends React.Component { constructor(props) { super(props); + this.pluginsFetched = false; this.state = { pluginMenuItems: [] }; this.logout = this.logout.bind(this); } - componentWillMount() { - DicoogleClient(Endpoints.base); + /** + * @param {packageJSON|packageJSON[]} plugins + */ + onMenuPlugin(packages) { + const {pluginMenuItems} = this.state; + + this.setState({ + pluginMenuItems: pluginMenuItems.concat(packages.map(pkg => ({ + value: pkg.name, + caption: pkg.dicoogle.caption || pkg.name, + isPlugin: true + }))) + }); + } + + + componentWillMount() + { + UserStore.listen(this.fetchPlugins.bind(this)); + let dicoogleClient = DicoogleClient(Endpoints.base); + if (localStorage.token!=null) + { + dicoogleClient.setToken(localStorage.token); + } Webcore.init(Endpoints.base); + } + fetchPlugins(data) { + if (this.pluginsFetched) + return; + let self = this; + if (!data.success) + return ; + this.setState(data); + Webcore.addPluginLoadListener(function(plugin) { console.log("Plugin loaded to Dicoogle:", plugin); }); Webcore.fetchPlugins('menu', (packages) => { - this.onMenuPlugin(packages); - Webcore.fetchModules(packages); + self.onMenuPlugin(packages); + Webcore.fetchModules(packages); }); + // pre-fetch modules of other plugin types - Webcore.fetchPlugins(['search', 'result-options', 'query', 'result'], Webcore.fetchModules); + Webcore.fetchPlugins(['search', 'result-options', 'query', 'result'], Webcore.fetchModules) + this.pluginsFetched = true; } - /** - * @param {packageJSON|packageJSON[]} plugins - */ - onMenuPlugin(packages) { - const {pluginMenuItems} = this.state; - - this.setState({ - pluginMenuItems: pluginMenuItems.concat(packages.map(pkg => ({ - value: pkg.name, - caption: pkg.dicoogle.caption || pkg.name, - isPlugin: true - }))) - }); - } - logout() { + let self = this; $.get(Endpoints.base + "/logout", (data, status) => { //Response console.log("Data: " + data + "\nStatus: " + status); //self.transitionTo('login'); // Works with recent version of react + react-router + self.setState({pluginMenuItems: []}); + self.pluginsFetched = false; UserActions.logout() + this.props.history.pushState(null, 'login'); }); } @@ -91,7 +116,7 @@ class App extends React.Component {
    {this.props.children} From caa3368911d7e947fa2e88ec235eae3e2571c027 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lui=CC=81s=20A=2E=20Bastia=CC=83o=20Silva?= Date: Tue, 26 Jan 2016 18:37:41 +0000 Subject: [PATCH 19/31] Trigger failed login --- .../web/webapp/WEB-INF/js/components/sidebar.js | 5 ++--- .../web/webapp/WEB-INF/js/stores/userStore.js | 14 +++++++++++--- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/sidebar.js b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/sidebar.js index 580d2ebe4..2e9753425 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/sidebar.js +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/sidebar.js @@ -18,7 +18,7 @@ const Sidebar = React.createClass({ render() { console.log("APP RENDER"); let menuItems = [ - {value: "search", caption: "Search", admin: true}, + {value: "search", caption: "Search", admin: false}, {value: "management", caption: "Management", admin: true}, {value: "indexer", caption: "Indexer", admin: true}, {value: "about", caption: "About", admin: false} @@ -26,7 +26,6 @@ const Sidebar = React.createClass({ let isAdmin = UserStore.isAdmin(); console.log("Is admin: " + isAdmin) - let sidebarInstance = (
      @@ -34,7 +33,7 @@ const Sidebar = React.createClass({ menuItems.map(function(e, i) { const to = (e.isPlugin ? '/ext/' : '/') + e.value; - if ((e.admin && isAdmin)||e.admin==false) + if (!e.admin || isAdmin) return (
    • {e.caption}
    • ); diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/stores/userStore.js b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/stores/userStore.js index 8c4151d38..3d635ab01 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/stores/userStore.js +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/stores/userStore.js @@ -34,16 +34,18 @@ var UserStore = Reflux.createStore({ }, loadLocalStore: function(){ - console.log("loadLocalStoreloadLocalStore"); if (localStorage.token!=null) { let user = JSON.parse(localStorage.getItem("user")); - console.log(user); this._isAdmin = user._isAdmin ; this._username = user.username; this._roles = user.roles; this._token = user.token ; this._isLoggedIn = true; + this.trigger({ + isLoggedIn: this._isLoggedIn, + success: true + }); } }, @@ -53,8 +55,14 @@ var UserStore = Reflux.createStore({ var formData = {username: user, password: pass}; //Array let dicoogleClient = DicoogleClient(Endpoints.base); + let errorCallBack = function() + { + self.trigger({ + failed: true + }); - dicoogleClient.login(user, pass, function(data){ + }; + dicoogleClient.login(user, pass, function(errorCallBack, data){ if (data.token===undefined || data.token==null) { self.trigger({ From b25d5fd3471f968b146527972290a4facec62861 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lui=CC=81s=20A=2E=20Bastia=CC=83o=20Silva?= Date: Tue, 26 Jan 2016 18:51:10 +0000 Subject: [PATCH 20/31] Allow users to have empty roles --- .../server/web/servlets/accounts/LoginServlet.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/servlets/accounts/LoginServlet.java b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/servlets/accounts/LoginServlet.java index 5a1c065a5..bb125728e 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/servlets/accounts/LoginServlet.java +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/servlets/accounts/LoginServlet.java @@ -60,12 +60,14 @@ protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws S json_resp.put("admin", mLoggedIn.isAdmin()); User u = UsersStruct.getInstance().getUser(mLoggedIn.getUserName()); JSONArray rolesObj = new JSONArray(); - for (Role r : u.getRoles()) - { - rolesObj.add(r.getName()); - } + if (u!=null&&u.getRoles()!=null) { + for (Role r : u.getRoles()) { + if (r!=null) + rolesObj.add(r.getName()); + } - json_resp.put("roles", rolesObj); + json_resp.put("roles", rolesObj); + } json_resp.put("token", mLoggedIn.getToken()); //Set response content type From 9333d369c124eb17c5b69e246ca5dd4d9a5d31a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lui=CC=81s=20A=2E=20Bastia=CC=83o=20Silva?= Date: Tue, 26 Jan 2016 19:02:28 +0000 Subject: [PATCH 21/31] Fix issue with duplicated key table column header --- .../web/webapp/WEB-INF/js/components/search/result/studyView.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/studyView.js b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/studyView.js index 1fce8a381..cb913b179 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/studyView.js +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/studyView.js @@ -128,7 +128,7 @@ var StudyView = React.createClass({
      Date - Description + Description Institution Modality From 86f912c21c72b577bad6ca946234b7e4e3650d40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lui=CC=81s=20A=2E=20Bastia=CC=83o=20Silva?= Date: Tue, 26 Jan 2016 19:05:00 +0000 Subject: [PATCH 22/31] Upgrade to new dicoogle-client-js --- .../java/pt/ua/dicoogle/server/web/webapp/WEB-INF/package.json | 2 +- webcore/package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/package.json b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/package.json index 7b9bbd94c..c989cd96f 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/package.json +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/package.json @@ -39,7 +39,7 @@ "dependencies": { "bootstrap": "^3.3.2", "core-js": "^2.0.3", - "dicoogle-client": "^2.4.2", + "dicoogle-client": "^3.0.0-rc0", "dicoogle-webcore": "../../../../../../../../../../../webcore", "document-register-element": "^0.5.4", "history": "^1.13.0", diff --git a/webcore/package.json b/webcore/package.json index 52ca76925..83afecc5d 100644 --- a/webcore/package.json +++ b/webcore/package.json @@ -31,7 +31,7 @@ "eslint": "^1.9.0" }, "dependencies": { - "dicoogle-client": "^2.4.1", + "dicoogle-client": "^3.0.0-rc0", "events": "^1.1.0" } } From 5bf7393840cb79a5baf9f34e528c01e32859769d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lui=CC=81s=20A=2E=20Bastia=CC=83o=20Silva?= Date: Tue, 26 Jan 2016 20:11:45 +0000 Subject: [PATCH 23/31] Make the username and logout more visible in the topbar --- .../server/web/webapp/WEB-INF/js/app.js | 18 +++++++++++++++- .../webapp/WEB-INF/js/components/sidebar.js | 21 +++++++------------ .../webapp/WEB-INF/sass/modules/_topbar.scss | 13 +++++++++++- 3 files changed, 36 insertions(+), 16 deletions(-) diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/app.js b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/app.js index 7c7760287..a3d526e95 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/app.js +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/app.js @@ -113,7 +113,23 @@ class App extends React.Component { +
      + + + + {UserStore.getUsername()} + + + + + + + + + +
      +
      +
      + ); return sidebarInstance; } diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/sass/modules/_topbar.scss b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/sass/modules/_topbar.scss index 3e829df82..22045e9ee 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/sass/modules/_topbar.scss +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/sass/modules/_topbar.scss @@ -4,6 +4,7 @@ background: $blue1; position:fixed; z-index: 1001; + line-height: 50px; } .btn_drawer { width: 50px; @@ -24,4 +25,14 @@ font-size: 30px; vertical-align: middle; } -} \ No newline at end of file +} + +.usernameLogin { + padding-right: 5px; +} + + +.buttonLogin { + padding-right: 10px; +} + From d84059a476c018629e9da64835813a832c07b76f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lui=CC=81s=20A=2E=20Bastia=CC=83o=20Silva?= Date: Tue, 26 Jan 2016 22:52:12 +0000 Subject: [PATCH 24/31] Fixed issue related test not compile --- .../java/pt/ua/dicoogle/core/auth/TestUsers.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/dicoogle/src/test/java/pt/ua/dicoogle/core/auth/TestUsers.java b/dicoogle/src/test/java/pt/ua/dicoogle/core/auth/TestUsers.java index a9a0c010c..459c6d0c0 100644 --- a/dicoogle/src/test/java/pt/ua/dicoogle/core/auth/TestUsers.java +++ b/dicoogle/src/test/java/pt/ua/dicoogle/core/auth/TestUsers.java @@ -73,9 +73,15 @@ public void testUsers() { } Authentication auth = Authentication.getInstance(); - LoggedIn loggedIn = auth.login("nat", "123"); - System.out.println(loggedIn.getUserName()); - System.out.println(loggedIn.isAdmin()); + try { + LoggedIn loggedIn = auth.login("nat", "123"); + System.out.println(loggedIn.getUserName()); + System.out.println(loggedIn.isAdmin()); + } + catch(Exception e) + { + System.out.println("Error in the test"); + } } From 5668a6f2a7a3684705c151a69481b750312b8995 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lui=CC=81s=20A=2E=20Bastia=CC=83o=20Silva?= Date: Wed, 27 Jan 2016 00:14:10 +0000 Subject: [PATCH 25/31] Be sure that after reload all the user requirements are fetched correctly --- .../server/web/webapp/WEB-INF/js/app.js | 7 ++++ .../web/webapp/WEB-INF/js/stores/userStore.js | 40 +++---------------- 2 files changed, 13 insertions(+), 34 deletions(-) diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/app.js b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/app.js index a3d526e95..53ae4175c 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/app.js +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/app.js @@ -41,6 +41,7 @@ class App extends React.Component { pluginMenuItems: [] }; this.logout = this.logout.bind(this); + } /** @@ -62,13 +63,19 @@ class App extends React.Component { componentWillMount() { UserStore.listen(this.fetchPlugins.bind(this)); + let dicoogleClient = DicoogleClient(Endpoints.base); if (localStorage.token!=null) { dicoogleClient.setToken(localStorage.token); } + Webcore.init(Endpoints.base); } + componentDidMount(){ + UserStore.loadLocalStore(); + //setTimeout(function(){}, 300); + } fetchPlugins(data) { if (this.pluginsFetched) return; diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/stores/userStore.js b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/stores/userStore.js index 3d635ab01..f22f709e4 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/stores/userStore.js +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/stores/userStore.js @@ -20,12 +20,12 @@ var UserStore = Reflux.createStore({ this._isAdmin = false; this._roles = []; this._token = ''; - this.loadLocalStore() + }, saveLocalStore: function(){ localStorage.setItem("user", JSON.stringify({ - isAdmin: this.isAdmin, + isAdmin: this._isAdmin, 'username': this._username, 'roles': this._roles, 'token': this._token @@ -36,8 +36,9 @@ var UserStore = Reflux.createStore({ loadLocalStore: function(){ if (localStorage.token!=null) { + console.log("loadLocalStore"); let user = JSON.parse(localStorage.getItem("user")); - this._isAdmin = user._isAdmin ; + this._isAdmin = user.isAdmin ; this._username = user.username; this._roles = user.roles; this._token = user.token ; @@ -87,37 +88,7 @@ var UserStore = Reflux.createStore({ }); - /*$.ajax({ - url: Endpoints.base + "/login", - type: "POST", - dataType: 'json', - data: formData, - success: function(data, textStatus, jqXHR) - { - console.log(data); - self._username = data.user; - self._isAdmin = data.admin; - self._token = data.token; - self._roles = data.roles; - self._isLoggedIn = true; - localStorage.token = self._token; - self.saveLocalStore(); - - console.log("Localstorage token: " + localStorage.token); - self.trigger({ - isLoggedIn: self._isLoggedIn, - success: true - }); - }, - error: function (jqXHR, textStatus, errorThrown) - { - //TODO: HANDLE LOGIN FAILED - console.log("Login Failed"); - self.trigger({ - failed: true - }); - } - });*/ + }, onIsLoggedIn: function(){ @@ -184,6 +155,7 @@ var UserStore = Reflux.createStore({ onLogout: function() { delete localStorage.token; + delete localStorage.user; }, getUsername: function(){ From 83006ae84cab6ce01d8087177493081e088ddd61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lui=CC=81s=20A=2E=20Bastia=CC=83o=20Silva?= Date: Wed, 27 Jan 2016 00:34:58 +0000 Subject: [PATCH 26/31] Plugin form to be large (size) --- .../web/webapp/WEB-INF/js/components/plugin/pluginForm.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/plugin/pluginForm.jsx b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/plugin/pluginForm.jsx index bb5f93c68..3581cb540 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/plugin/pluginForm.jsx +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/plugin/pluginForm.jsx @@ -50,7 +50,7 @@ export default class PluginFormModal extends React.Component { render() { const {plugin, slotId, data} = this.props; return (plugin && - + {this.props.plugin.caption} From 748aea7897149be77874a4a83162bff3f6f6575d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lui=CC=81s=20A=2E=20Bastia=CC=83o=20Silva?= Date: Wed, 27 Jan 2016 20:57:45 +0000 Subject: [PATCH 27/31] - Make the admin view all default plugins - Fixed issue with batch --- .../dicoogle/plugins/webui/WebUIPlugin.java | 22 ++++++++++--------- .../web/servlets/webui/WebUIServlet.java | 5 ++++- .../js/components/search/result/imageView.js | 1 + .../components/search/result/patientView.js | 1 + .../js/components/search/result/serieView.js | 1 + .../js/components/search/result/studyView.js | 1 + .../webapp/WEB-INF/js/components/sidebar.js | 2 +- 7 files changed, 21 insertions(+), 12 deletions(-) diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/plugins/webui/WebUIPlugin.java b/dicoogle/src/main/java/pt/ua/dicoogle/plugins/webui/WebUIPlugin.java index 1be0279be..d7b17266c 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/plugins/webui/WebUIPlugin.java +++ b/dicoogle/src/main/java/pt/ua/dicoogle/plugins/webui/WebUIPlugin.java @@ -82,16 +82,18 @@ public static WebUIPlugin fromPackageJSON(JSONObject obj) throws PluginFormatExc plugin.slotId = objDicoogle.getString("slot-id"); plugin.moduleFile = objDicoogle.optString("module-file", "module.js"); plugin.caption = objDicoogle.optString("caption", null); - JSONArray rolesArr = objDicoogle.getJSONArray("roles"); - System.out.println(rolesArr); - Set roles = new HashSet<>(); - if (rolesArr!=null) - for (Object role :rolesArr) - { - System.out.println(role); - roles.add((String)role); - } - plugin.roles = roles; + if (objDicoogle.containsKey("roles")) + { + JSONArray rolesArr = objDicoogle.getJSONArray("roles"); + + Set roles = new HashSet<>(); + if (rolesArr != null) + for (Object role : rolesArr) { + + roles.add((String) role); + } + plugin.roles = roles; + } return plugin; } catch(JSONException ex) { diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/servlets/webui/WebUIServlet.java b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/servlets/webui/WebUIServlet.java index 39995de61..6270c9b8f 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/servlets/webui/WebUIServlet.java +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/servlets/webui/WebUIServlet.java @@ -74,23 +74,26 @@ private String getPluginsBySlot(HttpServletRequest req, String token = req.getHeader("Authorization"); User user = Authentication.getInstance().getUsername(token); + System.out.println(slotIds); Collection plugins = PluginController.getInstance().getWebUIPlugins(slotIds); List pkgList = new ArrayList<>(plugins.size()); for (WebUIPlugin plugin : plugins) { + String pkg = PluginController.getInstance().getWebUIPackageJSON(plugin.getName()); boolean hasUserAllowPlugin= false; for (String r:plugin.getRoles()) { Role rr = RolesStruct.getInstance().getRole(r); + hasUserAllowPlugin = RolesStruct.getInstance().hasRole(user, rr); if (hasUserAllowPlugin) break; } - if (pkg != null&&hasUserAllowPlugin) { + if (pkg != null&&(hasUserAllowPlugin||user.isAdmin())) { pkgList.add(pkg); } } diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/imageView.js b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/imageView.js index 145f1f460..cafe51a37 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/imageView.js +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/imageView.js @@ -31,6 +31,7 @@ var ImageView = React.createClass({ componentWillMount: function() { // Subscribe to the store. SearchStore.listen(this._onChange); + ResultSelectActions.clear(); }, diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/patientView.js b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/patientView.js index c6ed2b1b3..c764b90aa 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/patientView.js +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/patientView.js @@ -38,6 +38,7 @@ const PatientView = React.createClass({ componentWillMount: function() { // Subscribe to the store. SearchStore.listen(this._onChange); + ResultSelectActions.clear(); }, /** diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/serieView.js b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/serieView.js index 9353b8896..8d3594dea 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/serieView.js +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/serieView.js @@ -24,6 +24,7 @@ var SeriesView = React.createClass({ componentWillMount: function() { // Subscribe to the store. SearchStore.listen(this._onChange); + ResultSelectActions.clear(); }, /** diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/studyView.js b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/studyView.js index 39e687bc9..83a18d761 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/studyView.js +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/studyView.js @@ -26,6 +26,7 @@ var StudyView = React.createClass({ componentWillMount: function() { // Subscribe to the store. SearchStore.listen(this._onChange); + ResultSelectActions.clear(); }, /** diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/sidebar.js b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/sidebar.js index fb7bfdeb4..a37cf23e5 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/sidebar.js +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/sidebar.js @@ -36,7 +36,7 @@ const Sidebar = React.createClass({ menuItems.map(function(e, i) { const to = (e.isPlugin ? '/ext/' : '/') + e.value; - let myKey = i + Math.floor((Math.random() * 100) + 1); + let myKey = i ;//+ Math.floor((Math.random() * 100) + 1); if (!e.admin || isAdmin) return (
    • {e.caption} From 5b4815924b078050423b88595557326f0e97bc3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lui=CC=81s=20A=2E=20Bastia=CC=83o=20Silva?= Date: Wed, 27 Jan 2016 21:00:29 +0000 Subject: [PATCH 28/31] Redirect if there is no login --- .../java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/app.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/app.js b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/app.js index 53ae4175c..07e978b22 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/app.js +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/app.js @@ -74,6 +74,8 @@ class App extends React.Component { } componentDidMount(){ UserStore.loadLocalStore(); + if (localStorage.token===undefined) + this.props.history.pushState(null, 'login'); //setTimeout(function(){}, 300); } fetchPlugins(data) { From 7fa51b8b978500749a21a36fe6ee1019cd87724d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lui=CC=81s=20A=2E=20Bastia=CC=83o=20Silva?= Date: Thu, 28 Jan 2016 18:41:07 +0000 Subject: [PATCH 29/31] Fixed problem with session and make logout works properly --- .../dicoogle/server/web/auth/Authentication.java | 8 ++++++++ .../pt/ua/dicoogle/server/web/auth/Session.java | 16 +++++++++++++--- .../web/servlets/accounts/LogoutServlet.java | 11 ++++++----- .../dicoogle/server/web/webapp/WEB-INF/js/app.js | 2 +- 4 files changed, 28 insertions(+), 9 deletions(-) diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/auth/Authentication.java b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/auth/Authentication.java index 19ee06804..9a8115c01 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/auth/Authentication.java +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/auth/Authentication.java @@ -73,6 +73,14 @@ public User getUsername(String token) } + public void logout(String username){ + String token = usersToken.get(username); + String user = tokenUsers.get(token); + tokenUsers.remove(token); + usersToken.remove(username); + + } + /** * Attemps to login on the plataform. * diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/auth/Session.java b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/auth/Session.java index 2c54d0d3a..998393fdf 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/auth/Session.java +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/auth/Session.java @@ -116,6 +116,16 @@ public static LoggedIn getUserLoggedIn(HttpSession session) public static boolean logout(HttpServletRequest request) { HttpSession session = request.getSession(false); + try + { + session.invalidate(); + } + catch (Exception e ) + { + System.err.println("Tracking session"); + } + + // if the sessio is invalid if (session == null) @@ -216,9 +226,9 @@ public static LoggedIn servletLogin(HttpServletRequest request, HttpServletRespo public static LoggedInStatus webappLogin(HttpServletRequest request, HttpServletResponse response, boolean requiresAdminRights) throws IOException { // check if there a session and a login information attached to it - HttpSession session = request.getSession(false); + HttpSession session = request.getSession(true); LoggedIn login = getUserLoggedIn(session); - if (login != null) + /*if (login != null) { // check if this request needs admin rights and the user has them if (requiresAdminRights && (! login.isAdmin())) @@ -228,7 +238,7 @@ public static LoggedInStatus webappLogin(HttpServletRequest request, HttpServlet } return new LoggedInStatus(login, LoggedInStatus.S_ALREADYLOGGEDIN); - } + }*/ // since the above failed, check if there is valid login information on the request parameters String username = request.getParameter("username"); diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/servlets/accounts/LogoutServlet.java b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/servlets/accounts/LogoutServlet.java index 02c195356..b3e9b776e 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/servlets/accounts/LogoutServlet.java +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/servlets/accounts/LogoutServlet.java @@ -25,6 +25,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import net.sf.json.JSONObject; +import pt.ua.dicoogle.server.web.auth.Authentication; import pt.ua.dicoogle.server.web.auth.Session; import pt.ua.dicoogle.server.web.utils.ResponseUtil; @@ -38,12 +39,12 @@ public class LogoutServlet extends HttpServlet{ protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //resp.addHeader("Access-Control-Allow-Origin", "*"); boolean logout = Session.logout(req); - + String username = req.getParameter("username"); + if (username!=null&&!username.equals("")) + Authentication.getInstance().logout(username); + ResponseUtil.simpleResponse(resp,"success", logout); - - - - + } } diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/app.js b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/app.js index 07e978b22..af2cbd34a 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/app.js +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/app.js @@ -102,7 +102,7 @@ class App extends React.Component { logout() { let self = this; - $.get(Endpoints.base + "/logout", (data, status) => { + $.get(Endpoints.base + "/logout?username="+UserStore.getUsername(), (data, status) => { //Response console.log("Data: " + data + "\nStatus: " + status); From 4ea9380a60205b0e8bbfef9046a304310a24c861 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lui=CC=81s=20A=2E=20Bastia=CC=83o=20Silva?= Date: Thu, 28 Jan 2016 21:19:37 +0000 Subject: [PATCH 30/31] Avoid exception if there is no session --- .../ua/dicoogle/server/web/servlets/webui/WebUIServlet.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/servlets/webui/WebUIServlet.java b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/servlets/webui/WebUIServlet.java index 6270c9b8f..7836bbb1e 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/servlets/webui/WebUIServlet.java +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/servlets/webui/WebUIServlet.java @@ -80,7 +80,7 @@ private String getPluginsBySlot(HttpServletRequest req, for (WebUIPlugin plugin : plugins) { - + String pkg = PluginController.getInstance().getWebUIPackageJSON(plugin.getName()); boolean hasUserAllowPlugin= false; for (String r:plugin.getRoles()) @@ -93,7 +93,7 @@ private String getPluginsBySlot(HttpServletRequest req, } - if (pkg != null&&(hasUserAllowPlugin||user.isAdmin())) { + if (pkg != null&&(hasUserAllowPlugin||(user!=null&&user.isAdmin()))) { pkgList.add(pkg); } } From 96c12e576c39cab3d06a06b043dfbe54b844edc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lui=CC=81s=20A=2E=20Bastia=CC=83o=20Silva?= Date: Thu, 28 Jan 2016 21:20:17 +0000 Subject: [PATCH 31/31] Make the plugins available in study level --- .../js/components/search/result/studyView.js | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/studyView.js b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/studyView.js index 83a18d761..7eaa95b59 100644 --- a/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/studyView.js +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/components/search/result/studyView.js @@ -69,17 +69,17 @@ var StudyView = React.createClass({ removeFiles = (); - - return (
      - {unindex} - {removeFiles} - {/* plugin-based result options */} - -
      ); } + return (
      + {unindex} + {removeFiles} + {/* plugin-based result options */} + +
      ); + } return (
      ); },