From dbf2397073d092ea6680a8b7dca19bdd24d1bab1 Mon Sep 17 00:00:00 2001 From: "Endi S. Dewata" Date: Tue, 2 Feb 2016 04:15:02 +0100 Subject: [PATCH] Fixed TPS token state transitions. The TPS service has been modified to provide a list of allowed state transitions based on the current token state. The TPS UI was modified to display only the allowed state transitions when changing the token status. The allowed state transition list has been modified to remove invalid token transitions including: * UNINITIALIZED -> FOUND * UNINITIALIZED -> TEMP_LOST_PERM_LOST The token FOUND state has been renamed to ACTIVE for clarity. The token TEMP_LOST_PERM_LOST state has been merged into PERM_LOST since they are identical in the database. https://fedorahosted.org/pki/ticket/1289 https://fedorahosted.org/pki/ticket/1291 https://fedorahosted.org/pki/ticket/1684 --- .../netscape/certsrv/tps/token/TokenClient.java | 5 ++ .../com/netscape/certsrv/tps/token/TokenData.java | 19 +++++++ .../com/netscape/cmstools/tps/token/TokenCLI.java | 2 + .../cmstools/tps/token/TokenModifyCLI.java | 60 +++++++++++++++++++--- base/tps-client/doc/CS.cfg.in | 30 +++++------ base/tps/shared/conf/CS.cfg.in | 30 +++++------ base/tps/shared/webapps/tps/js/token.js | 36 ++++++++++++- base/tps/shared/webapps/tps/ui/token.html | 6 --- base/tps/shared/webapps/tps/ui/tokens.html | 6 --- .../src/org/dogtagpki/server/tps/TPSTokendb.java | 7 +-- .../org/dogtagpki/server/tps/engine/TPSEngine.java | 3 +- .../dogtagpki/server/tps/rest/TokenService.java | 22 ++++---- 12 files changed, 158 insertions(+), 68 deletions(-) diff --git a/base/common/src/com/netscape/certsrv/tps/token/TokenClient.java b/base/common/src/com/netscape/certsrv/tps/token/TokenClient.java index 32a56b3d498b3c26e555fd2842e3ac35467c4781..a62e71cf8b7b418d4d595e4a3f474eb95cd02b3d 100644 --- a/base/common/src/com/netscape/certsrv/tps/token/TokenClient.java +++ b/base/common/src/com/netscape/certsrv/tps/token/TokenClient.java @@ -60,6 +60,11 @@ public class TokenClient extends Client { return client.getEntity(response, TokenData.class); } + public TokenData changeTokenStatus(String tokenID, TokenStatus tokenStatus) { + Response response = resource.changeTokenStatus(tokenID, tokenStatus); + return client.getEntity(response, TokenData.class); + } + public void removeToken(String tokenID) { Response response = resource.removeToken(tokenID); client.getEntity(response, Void.class); diff --git a/base/common/src/com/netscape/certsrv/tps/token/TokenData.java b/base/common/src/com/netscape/certsrv/tps/token/TokenData.java index 235e86feaebeafec5d6263e3658a53791fb845de..9947bf658100b23ac57d63fe4b6b32f34373a658 100644 --- a/base/common/src/com/netscape/certsrv/tps/token/TokenData.java +++ b/base/common/src/com/netscape/certsrv/tps/token/TokenData.java @@ -20,6 +20,7 @@ package com.netscape.certsrv.tps.token; import java.io.StringReader; import java.io.StringWriter; +import java.util.Collection; import java.util.Date; import javax.xml.bind.JAXBContext; @@ -54,7 +55,10 @@ public class TokenData { String tokenID; String userID; String type; + TokenStatus status; + Collection nextStates; + String appletID; String keyInfo; String policy; @@ -108,6 +112,15 @@ public class TokenData { this.status = status; } + @XmlElement(name="NextStates") + public Collection getNextStates() { + return nextStates; + } + + public void setNextStates(Collection nextStates) { + this.nextStates = nextStates; + } + @XmlElement(name="AppletID") public String getAppletID() { return appletID; @@ -172,6 +185,7 @@ public class TokenData { result = prime * result + ((keyInfo == null) ? 0 : keyInfo.hashCode()); result = prime * result + ((link == null) ? 0 : link.hashCode()); result = prime * result + ((modifyTimestamp == null) ? 0 : modifyTimestamp.hashCode()); + result = prime * result + ((nextStates == null) ? 0 : nextStates.hashCode()); result = prime * result + ((policy == null) ? 0 : policy.hashCode()); result = prime * result + ((status == null) ? 0 : status.hashCode()); result = prime * result + ((tokenID == null) ? 0 : tokenID.hashCode()); @@ -219,6 +233,11 @@ public class TokenData { return false; } else if (!modifyTimestamp.equals(other.modifyTimestamp)) return false; + if (nextStates == null) { + if (other.nextStates != null) + return false; + } else if (!nextStates.equals(other.nextStates)) + return false; if (policy == null) { if (other.policy != null) return false; diff --git a/base/java-tools/src/com/netscape/cmstools/tps/token/TokenCLI.java b/base/java-tools/src/com/netscape/cmstools/tps/token/TokenCLI.java index e7dd6a3081bdd89013d6d65d5b48797fb29dd55a..328490a498f8bfbf56f2cef85767c35194e4218a 100644 --- a/base/java-tools/src/com/netscape/cmstools/tps/token/TokenCLI.java +++ b/base/java-tools/src/com/netscape/cmstools/tps/token/TokenCLI.java @@ -18,6 +18,7 @@ package com.netscape.cmstools.tps.token; +import org.apache.commons.lang.StringUtils; import org.jboss.resteasy.plugins.providers.atom.Link; import com.netscape.certsrv.tps.token.TokenClient; @@ -54,6 +55,7 @@ public class TokenCLI extends CLI { if (token.getUserID() != null) System.out.println(" User ID: " + token.getUserID()); if (token.getType() != null) System.out.println(" Type: " + token.getType()); if (token.getStatus() != null) System.out.println(" Status: " + token.getStatus()); + if (token.getNextStates() != null) System.out.println(" Next States: " + StringUtils.join(token.getNextStates(), ", ")); if (token.getAppletID() != null) System.out.println(" Applet ID: " + token.getAppletID()); if (token.getKeyInfo() != null) System.out.println(" Key Info: " + token.getKeyInfo()); if (token.getPolicy() != null) System.out.println(" Policy: " + token.getPolicy()); diff --git a/base/java-tools/src/com/netscape/cmstools/tps/token/TokenModifyCLI.java b/base/java-tools/src/com/netscape/cmstools/tps/token/TokenModifyCLI.java index 38e9fb00d4112e2f130bb2f1ac6f0fd5ee9c1664..071d1500010a4a98965f1613b8d0b9931f3955ac 100644 --- a/base/java-tools/src/com/netscape/cmstools/tps/token/TokenModifyCLI.java +++ b/base/java-tools/src/com/netscape/cmstools/tps/token/TokenModifyCLI.java @@ -24,6 +24,7 @@ import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.Option; import com.netscape.certsrv.tps.token.TokenData; +import com.netscape.certsrv.tps.token.TokenStatus; import com.netscape.cmstools.cli.CLI; import com.netscape.cmstools.cli.MainCLI; @@ -65,6 +66,10 @@ public class TokenModifyCLI extends CLI { option = new Option(null, "policy", true, "Policy"); option.setArgName("Policy"); options.addOption(option); + + option = new Option(null, "status", true, "Status"); + option.setArgName("Status"); + options.addOption(option); } public void execute(String[] args) throws Exception { @@ -94,17 +99,56 @@ public class TokenModifyCLI extends CLI { System.exit(-1); } - String tokenID = cmdArgs[0]; - TokenData tokenData = new TokenData(); + boolean modify = false; + + String tokenID = cmdArgs[0]; tokenData.setID(tokenID); - tokenData.setUserID(cmd.getOptionValue("user")); - tokenData.setType(cmd.getOptionValue("type")); - tokenData.setAppletID(cmd.getOptionValue("applet")); - tokenData.setKeyInfo(cmd.getOptionValue("key-info")); - tokenData.setPolicy(cmd.getOptionValue("policy")); - tokenData = tokenCLI.tokenClient.modifyToken(tokenID, tokenData); + String userID = cmd.getOptionValue("user"); + if (userID != null) { + tokenData.setUserID(userID); + modify = true; + } + + String type = cmd.getOptionValue("type"); + if (type != null) { + tokenData.setType(type); + modify = true; + } + + String appletID = cmd.getOptionValue("applet"); + if (appletID != null) { + tokenData.setAppletID(appletID); + modify = true; + } + + String keyInfo = cmd.getOptionValue("key-info"); + if (keyInfo != null) { + tokenData.setKeyInfo(keyInfo); + modify = true; + } + + String policy = cmd.getOptionValue("policy"); + if (policy != null) { + tokenData.setPolicy(policy); + modify = true; + } + + if (modify) { + tokenData = tokenCLI.tokenClient.modifyToken(tokenID, tokenData); + } + + String status = cmd.getOptionValue("status"); + if (status != null) { + tokenData = tokenCLI.tokenClient.changeTokenStatus(tokenID, TokenStatus.valueOf(status)); + } + + if (!modify && status == null) { + System.err.println("Error: No modifications specified."); + printHelp(); + System.exit(-1); + } MainCLI.printMessage("Modified token \"" + tokenID + "\""); diff --git a/base/tps-client/doc/CS.cfg.in b/base/tps-client/doc/CS.cfg.in index d5c0f312eae005f29443dd6e0fc04c71d9efb0dd..273772276f7f0821418cac36903a664bc14f7965 100644 --- a/base/tps-client/doc/CS.cfg.in +++ b/base/tps-client/doc/CS.cfg.in @@ -1482,13 +1482,13 @@ tokendb._064=# is set to YES. Otherwise, re-enrollment is not tokendb._065=# allowed. tokendb._066=# tokendb.allowedTransitions: tokendb._067=# - has transitions between the following states -tokendb._068=# TOKEN_UNINITIALIZED = 0, -tokendb._069=# TOKEN_DAMAGED =1, -tokendb._070=# TOKEN_PERM_LOST=2, -tokendb._071=# TOKEN_TEMP_LOST=3, -tokendb._072=# TOKEN_FOUND =4, -tokendb._073=# TOKEN_TEMP_LOST_PERM_LOST =5, -tokendb._074=# TOKEN_TERMINATED = 6 +tokendb._068=# UNINITIALIZED = 0, +tokendb._069=# DAMAGED = 1, +tokendb._070=# PERM_LOST = 2, +tokendb._071=# TEMP_LOST = 3, +tokendb._072=# ACTIVE = 4, +tokendb._073=# TEMP_LOST_PERM_LOST = 5, +tokendb._074=# TERMINATED = 6 tokendb._075=######################################### tokendb.auditLog=[PKI_INSTANCE_PATH]/logs/tokendb-audit.log tokendb.hostport=[TOKENDB_HOST]:[TOKENDB_PORT] @@ -1545,7 +1545,7 @@ tokendb.confirmDeleteConfigTemplate=confirmDeleteConfig.template log.instance.SignedAudit.selected.events=ROLE_ASSUME,CONFIG_CERT_POLICY,CONFIG_CERT_PROFILE,CONFIG_CRL_PROFILE,CONFIG_OCSP_PROFILE,CONFIG_AUTH,CONFIG_ROLE,CONFIG_ACL,CONFIG_SIGNED_AUDIT,CONFIG_ENCRYPTION,CONFIG_TRUSTED_PUBLIC_KEY,CONFIG_DRM,SELFTESTS_EXECUTION,AUDIT_LOG_DELETE,LOG_PATH_CHANGE,LOG_EXPIRATION_CHANGE,CONFIG,CONFIG_ROLE,CONFIG_TOKEN,CONFIG_PROFILE,CONFIG_AUDIT,APPLET_UPGRADE,KEY_CHANGEOVER,RENEWAL log.instance.SignedAudit.selectable.events=ROLE_ASSUME,CONFIG_CERT_POLICY,CONFIG_CERT_PROFILE,CONFIG_CRL_PROFILE,CONFIG_OCSP_PROFILE,CONFIG_AUTH,CONFIG_ROLE,CONFIG_ACL,CONFIG_SIGNED_AUDIT,CONFIG_ENCRYPTION,CONFIG_TRUSTED_PUBLIC_KEY,CONFIG_DRM,SELFTESTS_EXECUTION,AUDIT_LOG_DELETE,LOG_PATH_CHANGE,LOG_EXPIRATION_CHANGE,PRIVATE_KEY_ARCHIVE,PRIVATE_KEY_ARCHIVE_PROCESSED,KEY_RECOVERY_REQUEST,KEY_RECOVERY_AGENT_LOGIN,KEY_RECOVERY_PROCESSED,KEY_GEN_ASYMMETRIC,NON_PROFILE_CERT_REQUEST,CONFIG,CONFIG_ROLE,CONFIG_TOKEN,CONFIG_PROFILE,CONFIG_AUDIT,APPLET_UPGRADE,KEY_CHANGEOVER,RENEWAL log.instance.SignedAudit.nonselectable.events=AUDIT_LOG_STARTUP,AUDIT_LOG_SHUTDOWN,CERT_REQUEST_PROCESSED,CERT_STATUS_CHANGE_REQUEST,CERT_STATUS_CHANGE_REQUEST_PROCESSED,AUTHZ_SUCCESS,AUTHZ_FAIL,INTER_BOUNDARY,AUTH_FAIL,AUTH_SUCCESS,CERT_PROFILE_APPROVAL,PROOF_OF_POSSESSION,CRL_RETRIEVAL,CRL_VALIDATION,CMC_SIGNED_REQUEST_SIG_VERIFY,SERVER_SIDE_KEYGEN_PROCESSED,SERVER_SIDE_KEYGEN_REQUEST -tokendb.allowedTransitions=0:1,0:2,0:3,0:4,0:5,0:6,3:4,3:5,3:6,4:1,4:2,4:3,4:6 +tokendb.allowedTransitions=0:1,0:2,0:3,0:6,3:2,3:4,3:6,4:1,4:2,4:3,4:6 target._000=######################################### target._001=# entries to enable configuration of parameter sets through the TPS UI agent and admin tabs target._002=# @@ -1592,13 +1592,13 @@ tps._005=# tps.cert.subsystem.nickname=xxx tps._007=# tps.cert.audit_signing.nickname=xxx tps._008=# operations.allowedTransitions: tps._009=# - token operations, like formatting and enrollment have transitions between the following states -tps._010=# TOKEN_UNINITIALIZED = 0, -tps._011=# TOKEN_DAMAGED =1, -tps._012=# TOKEN_PERM_LOST=2, -tps._013=# TOKEN_TEMP_LOST=3, -tps._014=# TOKEN_FOUND =4, -tps._015=# TOKEN_TEMP_LOST_PERM_LOST =5, -tps._016=# TOKEN_TERMINATED = 6 +tps._010=# UNINITIALIZED = 0, +tps._011=# DAMAGED = 1, +tps._012=# PERM_LOST = 2, +tps._013=# TEMP_LOST =3 , +tps._014=# ACTIVE = 4, +tps._015=# TEMP_LOST_PERM_LOST = 5, +tps._016=# TERMINATED = 6 tps._017=# Sample: tps.operations.allowedTransitions=0:0,0:4,4:6,6:0 tps._018=######################################## tps.operations.allowedTransitions=0:0,0:4,4:0 diff --git a/base/tps/shared/conf/CS.cfg.in b/base/tps/shared/conf/CS.cfg.in index 48fd8fe43d5f2e5016e27cbb231f462c6e6a7b1d..655ea4d67de454181145c1a9c19fc3ee00782ee8 100644 --- a/base/tps/shared/conf/CS.cfg.in +++ b/base/tps/shared/conf/CS.cfg.in @@ -1954,20 +1954,20 @@ tokendb._064=# is set to YES. Otherwise, re-enrollment is not tokendb._065=# allowed. tokendb._066=# tokendb.allowedTransitions: tokendb._067=# - has transitions between the following states -tokendb._068=# TOKEN_UNINITIALIZED = 0, -tokendb._069=# TOKEN_DAMAGED =1, -tokendb._070=# TOKEN_PERM_LOST=2, -tokendb._071=# TOKEN_TEMP_LOST=3, -tokendb._072=# TOKEN_FOUND =4, -tokendb._073=# TOKEN_TEMP_LOST_PERM_LOST =5, -tokendb._074=# TOKEN_TERMINATED = 6 +tokendb._068=# UNINITIALIZED = 0, +tokendb._069=# DAMAGED = 1, +tokendb._070=# PERM_LOST = 2, +tokendb._071=# TEMP_LOST = 3, +tokendb._072=# ACTIVE = 4, +tokendb._073=# TEMP_LOST_PERM_LOST = 5, +tokendb._074=# TERMINATED = 6 tokendb._075=######################################### tokendb.activityBaseDN=ou=Activities,[TOKENDB_ROOT] tokendb.addConfigTemplate=addConfig.template tokendb.addResultTemplate=addResults.template tokendb.agentSelectConfigTemplate=agentSelectConfig.template tokendb.agentViewConfigTemplate=agentViewConfig.template -tokendb.allowedTransitions=0:1,0:2,0:3,0:4,0:5,0:6,3:4,3:5,3:6,4:1,4:2,4:3,4:6 +tokendb.allowedTransitions=0:1,0:2,0:3,0:6,3:2,3:4,3:6,4:1,4:2,4:3,4:6 tokendb.auditAdminTemplate=auditAdmin.template tokendb.auditLog=[PKI_INSTANCE_PATH]/logs/tokendb-audit.log tokendb.baseDN=ou=Tokens,[TOKENDB_ROOT] @@ -2023,13 +2023,13 @@ tps._005=# tps.cert.subsystem.nickname=xxx tps._007=# tps.cert.audit_signing.nickname=xxx tps._008=# operations.allowedTransitions: tps._009=# - token operations, like formatting and enrollment have transitions between the following states -tps._010=# TOKEN_UNINITIALIZED = 0, -tps._011=# TOKEN_DAMAGED =1, -tps._012=# TOKEN_PERM_LOST=2, -tps._013=# TOKEN_TEMP_LOST=3, -tps._014=# TOKEN_FOUND =4, -tps._015=# TOKEN_TEMP_LOST_PERM_LOST =5, -tps._016=# TOKEN_TERMINATED = 6 +tps._010=# UNINITIALIZED = 0, +tps._011=# DAMAGED = 1, +tps._012=# PERM_LOST = 2, +tps._013=# TEMP_LOST = 3, +tps._014=# ACTIVE = 4, +tps._015=# TEMP_LOST_PERM_LOST = 5, +tps._016=# TERMINATED = 6 tps._017=# Sample: tps.operations.allowedTransitions=0:0,0:4,4:6,6:0 tps._018=######################################## tps.cert.audit_signing.certusage=ObjectSigner diff --git a/base/tps/shared/webapps/tps/js/token.js b/base/tps/shared/webapps/tps/js/token.js index f4d2d8a78e46b92fd1e0ae9a87136f0e63e3e2c8..1a4267f72de1c378522dc16ec18f3c90414f1dd7 100644 --- a/base/tps/shared/webapps/tps/js/token.js +++ b/base/tps/shared/webapps/tps/js/token.js @@ -25,6 +25,7 @@ var TokenStatus = { TEMP_LOST: "Temporarily lost", PERM_LOST: "Permanently lost", DAMAGED: "Physically damaged", + TEMP_LOST_PERM_LOST: "Temporarily lost then permanently lost", TERMINATED: "Terminated" }; @@ -38,6 +39,7 @@ var TokenModel = Model.extend({ type: response.Type, status: response.Status, statusLabel: TokenStatus[response.Status], + nextStates: response.NextStates, appletID: response.AppletID, keyInfo: response.KeyInfo, policy: response.Policy, @@ -91,6 +93,7 @@ var TokenCollection = Collection.extend({ type: entry.Type, status: entry.Status, statusLabel: TokenStatus[entry.Status], + nextStates: entry.NextStates, appletID: entry.AppletID, keyInfo: entry.KeyInfo, policy: entry.Policy, @@ -100,6 +103,35 @@ var TokenCollection = Collection.extend({ } }); +var TokenDialog = Dialog.extend({ + loadField: function(input) { + var self = this; + + var name = input.attr("name"); + if (name != "status") { + TokenDialog.__super__.loadField.call(self, input); + return; + } + + var select = input.empty(); + var status = self.entry["status"]; + + $('