summaryrefslogtreecommitdiffstats
path: root/base/tps-tomcat/src/org/dogtagpki
diff options
context:
space:
mode:
Diffstat (limited to 'base/tps-tomcat/src/org/dogtagpki')
-rw-r--r--base/tps-tomcat/src/org/dogtagpki/tps/TPSConnection.java98
-rw-r--r--base/tps-tomcat/src/org/dogtagpki/tps/TPSMessage.java101
-rw-r--r--base/tps-tomcat/src/org/dogtagpki/tps/server/TPSApplication.java84
-rw-r--r--base/tps-tomcat/src/org/dogtagpki/tps/server/TPSServlet.java61
-rw-r--r--base/tps-tomcat/src/org/dogtagpki/tps/server/TPSSubsystem.java115
-rw-r--r--base/tps-tomcat/src/org/dogtagpki/tps/token/TokenDatabase.java76
-rw-r--r--base/tps-tomcat/src/org/dogtagpki/tps/token/TokenRecord.java188
-rw-r--r--base/tps-tomcat/src/org/dogtagpki/tps/token/TokenService.java245
8 files changed, 968 insertions, 0 deletions
diff --git a/base/tps-tomcat/src/org/dogtagpki/tps/TPSConnection.java b/base/tps-tomcat/src/org/dogtagpki/tps/TPSConnection.java
new file mode 100644
index 000000000..cd62ff530
--- /dev/null
+++ b/base/tps-tomcat/src/org/dogtagpki/tps/TPSConnection.java
@@ -0,0 +1,98 @@
+// --- 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) 2013 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package org.dogtagpki.tps;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+
+/**
+ * @author Endi S. Dewata <edewata@redhat.com>
+ */
+public class TPSConnection {
+
+ public InputStream in;
+ public PrintStream out;
+ public boolean chunked;
+
+ public TPSConnection(InputStream in, OutputStream out) {
+ this(in, out, false);
+ }
+
+ public TPSConnection(InputStream in, OutputStream out, boolean chunked) {
+ this.in = in;
+ this.out = new PrintStream(out);
+ this.chunked = chunked;
+ }
+
+ public TPSMessage read() throws IOException {
+
+ StringBuilder sb = new StringBuilder();
+ int b;
+
+ // read the first parameter
+ while ((b = in.read()) >= 0) {
+ char c = (char)b;
+ if (c == '&') break;
+ sb.append(c);
+ }
+
+ if (b < 0) throw new IOException("Unexpected end of stream");
+
+ // parse message size
+ String nvp = sb.toString();
+ String[] s = nvp.split("=");
+ int size = Integer.parseInt(s[1]);
+
+ sb.append('&');
+
+ // read the rest of message
+ for (int i=0; i<size; i++) {
+
+ b = in.read();
+ if (b < 0) throw new IOException("Unexpected end of stream");
+
+ char c = (char)b;
+ sb.append(c);
+ }
+
+ // parse the entire message
+ return new TPSMessage(sb.toString());
+ }
+
+ public void write(TPSMessage message) throws IOException {
+ String s = message.encode();
+
+ if (chunked) {
+ // send message length + EOL
+ out.print(Integer.toHexString(s.length()));
+ out.print("\r\n");
+ }
+
+ // send message
+ out.print(s);
+
+ if (chunked) {
+ // send EOL
+ out.print("\r\n");
+ }
+
+ out.flush();
+ }
+}
diff --git a/base/tps-tomcat/src/org/dogtagpki/tps/TPSMessage.java b/base/tps-tomcat/src/org/dogtagpki/tps/TPSMessage.java
new file mode 100644
index 000000000..522a0f408
--- /dev/null
+++ b/base/tps-tomcat/src/org/dogtagpki/tps/TPSMessage.java
@@ -0,0 +1,101 @@
+// --- 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) 2013 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package org.dogtagpki.tps;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * @author Endi S. Dewata <edewata@redhat.com>
+ */
+public class TPSMessage {
+
+ Map<String, String> map = new LinkedHashMap<String, String>();
+
+ public TPSMessage() {
+ }
+
+ public TPSMessage(String message) {
+ decode(message);
+ }
+
+ public TPSMessage(Map<String, String> map) {
+ this.map.putAll(map);
+ }
+
+ public void put(String key, String value) {
+ map.put(key, value);
+ }
+
+ public void put(String key, Integer value) {
+ map.put(key, value.toString());
+ }
+
+ public void put(String key, byte[] bytes) {
+ StringBuilder sb = new StringBuilder();
+
+ for (byte b : bytes) {
+ sb.append("%");
+ sb.append(String.format("%02X", b));
+ }
+
+ map.put(key, sb.toString());
+ }
+
+ public void decode(String message) {
+
+ for (String nvp : message.split("&")) {
+ String[] s = nvp.split("=");
+
+ String key = s[0];
+ String value = s[1];
+
+ // skip message size
+ if (key.equals("s")) continue;
+
+ map.put(key, value);
+ }
+ }
+
+ public String encode() {
+
+ StringBuilder sb = new StringBuilder();
+
+ // encode message type
+ String type = map.get("msg_type");
+ sb.append("msg_type=" + type);
+
+ // encode other parameters
+ for (String key : map.keySet()) {
+
+ if (key.equals("msg_type")) continue;
+
+ String value = map.get(key);
+ sb.append("&" + key + "=" + value);
+ }
+
+ String message = sb.toString();
+
+ // encode message_size
+ return "s=" + message.length() + "&" + message;
+ }
+
+ public String toString() {
+ return map.toString();
+ }
+}
diff --git a/base/tps-tomcat/src/org/dogtagpki/tps/server/TPSApplication.java b/base/tps-tomcat/src/org/dogtagpki/tps/server/TPSApplication.java
new file mode 100644
index 000000000..2f2b2a63a
--- /dev/null
+++ b/base/tps-tomcat/src/org/dogtagpki/tps/server/TPSApplication.java
@@ -0,0 +1,84 @@
+// --- 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) 2013 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package org.dogtagpki.tps.server;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.ws.rs.core.Application;
+
+import org.dogtagpki.tps.token.TokenService;
+
+import com.netscape.certsrv.acls.ACLInterceptor;
+import com.netscape.certsrv.authentication.AuthMethodInterceptor;
+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;
+import com.netscape.cms.servlet.admin.UserCertService;
+import com.netscape.cms.servlet.admin.UserMembershipService;
+import com.netscape.cms.servlet.admin.UserService;
+import com.netscape.cms.servlet.csadmin.SystemConfigService;
+
+/**
+ * @author Endi S. Dewata <edewata@redhat.com>
+ */
+public class TPSApplication extends Application {
+
+ private Set<Object> singletons = new HashSet<Object>();
+ private Set<Class<?>> classes = new HashSet<Class<?>>();
+
+ public TPSApplication() {
+
+ // account
+ classes.add(AccountService.class);
+
+ // installer
+ classes.add(SystemConfigService.class);
+
+ // user and group management
+ classes.add(GroupMemberService.class);
+ classes.add(GroupService.class);
+ classes.add(UserCertService.class);
+ classes.add(UserMembershipService.class);
+ classes.add(UserService.class);
+
+ // system certs
+ classes.add(SystemCertService.class);
+
+ // tokens
+ classes.add(TokenService.class);
+
+ // exception mapper
+ classes.add(PKIException.Mapper.class);
+
+ // interceptors
+ singletons.add(new AuthMethodInterceptor());
+ singletons.add(new ACLInterceptor());
+ }
+
+ public Set<Class<?>> getClasses() {
+ return classes;
+ }
+
+ public Set<Object> getSingletons() {
+ return singletons;
+ }
+
+}
diff --git a/base/tps-tomcat/src/org/dogtagpki/tps/server/TPSServlet.java b/base/tps-tomcat/src/org/dogtagpki/tps/server/TPSServlet.java
new file mode 100644
index 000000000..78e6df4f8
--- /dev/null
+++ b/base/tps-tomcat/src/org/dogtagpki/tps/server/TPSServlet.java
@@ -0,0 +1,61 @@
+// --- 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) 2013 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package org.dogtagpki.tps.server;
+
+import java.io.IOException;
+
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.dogtagpki.tps.TPSConnection;
+import org.dogtagpki.tps.TPSMessage;
+
+/**
+ * @author Endi S. Dewata <edewata@redhat.com>
+ */
+public class TPSServlet extends HttpServlet {
+
+ private static final long serialVersionUID = -1092227495262381074L;
+
+ public void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
+
+ response.setHeader("Transfer-Encoding", "chunked");
+
+ TPSConnection con = new TPSConnection(
+ request.getInputStream(), response.getOutputStream(), true);
+
+ TPSMessage message = con.read();
+ System.out.println("Receive: " + message);
+
+ message = new TPSMessage();
+ message.put("msg_type", 9);
+ message.put("pdu_size", 12);
+ message.put("pdu_data", new byte[] {
+ (byte)0x00, (byte)0xA4, (byte)0x04, (byte)0x00,
+ (byte)0x07, (byte)0xA0, (byte)0x00, (byte)0x00,
+ (byte)0x00, (byte)0x03, (byte)0x00, (byte)0x00
+ });
+
+ System.out.println("Send: " + message);
+ con.write(message);
+
+ message = con.read();
+ System.out.println("Receive: " + message);
+ }
+}
diff --git a/base/tps-tomcat/src/org/dogtagpki/tps/server/TPSSubsystem.java b/base/tps-tomcat/src/org/dogtagpki/tps/server/TPSSubsystem.java
new file mode 100644
index 000000000..92017812c
--- /dev/null
+++ b/base/tps-tomcat/src/org/dogtagpki/tps/server/TPSSubsystem.java
@@ -0,0 +1,115 @@
+// --- 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) 2013 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package org.dogtagpki.tps.server;
+
+import org.dogtagpki.tps.token.TokenDatabase;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.authority.IAuthority;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.logging.ILogger;
+import com.netscape.certsrv.request.IRequestListener;
+import com.netscape.certsrv.request.IRequestQueue;
+
+/**
+ * @author Endi S. Dewata <edewata@redhat.com>
+ */
+public class TPSSubsystem implements IAuthority, ISubsystem {
+
+ public final static TPSSubsystem INSTANCE = new TPSSubsystem();
+
+ public ILogger logger = CMS.getLogger();
+
+ public String id;
+ public String nickname;
+ public ISubsystem owner;
+ public IConfigStore config;
+
+ public TokenDatabase tokenDatabase = new TokenDatabase();
+
+ public static TPSSubsystem getInstance() {
+ return INSTANCE;
+ }
+
+ @Override
+ public String getId() {
+ return id;
+ }
+
+ @Override
+ public void setId(String id) throws EBaseException {
+ this.id = id;
+ }
+
+ @Override
+ public void init(ISubsystem owner, IConfigStore config) throws EBaseException {
+ this.owner = owner;
+ this.config = config;
+ }
+
+ @Override
+ public void startup() throws EBaseException {
+ }
+
+ @Override
+ public void shutdown() {
+ }
+
+ @Override
+ public IConfigStore getConfigStore() {
+ return config;
+ }
+
+ @Override
+ public IRequestQueue getRequestQueue() {
+ return null;
+ }
+
+ @Override
+ public void registerRequestListener(IRequestListener listener) {
+ }
+
+ @Override
+ public void registerPendingListener(IRequestListener listener) {
+ }
+
+ @Override
+ public void log(int level, String msg) {
+ logger.log(ILogger.EV_SYSTEM, ILogger.S_TPS, level, msg);
+ }
+
+ @Override
+ public String getNickname() {
+ return nickname;
+ }
+
+ public void setNickname(String nickname) {
+ this.nickname = nickname;
+ }
+
+ @Override
+ public String getOfficialName() {
+ return "tps";
+ }
+
+ public TokenDatabase getTokenDatabase() {
+ return tokenDatabase;
+ }
+}
diff --git a/base/tps-tomcat/src/org/dogtagpki/tps/token/TokenDatabase.java b/base/tps-tomcat/src/org/dogtagpki/tps/token/TokenDatabase.java
new file mode 100644
index 000000000..3db76649f
--- /dev/null
+++ b/base/tps-tomcat/src/org/dogtagpki/tps/token/TokenDatabase.java
@@ -0,0 +1,76 @@
+// --- 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) 2013 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+package org.dogtagpki.tps.token;
+
+import java.util.Collection;
+import java.util.Date;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * This class implements in-memory token database. In the future this
+ * will be replaced with LDAP database.
+ *
+ * @author Endi S. Dewata
+ */
+public class TokenDatabase {
+
+ public final static int DEFAULT_SIZE = 20;
+
+ Map<String, TokenRecord> tokens = new LinkedHashMap<String, TokenRecord>();
+
+ public Collection<TokenRecord> getTokens() throws Exception {
+ return tokens.values();
+ }
+
+ public TokenRecord getToken(String tokenID) throws Exception {
+ if (!tokens.containsKey(tokenID)) {
+ throw new Exception("Token "+ tokenID + " does not exist.");
+ }
+ return tokens.get(tokenID);
+ }
+
+ public void addToken(TokenRecord tokenRecord) throws Exception {
+ if (tokens.containsKey(tokenRecord.getID())) {
+ throw new Exception("Token "+ tokenRecord.getID() + " already exists.");
+ }
+
+ tokenRecord.setStatus("ENABLED");
+ tokenRecord.setCreateTimestamp(new Date());
+
+ tokens.put(tokenRecord.getID(), tokenRecord);
+ }
+
+ public void updateToken(String tokenID, TokenRecord tokenRecord) throws Exception {
+ if (!tokens.containsKey(tokenRecord.getID())) {
+ throw new Exception("Token "+ tokenRecord.getID() + " does not exist.");
+ }
+
+ tokenRecord.setModifyTimestamp(new Date());
+
+ tokens.put(tokenRecord.getID(), tokenRecord);
+ }
+
+ public void removeToken(String tokenID) throws Exception {
+ if (!tokens.containsKey(tokenID)) {
+ throw new Exception("Token "+ tokenID + " does not exist.");
+ }
+ tokens.remove(tokenID);
+ }
+}
diff --git a/base/tps-tomcat/src/org/dogtagpki/tps/token/TokenRecord.java b/base/tps-tomcat/src/org/dogtagpki/tps/token/TokenRecord.java
new file mode 100644
index 000000000..1f9d9caf5
--- /dev/null
+++ b/base/tps-tomcat/src/org/dogtagpki/tps/token/TokenRecord.java
@@ -0,0 +1,188 @@
+// --- 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) 2013 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+package org.dogtagpki.tps.token;
+
+import java.util.Date;
+
+import com.netscape.certsrv.token.TokenData;
+
+/**
+ * @author Endi S. Dewata
+ */
+public class TokenRecord {
+
+ String id;
+ String userID;
+ String status;
+ String reason;
+ String appletID;
+ String keyInfo;
+ Date createTimestamp;
+ Date modifyTimestamp;
+
+ public String getID() {
+ return id;
+ }
+
+ public void setID(String id) {
+ this.id = id;
+ }
+
+ public String getUserID() {
+ return userID;
+ }
+
+ public void setUserID(String userID) {
+ this.userID = userID;
+ }
+
+ public String getStatus() {
+ return status;
+ }
+
+ public void setStatus(String status) {
+ this.status = status;
+ }
+
+ public String getReason() {
+ return reason;
+ }
+
+ public void setReason(String reason) {
+ this.reason = reason;
+ }
+
+ public String getAppletID() {
+ return appletID;
+ }
+
+ public void setAppletID(String appletID) {
+ this.appletID = appletID;
+ }
+
+ public String getKeyInfo() {
+ return keyInfo;
+ }
+
+ public void setKeyInfo(String keyInfo) {
+ this.keyInfo = keyInfo;
+ }
+
+ public Date getCreateTimestamp() {
+ return createTimestamp;
+ }
+
+ public void setCreateTimestamp(Date createTimestamp) {
+ this.createTimestamp = createTimestamp;
+ }
+
+ public Date getModifyTimestamp() {
+ return modifyTimestamp;
+ }
+
+ public void setModifyTimestamp(Date modifyTimestamp) {
+ this.modifyTimestamp = modifyTimestamp;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((appletID == null) ? 0 : appletID.hashCode());
+ result = prime * result + ((createTimestamp == null) ? 0 : createTimestamp.hashCode());
+ result = prime * result + ((id == null) ? 0 : id.hashCode());
+ result = prime * result + ((keyInfo == null) ? 0 : keyInfo.hashCode());
+ result = prime * result + ((modifyTimestamp == null) ? 0 : modifyTimestamp.hashCode());
+ result = prime * result + ((reason == null) ? 0 : reason.hashCode());
+ result = prime * result + ((status == null) ? 0 : status.hashCode());
+ result = prime * result + ((userID == null) ? 0 : userID.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ TokenRecord other = (TokenRecord) obj;
+ if (appletID == null) {
+ if (other.appletID != null)
+ return false;
+ } else if (!appletID.equals(other.appletID))
+ return false;
+ if (createTimestamp == null) {
+ if (other.createTimestamp != null)
+ return false;
+ } else if (!createTimestamp.equals(other.createTimestamp))
+ return false;
+ if (id == null) {
+ if (other.id != null)
+ return false;
+ } else if (!id.equals(other.id))
+ return false;
+ if (keyInfo == null) {
+ if (other.keyInfo != null)
+ return false;
+ } else if (!keyInfo.equals(other.keyInfo))
+ return false;
+ if (modifyTimestamp == null) {
+ if (other.modifyTimestamp != null)
+ return false;
+ } else if (!modifyTimestamp.equals(other.modifyTimestamp))
+ return false;
+ if (reason == null) {
+ if (other.reason != null)
+ return false;
+ } else if (!reason.equals(other.reason))
+ return false;
+ if (status == null) {
+ if (other.status != null)
+ return false;
+ } else if (!status.equals(other.status))
+ return false;
+ if (userID == null) {
+ if (other.userID != null)
+ return false;
+ } else if (!userID.equals(other.userID))
+ return false;
+ return true;
+ }
+
+ public static void main(String args[]) throws Exception {
+
+ TokenData before = new TokenData();
+ before.setID("token1");
+ before.setUserID("user1");
+ before.setStatus("revoked");
+ before.setReason("lost");
+ before.setAppletID("APPLET1234");
+ before.setKeyInfo("key info");
+ before.setCreateTimestamp(new Date());
+ before.setModifyTimestamp(new Date());
+
+ String string = before.toString();
+ System.out.println(string);
+
+ TokenData after = TokenData.valueOf(string);
+ System.out.println(before.equals(after));
+ }
+}
diff --git a/base/tps-tomcat/src/org/dogtagpki/tps/token/TokenService.java b/base/tps-tomcat/src/org/dogtagpki/tps/token/TokenService.java
new file mode 100644
index 000000000..bc8b35d59
--- /dev/null
+++ b/base/tps-tomcat/src/org/dogtagpki/tps/token/TokenService.java
@@ -0,0 +1,245 @@
+// --- 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) 2013 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+
+package org.dogtagpki.tps.token;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URLEncoder;
+import java.util.Iterator;
+
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+
+import org.dogtagpki.tps.server.TPSSubsystem;
+import org.jboss.resteasy.plugins.providers.atom.Link;
+
+import com.netscape.certsrv.base.PKIException;
+import com.netscape.certsrv.token.TokenCollection;
+import com.netscape.certsrv.token.TokenData;
+import com.netscape.certsrv.token.TokenModifyRequest;
+import com.netscape.certsrv.token.TokenResource;
+import com.netscape.cms.servlet.base.PKIService;
+
+/**
+ * @author Endi S. Dewata
+ */
+public class TokenService extends PKIService implements TokenResource {
+
+ public final static int DEFAULT_SIZE = 20;
+
+ public TokenService() {
+ System.out.println("TokenService.<init>()");
+ }
+
+ public TokenData createTokenData(TokenRecord tokenRecord) {
+
+ TokenData tokenData = new TokenData();
+ tokenData.setID(tokenRecord.getID());
+ tokenData.setUserID(tokenRecord.getUserID());
+ tokenData.setStatus(tokenRecord.getStatus());
+ tokenData.setReason(tokenRecord.getReason());
+ tokenData.setAppletID(tokenRecord.getAppletID());
+ tokenData.setKeyInfo(tokenRecord.getKeyInfo());
+ tokenData.setCreateTimestamp(tokenRecord.getCreateTimestamp());
+ tokenData.setModifyTimestamp(tokenRecord.getModifyTimestamp());
+
+ String tokenID = tokenRecord.getID();
+ try {
+ tokenID = URLEncoder.encode(tokenID, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ e.printStackTrace();
+ throw new PKIException(e.getMessage());
+ }
+
+ URI uri = uriInfo.getBaseUriBuilder().path(TokenResource.class).path("{tokenID}").build(tokenID);
+ tokenData.setLink(new Link("self", uri));
+
+ return tokenData;
+ }
+
+ public TokenRecord createTokenRecord(TokenData tokenData) {
+
+ TokenRecord tokenRecord = new TokenRecord();
+ tokenRecord.setID(tokenData.getID());
+ tokenRecord.setUserID(tokenData.getUserID());
+ tokenRecord.setStatus(tokenData.getStatus());
+ tokenRecord.setReason(tokenData.getReason());
+ tokenRecord.setAppletID(tokenData.getAppletID());
+ tokenRecord.setKeyInfo(tokenData.getKeyInfo());
+ tokenRecord.setCreateTimestamp(tokenData.getCreateTimestamp());
+ tokenRecord.setModifyTimestamp(tokenData.getModifyTimestamp());
+
+ return tokenRecord;
+ }
+
+ @Override
+ public TokenCollection findTokens(Integer start, Integer size) {
+
+ System.out.println("TokenService.findTokens()");
+
+ try {
+ start = start == null ? 0 : start;
+ size = size == null ? DEFAULT_SIZE : size;
+
+ TPSSubsystem subsystem = TPSSubsystem.getInstance();
+ TokenDatabase database = subsystem.getTokenDatabase();
+
+ Iterator<TokenRecord> tokens = database.getTokens().iterator();
+
+ TokenCollection response = new TokenCollection();
+
+ int i = 0;
+
+ // skip to the start of the page
+ for ( ; i<start && tokens.hasNext(); i++) tokens.next();
+
+ // return entries up to the page size
+ for ( ; i<start+size && tokens.hasNext(); i++) {
+ response.addToken(createTokenData(tokens.next()));
+ }
+
+ // count the total entries
+ for ( ; tokens.hasNext(); i++) tokens.next();
+
+ if (start > 0) {
+ URI uri = uriInfo.getRequestUriBuilder().replaceQueryParam("start", Math.max(start-size, 0)).build();
+ response.addLink(new Link("prev", uri));
+ }
+
+ if (start+size < i) {
+ URI uri = uriInfo.getRequestUriBuilder().replaceQueryParam("start", start+size).build();
+ response.addLink(new Link("next", uri));
+ }
+
+ return response;
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new PKIException(e.getMessage());
+ }
+ }
+
+ @Override
+ public TokenData getToken(String tokenID) {
+
+ System.out.println("TokenService.getToken(\"" + tokenID + "\")");
+
+ try {
+ TPSSubsystem subsystem = TPSSubsystem.getInstance();
+ TokenDatabase database = subsystem.getTokenDatabase();
+
+ return createTokenData(database.getToken(tokenID));
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new PKIException(e.getMessage());
+ }
+ }
+
+ @Override
+ public Response addToken(TokenData tokenData) {
+
+ System.out.println("TokenService.addToken(\"" + tokenData.getID() + "\")");
+
+ try {
+ TPSSubsystem subsystem = TPSSubsystem.getInstance();
+ TokenDatabase database = subsystem.getTokenDatabase();
+
+ database.addToken(createTokenRecord(tokenData));
+ tokenData = createTokenData(database.getToken(tokenData.getID()));
+
+ return Response
+ .created(tokenData.getLink().getHref())
+ .entity(tokenData)
+ .type(MediaType.APPLICATION_XML)
+ .build();
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new PKIException(e.getMessage());
+ }
+ }
+
+ @Override
+ public Response updateToken(String tokenID, TokenData tokenData) {
+
+ System.out.println("TokenService.updateToken(\"" + tokenID + "\")");
+
+ try {
+ TPSSubsystem subsystem = TPSSubsystem.getInstance();
+ TokenDatabase database = subsystem.getTokenDatabase();
+
+ TokenRecord tokenRecord = database.getToken(tokenID);
+ tokenRecord.setUserID(tokenData.getUserID());
+ database.updateToken(tokenData.getID(), tokenRecord);
+
+ tokenData = createTokenData(database.getToken(tokenID));
+
+ return Response
+ .ok(tokenData)
+ .type(MediaType.APPLICATION_XML)
+ .build();
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new PKIException(e.getMessage());
+ }
+ }
+
+ @Override
+ public Response modifyToken(String tokenID, TokenModifyRequest request) {
+
+ System.out.println("TokenService.modifyToken(\"" + tokenID + "\", request");
+
+ try {
+ TPSSubsystem subsystem = TPSSubsystem.getInstance();
+ TokenDatabase database = subsystem.getTokenDatabase();
+
+ TokenRecord tokenRecord = database.getToken(tokenID);
+ // TODO: perform modification
+
+ TokenData tokenData = createTokenData(tokenRecord);
+
+ return Response
+ .ok(tokenData)
+ .type(MediaType.APPLICATION_XML)
+ .build();
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new PKIException(e.getMessage());
+ }
+ }
+
+ @Override
+ public void removeToken(String tokenID) {
+
+ System.out.println("TokenService.removeToken(\"" + tokenID + "\")");
+
+ try {
+ TPSSubsystem subsystem = TPSSubsystem.getInstance();
+ TokenDatabase database = subsystem.getTokenDatabase();
+ database.removeToken(tokenID);
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new PKIException(e.getMessage());
+ }
+ }
+}