From 683a0f73d578b5858e10f4527f652294ba0d0957 Mon Sep 17 00:00:00 2001
From: Brian Major <major.brian@gmail.com>
Date: Mon, 13 Jun 2016 11:23:57 -0700
Subject: [PATCH] s1885 - allow quotes around privileged user identities in
 web.xml

---
 .../nrc/cadc/ac/server/web/UserServlet.java   |  33 ++--
 .../cadc/ac/server/web/UserServletTest.java   | 141 +++++++++++++++++-
 2 files changed, 162 insertions(+), 12 deletions(-)

diff --git a/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/UserServlet.java b/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/UserServlet.java
index ef27f742..b63a25ec 100644
--- a/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/UserServlet.java
+++ b/cadcAccessControl-Server/src/ca/nrc/cadc/ac/server/web/UserServlet.java
@@ -75,6 +75,8 @@ import java.security.PrivilegedActionException;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 import javax.security.auth.Subject;
 import javax.security.auth.x500.X500Principal;
@@ -104,7 +106,7 @@ public class UserServlet extends HttpServlet
     private static final long serialVersionUID = 5289130885807305288L;
     private static final Logger log = Logger.getLogger(UserServlet.class);
 
-    private List<Subject> privilegedSubjects;
+    protected List<Subject> privilegedSubjects;
 
     private UserPersistence userPersistence;
 
@@ -121,24 +123,37 @@ public class UserServlet extends HttpServlet
             String httpUsers = config.getInitParameter(UserServlet.class.getName() + ".PrivilegedHttpPrincipals");
             log.debug("PrivilegedHttpUsers: " + httpUsers);
 
-            String[] x500List = new String[0];
-            String[] httpList = new String[0];
+            List<String> x500List = new ArrayList<String>();
+            List<String> httpList = new ArrayList<String>();
             if (x500Users != null && httpUsers != null)
             {
-                x500List = x500Users.split(" ");
-                httpList = httpUsers.split(" ");
+                Pattern pattern = Pattern.compile("([^\"]\\S*|\".+?\")\\s*");
+                Matcher x500Matcher = pattern.matcher(x500Users);
+                Matcher httpMatcher = pattern.matcher(httpUsers);
 
-                if (x500List.length != httpList.length)
+                while (x500Matcher.find())
+                {
+                    String next = x500Matcher.group(1);
+                    x500List.add(next.replace("\"", ""));
+                }
+
+                while (httpMatcher.find())
+                {
+                    String next = httpMatcher.group(1);
+                    httpList.add(next.replace("\"", ""));
+                }
+
+                if (x500List.size() != httpList.size())
                 {
                     throw new RuntimeException("Init exception: Lists of augment subject principals not equivalent in length");
                 }
 
                 privilegedSubjects = new ArrayList<Subject>(x500Users.length());
-                for (int i=0; i<x500List.length; i++)
+                for (int i=0; i<x500List.size(); i++)
                 {
                     Subject s = new Subject();
-                    s.getPrincipals().add(new X500Principal(x500List[i]));
-                    s.getPrincipals().add(new HttpPrincipal(httpList[i]));
+                    s.getPrincipals().add(new X500Principal(x500List.get(i)));
+                    s.getPrincipals().add(new HttpPrincipal(httpList.get(i)));
                     privilegedSubjects.add(s);
                 }
 
diff --git a/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/UserServletTest.java b/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/UserServletTest.java
index e8558a79..0d04f62a 100644
--- a/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/UserServletTest.java
+++ b/cadcAccessControl-Server/test/src/ca/nrc/cadc/ac/server/web/UserServletTest.java
@@ -1,16 +1,38 @@
 package ca.nrc.cadc.ac.server.web;
 
 
+import static org.easymock.EasyMock.createMock;
+import static org.easymock.EasyMock.expect;
+import static org.easymock.EasyMock.replay;
+import static org.easymock.EasyMock.verify;
+import static org.junit.Assert.assertEquals;
+
+import java.util.List;
+
+import javax.security.auth.Subject;
+import javax.servlet.ServletConfig;
 import javax.servlet.http.HttpServletRequest;
 
-import ca.nrc.cadc.ac.server.web.UserServlet;
+import junit.framework.Assert;
+
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+import org.easymock.EasyMock;
 import org.junit.Test;
-import static org.easymock.EasyMock.*;
-import static org.junit.Assert.*;
+
+import ca.nrc.cadc.db.StandaloneContextFactory;
+import ca.nrc.cadc.util.Log4jInit;
 
 
 public class UserServletTest
 {
+    private static final Logger log = Logger.getLogger(UserServletTest.class);
+
+    public UserServletTest()
+    {
+        Log4jInit.setLevel("ca.nrc.cadc.ac", Level.INFO);
+    }
+
     @Test
     public void getAcceptedContentTypeJSON() throws Exception
     {
@@ -45,4 +67,117 @@ public class UserServletTest
 
         verify(mockRequest);
     }
+
+    @Test
+    public void testPrivilegedUsers1()
+    {
+        try
+        {
+            StandaloneContextFactory.initJNDI();
+            UserServlet userServlet = new UserServlet();
+            ServletConfig config = EasyMock.createMock(ServletConfig.class);
+            EasyMock.expect(config.getInitParameter(
+                UserServlet.class.getName() + ".PrivilegedX500Principals")).
+                    andReturn("cn=user1,ou=cadc,o=hia,c=ca cn=user2,ou=cadc,o=hia,c=ca");
+            EasyMock.expect(config.getInitParameter(
+                UserServlet.class.getName() + ".PrivilegedHttpPrincipals")).
+                    andReturn("user1 user2");
+            EasyMock.replay(config);
+            userServlet.init(config);
+            List<Subject> subjects = userServlet.privilegedSubjects;
+            Assert.assertTrue(subjects.size() == 2);
+            EasyMock.verify(config);
+        }
+        catch (Exception e)
+        {
+            log.error("Unexpected", e);
+            Assert.fail(e.getMessage());
+        }
+    }
+
+    @Test
+    public void testPrivilegedUsers2()
+    {
+        try
+        {
+            StandaloneContextFactory.initJNDI();
+            UserServlet userServlet = new UserServlet();
+            ServletConfig config = EasyMock.createMock(ServletConfig.class);
+            EasyMock.expect(config.getInitParameter(
+                UserServlet.class.getName() + ".PrivilegedX500Principals")).
+                    andReturn("\"cn=user1, ou=cadc, o=hia,c=ca\" \"cn=user2, ou=cadc,o=hia,c=ca\"");
+            EasyMock.expect(config.getInitParameter(
+                UserServlet.class.getName() + ".PrivilegedHttpPrincipals")).
+                    andReturn("user1 \"user2\"");
+            EasyMock.replay(config);
+            userServlet.init(config);
+            List<Subject> subjects = userServlet.privilegedSubjects;
+            Assert.assertTrue(subjects.size() == 2);
+            EasyMock.verify(config);
+        }
+        catch (Exception e)
+        {
+            log.error("Unexpected", e);
+            Assert.fail(e.getMessage());
+        }
+    }
+
+    @Test
+    public void testPrivilegedUsers3()
+    {
+        try
+        {
+            StandaloneContextFactory.initJNDI();
+            UserServlet userServlet = new UserServlet();
+            ServletConfig config = EasyMock.createMock(ServletConfig.class);
+            EasyMock.expect(config.getInitParameter(
+                UserServlet.class.getName() + ".PrivilegedX500Principals")).
+                    andReturn("\"cn=user1, ou=cadc, o=hia,c=ca\"");
+            EasyMock.expect(config.getInitParameter(
+                UserServlet.class.getName() + ".PrivilegedHttpPrincipals")).
+                    andReturn("user1");
+            EasyMock.replay(config);
+            userServlet.init(config);
+            List<Subject> subjects = userServlet.privilegedSubjects;
+            Assert.assertTrue(subjects.size() == 1);
+            EasyMock.verify(config);
+        }
+        catch (Exception e)
+        {
+            log.error("Unexpected", e);
+            Assert.fail(e.getMessage());
+        }
+    }
+
+    @Test
+    public void testPrivilegedUsers4()
+    {
+        try
+        {
+            StandaloneContextFactory.initJNDI();
+            UserServlet userServlet = new UserServlet();
+            ServletConfig config = EasyMock.createMock(ServletConfig.class);
+            EasyMock.expect(config.getInitParameter(
+                UserServlet.class.getName() + ".PrivilegedX500Principals")).
+                    andReturn("\"cn=user1, ou=cadc, o=hia,c=ca\" \"cn=user2, ou=cadc,o=hia,c=ca\"");
+            EasyMock.expect(config.getInitParameter(
+                UserServlet.class.getName() + ".PrivilegedHttpPrincipals")).
+                    andReturn("user1 \"user2\" user3");
+            EasyMock.replay(config);
+            try
+            {
+                userServlet.init(config);
+                Assert.fail("Should have thrown an error");
+            }
+            catch (ExceptionInInitializerError e)
+            {
+                // expected
+            }
+        }
+        catch (Exception e)
+        {
+            log.error("Unexpected", e);
+            Assert.fail(e.getMessage());
+        }
+    }
 }
-- 
GitLab