diff --git a/dicoogle/dicoogle.log b/dicoogle/dicoogle.log deleted file mode 100644 index e69de29bb..000000000 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/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..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 @@ -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,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); + 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) { @@ -156,5 +175,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/users/Role.java b/dicoogle/src/main/java/pt/ua/dicoogle/server/users/Role.java new file mode 100644 index 000000000..cf5fe3039 --- /dev/null +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/users/Role.java @@ -0,0 +1,67 @@ +/** + * 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; + +/** + * 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..db28eef2a --- /dev/null +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/users/RoleManager.java @@ -0,0 +1,35 @@ +/** + * 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; +import java.util.List; +import java.util.Set; + +/** + * Created by bastiao on 23/01/16. + */ +public interface RoleManager { + + public boolean hasRole(User user, Role r); + 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 new file mode 100644 index 000000000..3b4a3dc7e --- /dev/null +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/users/RolesStruct.java @@ -0,0 +1,72 @@ +/** + * 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.*; + +/** + * Created by bastiao on 23/01/16. + */ +public class RolesStruct implements RoleManager{ + + private static RolesStruct instance = null ; + + private Set roles = new HashSet<>(); + private Map rolesMap = new HashMap(); + + public static synchronized RolesStruct getInstance() { + if (instance == null) { + instance = new RolesStruct(); + } + + return instance; + } + private RolesStruct(){ + reset(); + } + + public void reset(){ + roles = new HashSet<>(); + } + + @Override + public boolean hasRole(User user, Role r) { + if (user==null||r==null) + return false; + return UsersStruct.getInstance().getUser(user.getUsername()).hasRole(r); + } + + @Override + 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 new file mode 100755 index 000000000..efdb357bf --- /dev/null +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/users/RolesXML.java @@ -0,0 +1,243 @@ +/** + * 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.crypto.Cipher; +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.*; +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 RolesStruct roles = RolesStruct.getInstance(); + private boolean isRoles = false ; + + private String rolename; + + + + public RolesXML() + { + rolename = ""; + } + + + @Override + public void startElement( String uri, String localName, String qName, + Attributes attribs ) + { + + + + if (localName.equals("Roles")) + { + isRoles = true ; + } + else if (this.isRoles && localName.equals("role")) + { + this.rolename = this.resolveAttrib("name", attribs, "xp"); + } + + } + + + @Override + public void endElement( String uri, String localName, String qName ) + { + + if (localName.equals("Users")) + { + isRoles = false ; + } + else if( localName.equals( "role" ) ) + { + roles.addRole(new Role(rolename)); + } + + } + + private String resolveAttrib( String attr, Attributes attribs, String defaultValue) { + String tmp = attribs.getValue(attr); + return (tmp!=null)?(tmp):(defaultValue); + } + + + public RolesStruct getXML() + { + roles.reset(); + + try + { + + 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) + { + + printXML(); + return roles; + } + + + // 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 roles; + } + catch (SAXException | IOException ex) + { + LoggerFactory.getLogger(RolesXML.class).error(ex.getMessage(), ex); + } + return null; + } + + /** + * Print the roles 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(); + + 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("", "", "Roles", atts); + + Iterator us = RolesStruct.getInstance().getRoles().iterator(); + + atts.clear(); + while (us.hasNext()) + { + Role role = us.next(); + + atts.addAttribute("", "", "name", "", role.getName()); + + hd.startElement("", "", "role", atts); + atts.clear(); + hd.endElement("", "", "role"); + } + hd.endElement("", "", "Roles"); + + + hd.endDocument(); + } catch (SAXException ex) + { + LoggerFactory.getLogger(RolesXML.class).error(ex.getMessage(), ex); + } + finally { + try { + out.close(); + + printFile(out.toByteArray()); + + } catch (Exception ex) { + LoggerFactory.getLogger(RolesXML.class).error(ex.getMessage(), ex); + } + } + + + } + /** + * 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/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..0f2956f1b --- /dev/null +++ b/dicoogle/src/main/java/pt/ua/dicoogle/server/users/UserRoleManager.java @@ -0,0 +1,28 @@ +/** + * 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; + +/** + * Created by bastiao on 23/01/16. + */ +public interface UserRoleManager { + + public boolean hasRole(Role r); + public void addRole(Role r); +} 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/CORSFilter.java b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/CORSFilter.java index e00cc25ad..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 @@ -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,Content-Length"; } + } @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..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"); + 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/auth/Authentication.java b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/auth/Authentication.java index fad688962..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 @@ -18,10 +18,11 @@ */ 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.*; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; /** * Provides login routines for users. @@ -33,8 +34,14 @@ public class Authentication private static Authentication instance = null; private static UsersStruct users; + private static Map usersToken = new HashMap(); + private static Map tokenUsers = new HashMap(); // to have performance. + + 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(); @@ -56,6 +63,24 @@ 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); + + } + + 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. * @@ -78,8 +103,17 @@ 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 { + String token =UUID.randomUUID().toString(); + usersToken.put(username, token); + tokenUsers.put(token, username); + 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/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/LoginServlet.java b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/servlets/accounts/LoginServlet.java index 8da34c9a5..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 @@ -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; @@ -27,7 +28,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; @@ -41,7 +46,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"); @@ -51,7 +58,17 @@ 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(); + 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("token", mLoggedIn.getToken()); //Set response content type resp.setContentType("application/json"); @@ -75,7 +92,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/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/servlets/webui/WebUIServlet.java b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/servlets/webui/WebUIServlet.java index acbb521ff..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 @@ -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,36 @@ 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); + + 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()); - 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||(user!=null&&user.isAdmin()))) { pkgList.add(pkg); } } 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/app.js b/dicoogle/src/main/java/pt/ua/dicoogle/server/web/webapp/WEB-INF/js/app.js index 4c0230049..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 @@ -19,7 +19,10 @@ 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 {UserStore} from './stores/userStore'; + import 'document-register-element'; require('core-js/shim'); @@ -33,48 +36,82 @@ class App extends React.Component { constructor(props) { super(props); + this.pluginsFetched = false; this.state = { pluginMenuItems: [] }; this.logout = this.logout.bind(this); + + } + + /** + * @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() { - DicoogleClient(Endpoints.base); + + 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(); + if (localStorage.token===undefined) + this.props.history.pushState(null, 'login'); + //setTimeout(function(){}, 300); + } + 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() { - $.get(Endpoints.base + "/logout", (data, status) => { + let self = this; + $.get(Endpoints.base + "/logout?username="+UserStore.getUsername(), (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'); }); } @@ -85,10 +122,26 @@ class App extends React.Component { +
+ + + + {UserStore.getUsername()} + + + + + + + + + +
+ +
{this.props.children} 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} 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 e9e134dd8..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 @@ -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({ @@ -29,6 +31,7 @@ var ImageView = React.createClass({ componentWillMount: function() { // Subscribe to the store. SearchStore.listen(this._onChange); + ResultSelectActions.clear(); }, @@ -77,18 +80,37 @@ var ImageView = 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 (
); }, @@ -136,7 +158,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 (
-
- ); + + 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 (
); }, @@ -118,8 +139,13 @@ var SeriesView = React.createClass({ bgColor: "rgb(163, 210, 216)", onSelect: this.onRowSelect }; - - return ( + + + // TODO trigger this action elsewhere + ResultSelectActions.level("series"); + + + return (
Number 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 50b7af522..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 @@ -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. @@ -23,6 +26,7 @@ var StudyView = React.createClass({ componentWillMount: function() { // Subscribe to the store. SearchStore.listen(this._onChange); + ResultSelectActions.clear(); }, /** @@ -53,16 +57,30 @@ var StudyView = React.createClass({ formatOptions: function(cell, item){ let self = this; - if (this.props.enableAdvancedSearch) + let isAdmin = UserStore.isAdmin(); + let unindex = null; + let removeFiles = null; + if (this.props.enableAdvancedSearch) { + + if (isAdmin) { + unindex = ( + ); + + removeFiles = (); + } return (
- - - {/* plugin-based result options */} - -
); + {unindex} + {removeFiles} + {/* plugin-based result options */} + +
); + + } return (
); }, @@ -106,12 +124,13 @@ var StudyView = React.createClass({ bgColor: "rgb(163, 210, 216)", onSelect: this.onRowSelect }; - + // TODO trigger this action elsewhere + ResultSelectActions.level("study"); return (
Date - Description + Description Institution Modality 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..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 @@ -18,37 +18,34 @@ 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} -
  • ); + + let myKey = i ;//+ Math.floor((Math.random() * 100) + 1); + if (!e.admin || isAdmin) + return (
  • + {e.caption} +
  • ); }) }
-
-
-
- {UserStore.getUsername()} -
-
-
-
- -
-
-
+ ); return sidebarInstance; } 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 1f433598b..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 @@ -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 () { @@ -14,72 +18,134 @@ var UserStore = Reflux.createStore({ this._isLoggedIn = false; this._username = ""; this._isAdmin = false; + this._roles = []; + this._token = ''; + }, + saveLocalStore: function(){ + localStorage.setItem("user", JSON.stringify({ + isAdmin: this._isAdmin, + 'username': this._username, + 'roles': this._roles, + 'token': this._token + })); + + + }, + loadLocalStore: function(){ + if (localStorage.token!=null) + { + console.log("loadLocalStore"); + let user = JSON.parse(localStorage.getItem("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 + }); + } + + }, onLogin: function(user, pass){ console.log("onLogin"); var self = this; var formData = {username: user, password: pass}; //Array - $.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._isLoggedIn = true; - + let dicoogleClient = DicoogleClient(Endpoints.base); + let errorCallBack = function() + { self.trigger({ - isLoggedIn: self._isLoggedIn, - success: true + failed: true }); - }, - error: function (jqXHR, textStatus, errorThrown) + + }; + dicoogleClient.login(user, pass, function(errorCallBack, data){ + if (data.token===undefined || data.token==null) { - //TODO: HANDLE LOGIN FAILED - console.log("Login Failed"); - self.trigger({ - failed: true - }); + 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 + }); + }); + + + }, onIsLoggedIn: function(){ + 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; + if (localStorage.token !=null) { + 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,9 +153,17 @@ var UserStore = Reflux.createStore({ } }, + onLogout: function() { + delete localStorage.token; + delete localStorage.user; + }, + getUsername: function(){ return this._username; }, + isAdmin: function(){ + return this._isAdmin; + }, getLogginState: function(){ return this._isLoggedIn; } 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/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; +} + 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..343a8016b --- /dev/null +++ b/dicoogle/src/test/java/pt/ua/dicoogle/core/auth/TestRoles.java @@ -0,0 +1,65 @@ +/** + * 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; +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()); + } + + //@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); + } + } + + + + } +} 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..459c6d0c0 --- /dev/null +++ b/dicoogle/src/test/java/pt/ua/dicoogle/core/auth/TestUsers.java @@ -0,0 +1,88 @@ +/** + * 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(); + 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"); + } + + } + +} 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 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" } }