From e76839662e41dce658aef43fdb1717e24af1cbfe Mon Sep 17 00:00:00 2001
From: Endi Sukma Dewata <edewata@redhat.com>
Date: Mon, 8 Oct 2012 14:50:26 -0500
Subject: [PATCH] Added REST account service.

A REST account service has been added to allow client to login
to establish a session and to logout to destroy the session. This
way multiple operations can be executed using the same session
without having to re-authenticate.

Ticket #357
---
 base/ca/shared/conf/acl.ldif                       |  1 +
 base/ca/shared/webapps/ca/WEB-INF/auth.properties  |  2 +
 base/ca/shared/webapps/ca/WEB-INF/web.xml          | 13 ++++++
 .../ca/CertificateAuthorityApplication.java        |  5 ++
 .../netscape/certsrv/account/AccountClient.java    | 54 ++++++++++++++++++++++
 .../netscape/certsrv/account/AccountResource.java  | 37 +++++++++++++++
 .../com/netscape/cms/authorization/AAclAuthz.java  |  4 +-
 .../cms/servlet/account/AccountService.java        | 50 ++++++++++++++++++++
 .../src/com/netscape/cmstools/cli/MainCLI.java     | 34 ++++++++++++--
 base/kra/shared/conf/acl.ldif                      |  1 +
 .../kra/shared/webapps/kra/WEB-INF/auth.properties |  2 +
 base/kra/shared/webapps/kra/WEB-INF/web.xml        | 13 ++++++
 .../kra/KeyRecoveryAuthorityApplication.java       |  5 ++
 13 files changed, 214 insertions(+), 7 deletions(-)
 create mode 100644 base/common/src/com/netscape/certsrv/account/AccountClient.java
 create mode 100644 base/common/src/com/netscape/certsrv/account/AccountResource.java
 create mode 100644 base/common/src/com/netscape/cms/servlet/account/AccountService.java

diff --git a/base/ca/shared/conf/acl.ldif b/base/ca/shared/conf/acl.ldif
index aec1447e56eafbc334f6b5d8fff662e2c976284e..4807a4dcf06df4245a665967fc010f813e0a0c16 100644
--- a/base/ca/shared/conf/acl.ldif
+++ b/base/ca/shared/conf/acl.ldif
@@ -51,6 +51,7 @@ resourceACLS: certServer.ca.connectorInfo:read,modify:allow (modify,read) group=
 resourceACLS: certServer.ca.registerUser:read,modify:allow (modify,read) group="Enterprise CA Administrators" || group="Enterprise KRA Administrators" || group="Enterprise RA Administrators" || group="Enterprise OCSP Administrators" || group="Enterprise TKS Administrators" || group="Enterprise TPS Administrators":Only Enterprise Administrators are allowed to register a new agent
 resourceACLS: certServer.clone.configuration:read,modify:allow (modify,read) group="Enterprise CA Administrators" || group="Enterprise KRA Administrators" || group="Enterprise RA Administrators" || group="Enterprise OCSP Administrators" || group="Enterprise TKS Administrators":Only Enterprise Administrators are allowed to clone the configuration.
 resourceACLS: certServer.admin.ocsp:read,modify:allow (modify,read) group="Enterprise OCSP Administrators":Only Enterprise Administrators are allowed to read or update the OCSP configuration.
+resourceACLS: certServer.ca.account:login,logout:allow (login,logout) user="anybody":Anybody can login and logout
 resourceACLS: certServer.ca.certs:execute:allow (execute) group="Certificate Manager Agents":Agents may execute cert operations
 resourceACLS: certServer.ca.groups:execute:allow (execute) group="Administrators":Admins may execute group operations
 resourceACLS: certServer.ca.users:execute:allow (execute) group="Administrators":Admins may execute user operations
diff --git a/base/ca/shared/webapps/ca/WEB-INF/auth.properties b/base/ca/shared/webapps/ca/WEB-INF/auth.properties
index ebb1c6c3fd6a80addf52575d3bbfda21c352312a..71f3d8052b1b37950ba91cc878f126bc16aa3e35 100644
--- a/base/ca/shared/webapps/ca/WEB-INF/auth.properties
+++ b/base/ca/shared/webapps/ca/WEB-INF/auth.properties
@@ -4,6 +4,8 @@
 # <Rest API URL> = <ACL Resource ID>,<ACL resource operation>
 # ex:      /ca/pki/users = certServer.ca.users,read
 
+/ca/rest/account/login = certServer.ca.account,login
+/ca/rest/account/logout = certServer.ca.account,logout
 /ca/rest/admin/users = certServer.ca.users,execute
 /ca/rest/admin/groups = certServer.ca.groups,execute
 /ca/rest/agent/certs = certServer.ca.certs,execute
diff --git a/base/ca/shared/webapps/ca/WEB-INF/web.xml b/base/ca/shared/webapps/ca/WEB-INF/web.xml
index c1b2738c833024a33f73e1ab5669340bc644f63b..32017ea2e173355ecd77cc180f908ae62f5bfe5a 100644
--- a/base/ca/shared/webapps/ca/WEB-INF/web.xml
+++ b/base/ca/shared/webapps/ca/WEB-INF/web.xml
@@ -2387,6 +2387,19 @@
 
     <security-constraint>
         <web-resource-collection>
+            <web-resource-name>Account Services</web-resource-name>
+            <url-pattern>/rest/account/*</url-pattern>
+        </web-resource-collection>
+        <auth-constraint>
+            <role-name>*</role-name>
+        </auth-constraint>
+        <user-data-constraint>
+            <transport-guarantee>CONFIDENTIAL</transport-guarantee>
+        </user-data-constraint>
+    </security-constraint>
+
+    <security-constraint>
+        <web-resource-collection>
             <web-resource-name>Admin Services</web-resource-name>
             <url-pattern>/rest/admin/*</url-pattern>
         </web-resource-collection>
diff --git a/base/ca/src/com/netscape/ca/CertificateAuthorityApplication.java b/base/ca/src/com/netscape/ca/CertificateAuthorityApplication.java
index bb6431907ee77c9ff7890b8c18fae95d96adf129..1f0cc62162231e67aead2dfb458b827f6b3e895c 100644
--- a/base/ca/src/com/netscape/ca/CertificateAuthorityApplication.java
+++ b/base/ca/src/com/netscape/ca/CertificateAuthorityApplication.java
@@ -6,6 +6,7 @@ import java.util.Set;
 import javax.ws.rs.core.Application;
 
 import com.netscape.certsrv.base.PKIException;
+import com.netscape.cms.servlet.account.AccountService;
 import com.netscape.cms.servlet.admin.GroupMemberService;
 import com.netscape.cms.servlet.admin.GroupService;
 import com.netscape.cms.servlet.admin.SystemCertService;
@@ -21,6 +22,10 @@ public class CertificateAuthorityApplication extends Application {
     private Set<Class<?>> classes = new HashSet<Class<?>>();
 
     public CertificateAuthorityApplication() {
+
+        // account
+        classes.add(AccountService.class);
+
         // installer
         classes.add(SystemConfigService.class);
 
diff --git a/base/common/src/com/netscape/certsrv/account/AccountClient.java b/base/common/src/com/netscape/certsrv/account/AccountClient.java
new file mode 100644
index 0000000000000000000000000000000000000000..e60112229446ea34bd398915d31a6d26c9250aac
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/account/AccountClient.java
@@ -0,0 +1,54 @@
+//--- BEGIN COPYRIGHT BLOCK ---
+//This program 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; version 2 of the License.
+//
+//This program 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 this program; if not, write to the Free Software Foundation, Inc.,
+//51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+//(C) 2012 Red Hat, Inc.
+//All rights reserved.
+//--- END COPYRIGHT BLOCK ---
+package com.netscape.certsrv.account;
+
+import java.net.URISyntaxException;
+
+import com.netscape.certsrv.client.ClientConfig;
+import com.netscape.certsrv.client.PKIClient;
+import com.netscape.certsrv.client.PKIConnection;
+
+/**
+ * @author Endi S. Dewata
+ */
+public class AccountClient extends PKIClient {
+
+    public AccountResource resource;
+
+    public AccountClient(PKIConnection connection) throws URISyntaxException {
+        super(connection);
+        init();
+    }
+
+    public AccountClient(ClientConfig config) throws URISyntaxException {
+        super(config);
+        init();
+    }
+
+    public void init() throws URISyntaxException {
+        resource = createProxy(AccountResource.class);
+    }
+
+    public void login() {
+        resource.login();
+    }
+
+    public void logout() {
+        resource.logout();
+    }
+}
diff --git a/base/common/src/com/netscape/certsrv/account/AccountResource.java b/base/common/src/com/netscape/certsrv/account/AccountResource.java
new file mode 100644
index 0000000000000000000000000000000000000000..ee40b24a8d5fdebbbb54147f3e06727e35d8c60d
--- /dev/null
+++ b/base/common/src/com/netscape/certsrv/account/AccountResource.java
@@ -0,0 +1,37 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program 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; version 2 of the License.
+//
+// This program 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 this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2012 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+package com.netscape.certsrv.account;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+
+/**
+ * @author Endi S. Dewata
+ */
+@Path("account")
+public interface AccountResource {
+
+    @GET
+    @Path("login")
+    public void login();
+
+    @GET
+    @Path("logout")
+    public void logout();
+}
diff --git a/base/common/src/com/netscape/cms/authorization/AAclAuthz.java b/base/common/src/com/netscape/cms/authorization/AAclAuthz.java
index b47956fb3bdd87832d0edd36e1ad574bc8adfe42..089cca9bea9f7cfcdac65f6023060109eb6b8d10 100644
--- a/base/common/src/com/netscape/cms/authorization/AAclAuthz.java
+++ b/base/common/src/com/netscape/cms/authorization/AAclAuthz.java
@@ -521,7 +521,7 @@ public abstract class AAclAuthz {
             log(ILogger.LL_INFO, infoMsg);
             return;
         } else {
-            Object[] params = new Object[2];
+            String[] params = new String[2];
 
             params[0] = name;
             params[1] = perm;
@@ -530,7 +530,7 @@ public abstract class AAclAuthz {
                     CMS.getLogMessage("AUTHZ_EVALUATOR_ACCESS_DENIED", name, perm));
 
             throw new EACLsException(CMS.getUserMessage("CMS_ACL_NO_PERMISSION",
-                        (String[]) params));
+                        params));
         }
     }
 
diff --git a/base/common/src/com/netscape/cms/servlet/account/AccountService.java b/base/common/src/com/netscape/cms/servlet/account/AccountService.java
new file mode 100644
index 0000000000000000000000000000000000000000..eb43233534cd39ffdbc14a89359884f2428562ae
--- /dev/null
+++ b/base/common/src/com/netscape/cms/servlet/account/AccountService.java
@@ -0,0 +1,50 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program 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; version 2 of the License.
+//
+// This program 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 this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2012 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+package com.netscape.cms.servlet.account;
+
+import java.security.Principal;
+
+import javax.servlet.http.HttpSession;
+
+import com.netscape.certsrv.account.AccountResource;
+import com.netscape.cms.servlet.base.PKIService;
+
+/**
+ * @author Endi S. Dewata
+ */
+public class AccountService extends PKIService implements AccountResource {
+
+    @Override
+    public void login() {
+        HttpSession session = servletRequest.getSession();
+        System.out.println("Creating session "+session.getId());
+
+        Principal principal = servletRequest.getUserPrincipal();
+        System.out.println("Principal: "+principal);
+    }
+
+    @Override
+    public void logout() {
+        HttpSession session = servletRequest.getSession(false);
+        if (session == null) return;
+
+        System.out.println("Destroying session "+session.getId());
+        session.invalidate();
+    }
+}
diff --git a/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java b/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java
index aac1d7aecc4c3695ff908924b97f1b76d859e81c..6e0c7d35b8e620c2c71cc61325f256c32b76d750 100644
--- a/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java
+++ b/base/java-tools/src/com/netscape/cmstools/cli/MainCLI.java
@@ -30,6 +30,7 @@ import org.mozilla.jss.crypto.CryptoToken;
 import org.mozilla.jss.util.IncorrectPasswordException;
 import org.mozilla.jss.util.Password;
 
+import com.netscape.certsrv.account.AccountClient;
 import com.netscape.certsrv.client.ClientConfig;
 import com.netscape.certsrv.client.PKIConnection;
 import com.netscape.cmstools.cert.CertCLI;
@@ -44,6 +45,7 @@ public class MainCLI extends CLI {
     public ClientConfig config = new ClientConfig();
 
     public PKIConnection connection;
+    public AccountClient accountClient;
 
     public MainCLI() throws Exception {
         super("pki", "PKI command-line interface");
@@ -165,6 +167,8 @@ public class MainCLI extends CLI {
     public void connect() throws Exception {
         connection = new PKIConnection(config);
         connection.setVerbose(verbose);
+
+        accountClient = new AccountClient(connection);
     }
 
     public void execute(String[] args) throws Exception {
@@ -251,13 +255,12 @@ public class MainCLI extends CLI {
             return;
         }
 
-        // execute module command
-        try {
-            if (verbose) System.out.println("Server URI: "+config.getServerURI());
+        if (verbose) System.out.println("Server URI: "+config.getServerURI());
 
-            // initialize certificate database if specified
-            if (config.getCertDatabase() != null) {
+        // initialize certificate database if specified
+        if (config.getCertDatabase() != null) {
 
+            try {
                 if (verbose) System.out.println("Certificate database: "+config.getCertDatabase());
                 CryptoManager.initialize(config.getCertDatabase());
 
@@ -272,10 +275,28 @@ public class MainCLI extends CLI {
                         throw new Error("Incorrect certificate database password.", e);
                     }
                 }
+
+            } catch (Throwable t) {
+                if (verbose) {
+                    t.printStackTrace(System.err);
+                } else {
+                    System.err.println(t.getClass().getSimpleName()+": "+t.getMessage());
+                }
+                System.exit(1);
             }
+        }
 
+        // execute command
+        boolean loggedIn = false;
+        try {
             connect();
 
+            // login
+            if (config.getCertDatabase() != null || config.getUsername() != null) {
+                accountClient.login();
+                loggedIn = true;
+            }
+
             // execute module command
             module.execute(moduleArgs);
 
@@ -286,6 +307,9 @@ public class MainCLI extends CLI {
                 System.err.println(t.getClass().getSimpleName()+": "+t.getMessage());
             }
             System.exit(1);
+
+        } finally {
+            if (loggedIn) accountClient.logout();
         }
     }
 
diff --git a/base/kra/shared/conf/acl.ldif b/base/kra/shared/conf/acl.ldif
index ea70ffd21544a5d47793a445617fbec233aaaf0d..c3eae7596cc876c59cbf98459439f8328d5095fe 100644
--- a/base/kra/shared/conf/acl.ldif
+++ b/base/kra/shared/conf/acl.ldif
@@ -30,6 +30,7 @@ resourceACLS: certServer.kra.TokenKeyRecovery:submit:allow (submit) group="Data
 resourceACLS: certServer.kra.registerUser:read,modify:allow (modify,read) group="Enterprise CA Administrators" || group="Enterprise KRA Administrators" || group="Enterprise OCSP Administrators" || group="Enterprise TKS Administrators" || group="Enterprise TPS Administrators":Only Enterprise Administrators are allowed to register a new agent
 resourceACLS: certServer.kra.getTransportCert:read:allow (read) group="Enterprise CA Administrators" || group="Enterprise KRA Administrators" || group="Enterprise OCSP Administrators" || group="Enterprise TKS Administrators" || group="Enterprise TPS Administrators":Only Enterprise Administrators are allowed to retrieve the transport cert
 resourceACLS: certServer.clone.configuration:read,modify:allow (modify,read) group="Enterprise CA Administrators" || group="Enterprise KRA Administrators" || group="Enterprise OCSP Administrators" || group="Enterprise TKS Administrators":Only Enterprise Administrators are allowed to clone the configuration.
+resourceACLS: certServer.kra.account:login,logout:allow (login,logout) user="anybody":Anybody can login and logout
 resourceACLS: certServer.kra.groups:execute:allow (execute) group="Administrators":Admins may execute group operations
 resourceACLS: certServer.kra.keys:execute:allow (execute) group="Data Recovery Manager Agents":Agents may execute key operations
 resourceACLS: certServer.kra.keyrequests:execute:allow (execute) group="Data Recovery Manager Agents":Agents may execute key request operations
diff --git a/base/kra/shared/webapps/kra/WEB-INF/auth.properties b/base/kra/shared/webapps/kra/WEB-INF/auth.properties
index d2ba3075e15decadd1e2bdc43bcb6e82fcbaf05d..0a529f060dc34dd9dde1b4a9570068ce8dd08286 100644
--- a/base/kra/shared/webapps/kra/WEB-INF/auth.properties
+++ b/base/kra/shared/webapps/kra/WEB-INF/auth.properties
@@ -4,6 +4,8 @@
 # <Rest API URL> = <ACL Resource ID>,<ACL resource operation>
 # ex:      /kra/pki/key/retrieve = certServer.kra.pki.key.retrieve,execute
 
+/kra/rest/account/login = certServer.kra.account,login
+/kra/rest/account/logout = certServer.kra.account,logout
 /kra/rest/admin/users = certServer.kra.users,execute
 /kra/rest/admin/groups = certServer.kra.groups,execute
 /kra/rest/agent/keys = certServer.kra.keys,execute
diff --git a/base/kra/shared/webapps/kra/WEB-INF/web.xml b/base/kra/shared/webapps/kra/WEB-INF/web.xml
index 1a5b6aaf549aac593dffaa4221fd7327c3f9a6f1..03def86c7da0a71bf71f9dfbf7780eed451c879a 100644
--- a/base/kra/shared/webapps/kra/WEB-INF/web.xml
+++ b/base/kra/shared/webapps/kra/WEB-INF/web.xml
@@ -954,6 +954,19 @@
         <session-timeout>30</session-timeout>
    </session-config>
 
+    <security-constraint>
+        <web-resource-collection>
+            <web-resource-name>Account Services</web-resource-name>
+            <url-pattern>/rest/account/*</url-pattern>
+        </web-resource-collection>
+        <auth-constraint>
+            <role-name>*</role-name>
+        </auth-constraint>
+        <user-data-constraint>
+            <transport-guarantee>CONFIDENTIAL</transport-guarantee>
+        </user-data-constraint>
+    </security-constraint>
+
     <!--
     <security-constraint>
         <web-resource-collection>
diff --git a/base/kra/src/com/netscape/kra/KeyRecoveryAuthorityApplication.java b/base/kra/src/com/netscape/kra/KeyRecoveryAuthorityApplication.java
index f972fe4b5d780410ff327544a0f797b5626a93f6..280ffe1dc1fbe93219e1269efc440a41d019d29d 100644
--- a/base/kra/src/com/netscape/kra/KeyRecoveryAuthorityApplication.java
+++ b/base/kra/src/com/netscape/kra/KeyRecoveryAuthorityApplication.java
@@ -6,6 +6,7 @@ import java.util.Set;
 import javax.ws.rs.core.Application;
 
 import com.netscape.certsrv.base.PKIException;
+import com.netscape.cms.servlet.account.AccountService;
 import com.netscape.cms.servlet.admin.GroupMemberService;
 import com.netscape.cms.servlet.admin.GroupService;
 import com.netscape.cms.servlet.admin.SystemCertService;
@@ -21,6 +22,10 @@ public class KeyRecoveryAuthorityApplication extends Application {
     private Set<Class<?>> classes = new HashSet<Class<?>>();
 
     public KeyRecoveryAuthorityApplication() {
+
+        // account
+        classes.add(AccountService.class);
+
         // installer
         classes.add(SystemConfigService.class);
 
-- 
1.7.11.4

