Hello Jorge, I agree that this setup is functional and probably about the simplest way you can implement authorisation. If these accounts are all you need in your setup (and you are probably the best judge for that) then I would not make it any more complex than this. One thing to consider would be to extend this to “role based access”, not linking permissions directly to users but roles instead.
Greetings, Marcel On 28 July 2016 at 22:41:02, Jorge Martín Cuervo ([email protected]) wrote: Hello, after setting up the authentication (1 admin account and one for each target), I have made some changes into the servlets to enforce the authorisation: - repository is only accessible to the admin - deployment is accessible to the admin and for targets if the target Id matches - agent is accessible to the admin and for targets if the target Id matches - log (audit) get is accessible to the admin and for targets if the target Id matches - log (audit) post is accessible to everybody This is functional, but I am not sure this is the best way. Could you please give me some feedback? Thanks! diff --git a/org.apache.ace.deployment/src/org/apache/ace/deployment/servlet/AgentDeploymentServlet.java b/org.apache.ace.deployment/src/org/apache/ace/deployment/servlet/AgentDeploymentServlet.java index 27ac522..c7c0a9b 100644 --- a/org.apache.ace.deployment/src/org/apache/ace/deployment/servlet/AgentDeploymentServlet.java +++ b/org.apache.ace.deployment/src/org/apache/ace/deployment/servlet/AgentDeploymentServlet.java @@ -54,6 +54,7 @@ import org.osgi.service.log.LogService; import org.osgi.service.repository.ContentNamespace; import org.osgi.service.repository.Repository; +import org.osgi.service.useradmin.User; import aQute.bnd.deployer.repository.FixedIndexedRepo; import aQute.bnd.osgi.resource.CapReqBuilder; @@ -103,8 +104,17 @@ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try { String[] pathElements = verifyAndGetPathElements(request.getPathInfo()); - // String targetID = pathElements[1]; // in the future we might use this for per target approval + String targetID = pathElements[1]; // in the future we might use this for per target approval String agentID = pathElements[2]; + + User user = (User)request.getAttribute("org.apache.ace.authentication.user"); + if(user != null && user.getName().equals("admin")) { + //no-op + } else if(user != null && !user.getName().equals(targetID)) { + //the target does not correspond to the username + throw new AceRestException(HttpServletResponse.SC_UNAUTHORIZED, "Not authorised"); + } + int numberOfElements = pathElements.length; if (numberOfElements == 4) { handleVersionsRequest(getVersions(agentID), response); diff --git a/org.apache.ace.deployment/src/org/apache/ace/deployment/servlet/DeploymentServlet.java b/org.apache.ace.deployment/src/org/apache/ace/deployment/servlet/DeploymentServlet.java index 2509433..e8b8d34 100644 --- a/org.apache.ace.deployment/src/org/apache/ace/deployment/servlet/DeploymentServlet.java +++ b/org.apache.ace.deployment/src/org/apache/ace/deployment/servlet/DeploymentServlet.java @@ -38,6 +38,7 @@ import org.apache.ace.deployment.streamgenerator.StreamGenerator; import org.osgi.framework.ServiceReference; import org.osgi.service.log.LogService; +import org.osgi.service.useradmin.User; /** * The DeploymentServlet class provides in a list of versions available for a target and a stream of data containing the @@ -104,6 +105,16 @@ try { String[] pathElements = verifyAndGetPathElements(request.getPathInfo()); String targetID = pathElements[1]; + + User user = (User)request.getAttribute("org.apache.ace.authentication.user"); + if(user != null && user.getName().equals("admin")) { + //no-op + } else if(user != null && !user.getName().equals(targetID)) { + //the target does not correspond to the username + throw new AceRestException(HttpServletResponse.SC_UNAUTHORIZED, "Not authorised"); + } + + int numberOfElements = pathElements.length; if (numberOfElements == 3) { @@ -138,6 +149,14 @@ String targetID = pathElements[1]; String version = pathElements[3]; + User user = (User)request.getAttribute("org.apache.ace.authentication.user"); + if(user != null && user.getName().equals("admin")) { + //no-op + } else if(user != null && !user.getName().equals(targetID)) { + //the target does not correspond to the username + throw new AceRestException(HttpServletResponse.SC_UNAUTHORIZED, "Not authorised"); + } + response.setContentType(DP_MIMETYPE); long dpSize = estimateDeploymentPackageSize(request, targetID, version); diff --git a/org.apache.ace.log/src/org/apache/ace/log/server/servlet/LogServlet.java b/org.apache.ace.log/src/org/apache/ace/log/server/servlet/LogServlet.java index 74ad089..dd0a37f 100644 --- a/org.apache.ace.log/src/org/apache/ace/log/server/servlet/LogServlet.java +++ b/org.apache.ace.log/src/org/apache/ace/log/server/servlet/LogServlet.java @@ -36,6 +36,7 @@ import org.apache.ace.log.server.store.LogStore; import org.apache.ace.range.SortedRangeSet; import org.osgi.service.log.LogService; +import org.osgi.service.useradmin.User; /** * This class acts as a servlet and handles the log protocol. This means a number of requests will be handled: @@ -121,6 +122,15 @@ ServletOutputStream output = null; try { + + User user = (User)request.getAttribute("org.apache.ace.authentication.user"); + if(user != null && user.getName().equals("admin")) { + //no-op + } else if(user != null && !user.getName().equals(targetID)) { + //the target does not correspond to the username + sendError(response, HttpServletResponse.SC_UNAUTHORIZED, "Not authorised"); + } + output = response.getOutputStream(); if (QUERY.equals(path) && !handleQuery(targetID, logID, filter, output)) { sendError(response, HttpServletResponse.SC_BAD_REQUEST, "Unable to interpret query"); diff --git a/org.apache.ace.repository/src/org/apache/ace/repository/servlet/RepositoryServletBase.java b/org.apache.ace.repository/src/org/apache/ace/repository/servlet/RepositoryServletBase.java index 3a0c456..ee69b46 100644 --- a/org.apache.ace.repository/src/org/apache/ace/repository/servlet/RepositoryServletBase.java +++ b/org.apache.ace.repository/src/org/apache/ace/repository/servlet/RepositoryServletBase.java @@ -34,6 +34,7 @@ import org.osgi.framework.InvalidSyntaxException; import org.osgi.framework.ServiceReference; import org.osgi.service.log.LogService; +import org.osgi.service.useradmin.User; /** * Base class for the repository servlets. Both the repository and the repository replication servlets work in a similar @@ -92,8 +93,13 @@ String name = request.getParameter("name"); String filter = request.getParameter("filter"); String version = request.getParameter("version"); - - if (QUERY.equals(path)) { + + User user = (User)request.getAttribute("org.apache.ace.authentication.user"); + if(user != null && !user.getName().equals("admin")) { + + response.sendError(HttpServletResponse.SC_UNAUTHORIZED); + + } else if (QUERY.equals(path)) { // both repositories have a query method if (filter != null) { if ((name == null) && (customer == null)) { @@ -136,8 +142,13 @@ String customer = request.getParameter("customer"); String name = request.getParameter("name"); String version = request.getParameter("version"); + + User user = (User)request.getAttribute("org.apache.ace.authentication.user"); - if (getCommitCommand().equals(path)) { + if(user != null && !user.getName().equals("admin")) { + response.sendError(HttpServletResponse.SC_UNAUTHORIZED); + } else if (getCommitCommand().equals(path)) { + // and finally, both have a commit, only it's named differently if ((name != null) && (customer != null) && (version != null)) { handleCommit(customer, name, Long.parseLong(version), request.getInputStream(), response); -- ____________________________________ Jorge Martin Cuervo email <[email protected]> voice 0032 489 336 802 voice 0034 660 026 384 skype jorgemartincuervo ____________________________________
