diff --git a/ad-connector/src/main/java/net/jami/jams/ad/connector/ADConnector.java b/ad-connector/src/main/java/net/jami/jams/ad/connector/ADConnector.java index 6fb46a6294b2285aa55788014897968adc42aa7c..2b909cb1dcdee6d28942a34d341f620e194650fb 100644 --- a/ad-connector/src/main/java/net/jami/jams/ad/connector/ADConnector.java +++ b/ad-connector/src/main/java/net/jami/jams/ad/connector/ADConnector.java @@ -73,6 +73,11 @@ public class ADConnector implements AuthenticationSource { return userProfileService.getUserProfile(queryString,field); } + @Override + public void setUserProfile(UserProfile userProfile) { + //does nothing as we cannot edit user profiles. + } + @Override public boolean authenticate(String username, String password) { try { diff --git a/authentication-module/src/main/java/net/jami/jams/authmodule/UserAuthenticationModule.java b/authentication-module/src/main/java/net/jami/jams/authmodule/UserAuthenticationModule.java index 401e0d9041da50fee3151b47a7ec6d1763b4a294..2768668ee3d6c27666db6b55f346204b129075cd 100644 --- a/authentication-module/src/main/java/net/jami/jams/authmodule/UserAuthenticationModule.java +++ b/authentication-module/src/main/java/net/jami/jams/authmodule/UserAuthenticationModule.java @@ -23,7 +23,6 @@ import java.security.PrivateKey; import java.security.PublicKey; import java.security.cert.X509Certificate; import java.security.interfaces.RSAPublicKey; -import java.util.HashMap; import java.util.concurrent.ConcurrentHashMap; diff --git a/datastore/src/main/java/net/jami/datastore/main/DataStore.java b/datastore/src/main/java/net/jami/datastore/main/DataStore.java index 457f9074877c8752f4356a64e41122b19920b0ff..2ec325c04cccd3420a91e23a4c52f3f62df4ff5b 100644 --- a/datastore/src/main/java/net/jami/datastore/main/DataStore.java +++ b/datastore/src/main/java/net/jami/datastore/main/DataStore.java @@ -51,6 +51,11 @@ public class DataStore implements AuthenticationSource { return null; } + @Override + public void setUserProfile(UserProfile userProfile) { + //TODO: Implement this. + } + @Override public boolean authenticate(String username, String password) { StatementList statementList = new StatementList(); diff --git a/integration-test/install-server.py b/integration-test/install-server.py index 4add5375b079ca2552a6db951e14ffbbaebd68cd..6e96c067285a88aa5c1f8984689f640dfe75c8f2 100644 --- a/integration-test/install-server.py +++ b/integration-test/install-server.py @@ -118,4 +118,9 @@ print(token) response = requests.get("http://localhost:8080/api/nameserver/name/aberaud",headers=header) print(response.status_code) +print(response.text) + + +response = requests.get("http://localhost:8080//api/auth/directories",headers=header) +print(response.status_code) print(response.text) \ No newline at end of file diff --git a/jams-common/src/main/java/net/jami/jams/common/authentication/AuthenticationSource.java b/jams-common/src/main/java/net/jami/jams/common/authentication/AuthenticationSource.java index 1b27f44b9cfd024f768cb8c7302418a22519c344..68c1314369c81ece50dcd5ddfde9251c3e0d047e 100644 --- a/jams-common/src/main/java/net/jami/jams/common/authentication/AuthenticationSource.java +++ b/jams-common/src/main/java/net/jami/jams/common/authentication/AuthenticationSource.java @@ -7,6 +7,7 @@ public interface AuthenticationSource { boolean createUser(User user); UserProfile[] getUserProfile(String queryString, String field); + void setUserProfile(UserProfile userProfile); boolean authenticate(String username, String password); AuthenticationSourceInfo getInfo(); boolean test(); diff --git a/jams-common/src/main/java/net/jami/jams/common/authentication/AuthenticationSourceType.java b/jams-common/src/main/java/net/jami/jams/common/authentication/AuthenticationSourceType.java index 329f003b8d5c5ded471bae9d7fc51e1b8053d514..ed5c90c3ffe2c7a750a574a179a9c47698cc8ee8 100644 --- a/jams-common/src/main/java/net/jami/jams/common/authentication/AuthenticationSourceType.java +++ b/jams-common/src/main/java/net/jami/jams/common/authentication/AuthenticationSourceType.java @@ -3,5 +3,13 @@ package net.jami.jams.common.authentication; public enum AuthenticationSourceType { AD, LDAP, - LOCAL + LOCAL; + + public static AuthenticationSourceType fromString(String str){ + if(str.equals("AD")) return AD; + if(str.equals("LDAP")) return LDAP; + if(str.equals("LOCAL")) return LOCAL; + return null; + } + } diff --git a/jams-server/src/main/java/module-info.java b/jams-server/src/main/java/module-info.java index 559226c409985e51337db186cb74624bfd6579b3..7e05ebd76b4032cf1a245d3b4db0f63a6a2273cd 100644 --- a/jams-server/src/main/java/module-info.java +++ b/jams-server/src/main/java/module-info.java @@ -16,11 +16,17 @@ module jams.server { requires jami.dht; requires nimbus.jose.jwt; requires java.desktop; - exports net.jami.jams.server.servlets.general to org.apache.tomcat.embed.core; + exports net.jami.jams.server.servlets.filters to org.apache.tomcat.embed.core; + exports net.jami.jams.server.servlets.api.auth.login to org.apache.tomcat.embed.core; exports net.jami.jams.server.servlets.api.auth.device to org.apache.tomcat.embed.core; + exports net.jami.jams.server.servlets.api.auth.directory to org.apache.tomcat.embed.core; + exports net.jami.jams.server.servlets.api.install to org.apache.tomcat.embed.core; + + exports net.jami.jams.server.servlets.general to org.apache.tomcat.embed.core; exports net.jami.jams.server.servlets.api.jaminameserver to org.apache.tomcat.embed.core; exports net.jami.jams.server.servlets.x509 to org.apache.tomcat.embed.core; + } \ No newline at end of file diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/devices/DeviceServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/devices/DeviceServlet.java index dff1de3f6122db25ac1d73a2d918fac1b20b9324..f6ccf37b3749e6b6e18ae6168b9ec2025bd5a56b 100644 --- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/devices/DeviceServlet.java +++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/devices/DeviceServlet.java @@ -1,31 +1,47 @@ package net.jami.jams.server.servlets.api.admin.devices; +import com.jsoniter.output.JsonStream; import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; +import net.jami.jams.common.dao.StatementElement; +import net.jami.jams.common.dao.StatementList; +import net.jami.jams.common.objects.responses.DeviceRevocationResponse; +import net.jami.jams.server.core.workflows.RevokeDeviceFlow; import java.io.IOException; -@WebServlet("/api/admin/device/*") +import static net.jami.jams.server.Server.dataStore; + +@WebServlet("/api/admin/device") public class DeviceServlet extends HttpServlet { //Get a detailed device info. @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - super.doGet(req, resp); + String username = req.getParameter("username"); + String deviceId = req.getParameter("deviceId"); + StatementList statementList = new StatementList(); + StatementElement st1 = new StatementElement("owner","=",username,"AND"); + StatementElement st2 = new StatementElement("deviceId","=",deviceId,""); + statementList.addStatement(st1); + statementList.addStatement(st2); + resp.getOutputStream().write(JsonStream.serialize(dataStore.getDeviceDao().getObjects(statementList).get(0)).getBytes()); } //Update device data. @Override protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - super.doPut(req, resp); + } //Revoke/delete a device. @Override protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - super.doDelete(req, resp); + DeviceRevocationResponse devResponse = RevokeDeviceFlow.revokeDevice(req.getParameter("username").toString(),req.getParameter("deviceId")); + if(devResponse != null) resp.getOutputStream().write(JsonStream.serialize(devResponse).getBytes()); + else resp.sendError(500,"An exception has occurred while trying to revoke a device!"); } } diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/devices/DevicesServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/devices/DevicesServlet.java index ba3162715ceea23e7aee24e86af6b50b75f84be2..b28b616c565aa546c025e53e8b7373cc8dae6aa5 100644 --- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/devices/DevicesServlet.java +++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/devices/DevicesServlet.java @@ -1,19 +1,28 @@ package net.jami.jams.server.servlets.api.admin.devices; +import com.jsoniter.output.JsonStream; import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; +import net.jami.jams.common.dao.StatementElement; +import net.jami.jams.common.dao.StatementList; import java.io.IOException; -@WebServlet("/api/admin/devices/*") +import static net.jami.jams.server.Server.dataStore; + +@WebServlet("/api/admin/devices") public class DevicesServlet extends HttpServlet { //Get a list of devices for a user. @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - super.doGet(req, resp); + String username = req.getParameter("username"); + StatementList statementList = new StatementList(); + StatementElement st1 = new StatementElement("owner","=",username,""); + statementList.addStatement(st1); + resp.getOutputStream().write(JsonStream.serialize(dataStore.getDeviceDao().getObjects(statementList)).getBytes()); } } diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/directory/DirectoryEntryServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/directory/DirectoryEntryServlet.java new file mode 100644 index 0000000000000000000000000000000000000000..2b7d57b06ca5807d9ac97c190c4329050f4a08ef --- /dev/null +++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/directory/DirectoryEntryServlet.java @@ -0,0 +1,46 @@ +package net.jami.jams.server.servlets.api.admin.directory; + +import com.jsoniter.JsonIterator; +import jakarta.servlet.ServletException; +import jakarta.servlet.annotation.WebServlet; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.extern.slf4j.Slf4j; +import net.jami.jams.common.authentication.AuthenticationSourceType; +import net.jami.jams.common.authmodule.AuthModuleKey; +import net.jami.jams.common.objects.user.UserProfile; + +import java.io.IOException; + +import static net.jami.jams.server.Server.userAuthenticationModule; + +@WebServlet("/api/admin/directory/entry") +@Slf4j +public class DirectoryEntryServlet extends HttpServlet { + + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + //Create a user profile. + try { + String realm = req.getParameter("directory"); + UserProfile userProfile = JsonIterator.deserialize(req.getInputStream().readAllBytes(), UserProfile.class); + userAuthenticationModule.getAuthSources().get(new AuthModuleKey(realm, AuthenticationSourceType.LOCAL)) + .setUserProfile(userProfile); + } + catch (Exception e){ + log.error("Could not store a user profile!"); + } + + } + + @Override + protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + //Update a user's profile. + } + + @Override + protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + //This method will probably never be implemented. + } +} diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/users/UserServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/users/UserServlet.java index 738d6f7256c93a4845b65d82e96ca2939dc81f48..25879185385f6ea30ee9b65cb32eecdc7d4b871e 100644 --- a/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/users/UserServlet.java +++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/admin/users/UserServlet.java @@ -1,39 +1,48 @@ package net.jami.jams.server.servlets.api.admin.users; +import com.jsoniter.JsonIterator; import com.jsoniter.output.JsonStream; import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; +import net.jami.jams.common.dao.StatementElement; +import net.jami.jams.common.dao.StatementList; import net.jami.jams.common.objects.requests.RevocationRequest; import net.jami.jams.common.objects.requests.RevocationType; import net.jami.jams.common.objects.responses.DeviceRevocationResponse; +import net.jami.jams.common.objects.user.User; import net.jami.jams.server.core.workflows.RevokeDeviceFlow; import net.jami.jams.server.core.workflows.RevokeUserFlow; import java.io.IOException; import java.math.BigInteger; -@WebServlet("/api/admin/user/*") +import static net.jami.jams.server.Server.dataStore; + +@WebServlet("/api/admin/user") public class UserServlet extends HttpServlet { //Get the user profile. @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - super.doGet(req, resp); + StatementList statementList = new StatementList(); + StatementElement st1 = new StatementElement("username","=",req.getParameter("username"),""); + statementList.addStatement(st1); + resp.getOutputStream().write(JsonStream.serialize(dataStore.getUserDao().getObjects(statementList)).getBytes()); } //Create an internal user - this is always technically available, because internal users have the right to exist. @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - super.doPost(req, resp); + } //Update user data. @Override protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { - super.doPut(req, resp); + } //Revoke a user. diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/directory/DirectoriesServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/directory/DirectoriesServlet.java new file mode 100644 index 0000000000000000000000000000000000000000..8f5b05e18235c26d95ce7524b8a4a805910222c4 --- /dev/null +++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/directory/DirectoriesServlet.java @@ -0,0 +1,21 @@ +package net.jami.jams.server.servlets.api.auth.directory; + +import com.jsoniter.output.JsonStream; +import jakarta.servlet.ServletException; +import jakarta.servlet.annotation.WebServlet; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; + +import java.io.IOException; + +import static net.jami.jams.server.Server.userAuthenticationModule; + +@WebServlet("/api/auth/directories") +public class DirectoriesServlet extends HttpServlet { + + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + resp.getOutputStream().write(JsonStream.serialize(userAuthenticationModule.getAuthSources().keySet()).getBytes()); + } +} diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/directory/DirectoryEntryServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/directory/DirectoryEntryServlet.java new file mode 100644 index 0000000000000000000000000000000000000000..8a28415519396b9a2b5066a894a7816d60b5a914 --- /dev/null +++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/directory/DirectoryEntryServlet.java @@ -0,0 +1,47 @@ +package net.jami.jams.server.servlets.api.auth.directory; + +import com.jsoniter.output.JsonStream; +import jakarta.servlet.ServletException; +import jakarta.servlet.annotation.WebServlet; +import jakarta.servlet.http.HttpServlet; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import net.jami.jams.common.authentication.AuthenticationSourceType; +import net.jami.jams.common.authmodule.AuthModuleKey; +import net.jami.jams.common.objects.user.UserProfile; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import static net.jami.jams.server.Server.userAuthenticationModule; + +//This is an endpoint to manipulate directory entry-data, this make sense only for local setups. + +@WebServlet("/api/auth/directory/entry") +public class DirectoryEntryServlet extends HttpServlet { + + //Get a profile from a directory, we are assuming here + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + if (req.getParameter("directory") != null && req.getParameter("directoryType") != null) { + UserProfile[] profiles = userAuthenticationModule.getAuthSources() + .get(new AuthModuleKey(req.getParameter("directory"), AuthenticationSourceType.fromString(req.getParameter("directoryType")))) + .getUserProfile(req.getParameter("username"), "LOGON_NAME"); + resp.getOutputStream().write(JsonStream.serialize(profiles[0]).getBytes()); + return; + } + List<UserProfile> userProfiles = new ArrayList<>(); + userAuthenticationModule.getAuthSources().forEach((k, v) -> { + UserProfile[] profiles = v.getUserProfile(req.getParameter("username"), "LOGON_NAME"); + if (profiles != null && profiles.length != 0) userProfiles.addAll(Arrays.asList(profiles)); + }); + resp.getOutputStream().write(JsonStream.serialize(userProfiles.get(0)).getBytes()); + } + + @Override + protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + //This should work to modify a profile only in the case of a LOCAL directory. + } +} diff --git a/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/user/UserServlet.java b/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/user/UserServlet.java new file mode 100644 index 0000000000000000000000000000000000000000..fc79b8965fdf5f97a822b60b714f9c7d0a1ef839 --- /dev/null +++ b/jams-server/src/main/java/net/jami/jams/server/servlets/api/auth/user/UserServlet.java @@ -0,0 +1,8 @@ +package net.jami.jams.server.servlets.api.auth.user; + +import jakarta.servlet.annotation.WebServlet; +import jakarta.servlet.http.HttpServlet; + +@WebServlet("/api/auth/user") +public class UserServlet extends HttpServlet { +} diff --git a/ldap-connector/src/main/java/net/jami/jams/ldap/connector/LDAPConnector.java b/ldap-connector/src/main/java/net/jami/jams/ldap/connector/LDAPConnector.java index 6865ba19f8269d377cfe57f1b8b2daca0931bf9d..427421595a53d9f54fa6a522f22f6c874f952010 100644 --- a/ldap-connector/src/main/java/net/jami/jams/ldap/connector/LDAPConnector.java +++ b/ldap-connector/src/main/java/net/jami/jams/ldap/connector/LDAPConnector.java @@ -49,6 +49,11 @@ public class LDAPConnector implements AuthenticationSource { return userProfileService.getUserProfile(queryString,field); } + @Override + public void setUserProfile(UserProfile userProfile) { + //does nothing since we cannot edit LDAP profiles. + } + @Override public boolean authenticate(String username, String password) { return authenticationService.authenticateUser(username,password);