From: INOPIAE Date: Fri, 6 Jul 2018 12:54:01 +0000 (+0200) Subject: add: handling of RA Agent Contract X-Git-Url: https://code.wpia.club/?p=gigi.git;a=commitdiff_plain;h=46eea3386b6003bd243061cb215196f0f9240c90 add: handling of RA Agent Contract Only covers the basic functionality. The full text of the contract and the email will be covered in a later patch. The data contract.id and contract.token will be used for pdf-output in a later patch. The implementation of the restrictions connected to signed contract will be covered in a later patch. Change-Id: I5b47d31458779d227a4f9702a9e7563ab210e7e5 --- diff --git a/src/club/wpia/gigi/Gigi.java b/src/club/wpia/gigi/Gigi.java index e76c5171..d33d546d 100644 --- a/src/club/wpia/gigi/Gigi.java +++ b/src/club/wpia/gigi/Gigi.java @@ -57,6 +57,7 @@ import club.wpia.gigi.pages.Verify; import club.wpia.gigi.pages.account.ChangePasswordPage; import club.wpia.gigi.pages.account.FindAgentAccess; import club.wpia.gigi.pages.account.History; +import club.wpia.gigi.pages.account.MyContracts; import club.wpia.gigi.pages.account.MyDetails; import club.wpia.gigi.pages.account.UserTrainings; import club.wpia.gigi.pages.account.certs.CertificateAdd; @@ -195,6 +196,7 @@ public final class Gigi extends HttpServlet { putPage(UserTrainings.SUPPORT_PATH, new UserTrainings(true), null); putPage(Points.SUPPORT_PATH, new Points(true), null); putPage(Certificates.SUPPORT_PATH + "/*", new Certificates(true), null); + putPage(MyContracts.PATH, new MyContracts(), null); putPage(PasswordResetPage.PATH, new PasswordResetPage(), null); putPage(LogoutPage.PATH, new LogoutPage(), null); diff --git a/src/club/wpia/gigi/database/DatabaseConnection.java b/src/club/wpia/gigi/database/DatabaseConnection.java index b5e78eaa..55a597e8 100644 --- a/src/club/wpia/gigi/database/DatabaseConnection.java +++ b/src/club/wpia/gigi/database/DatabaseConnection.java @@ -181,7 +181,7 @@ public class DatabaseConnection { } - public static final int CURRENT_SCHEMA_VERSION = 37; + public static final int CURRENT_SCHEMA_VERSION = 38; public static final int CONNECTION_TIMEOUT = 24 * 60 * 60; diff --git a/src/club/wpia/gigi/database/tableStructure.sql b/src/club/wpia/gigi/database/tableStructure.sql index e9097fd1..ef7547ce 100644 --- a/src/club/wpia/gigi/database/tableStructure.sql +++ b/src/club/wpia/gigi/database/tableStructure.sql @@ -372,7 +372,7 @@ CREATE TABLE "schemeVersion" ( "version" smallint NOT NULL, PRIMARY KEY ("version") ); -INSERT INTO "schemeVersion" (version) VALUES(37); +INSERT INTO "schemeVersion" (version) VALUES(38); DROP TABLE IF EXISTS `passwordResetTickets`; CREATE TABLE `passwordResetTickets` ( @@ -698,3 +698,22 @@ CREATE TABLE "jobLog" ( PRIMARY KEY ("jobid", "attempt") ); CREATE INDEX ON "jobLog" ("jobid"); + +DROP TABLE IF EXISTS "user_contracts"; +DROP TYPE IF EXISTS "contractType"; +CREATE TYPE "contractType" AS ENUM ('RA Agent Contract', 'Org RA Agent Contract'); + +CREATE TABLE "user_contracts" ( + "id" serial NOT NULL, + "token" varchar(32) NOT NULL, + "memid" int NOT NULL, + "document" "contractType" NOT NULL, + "agentname" varchar(255) NOT NULL, + "datesigned" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "daterevoked" timestamp DEFAULT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX ON "user_contracts" ("memid"); +CREATE INDEX ON "user_contracts" ("document"); +CREATE INDEX ON "user_contracts" ("datesigned"); +CREATE INDEX ON "user_contracts" ("daterevoked"); diff --git a/src/club/wpia/gigi/database/upgrade/from_37.sql b/src/club/wpia/gigi/database/upgrade/from_37.sql new file mode 100644 index 00000000..1ac2a4e3 --- /dev/null +++ b/src/club/wpia/gigi/database/upgrade/from_37.sql @@ -0,0 +1,18 @@ +DROP TABLE IF EXISTS "user_contracts"; +DROP TYPE IF EXISTS "contractType"; +CREATE TYPE "contractType" AS ENUM ('RA Agent Contract', 'Org RA Agent Contract'); + +CREATE TABLE "user_contracts" ( + "id" serial NOT NULL, + "token" varchar(32) NOT NULL, + "memid" int NOT NULL, + "document" "contractType" NOT NULL, + "agentname" varchar(255) NOT NULL, + "datesigned" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + "daterevoked" timestamp DEFAULT NULL, + PRIMARY KEY ("id") +); +CREATE INDEX ON "user_contracts" ("memid"); +CREATE INDEX ON "user_contracts" ("document"); +CREATE INDEX ON "user_contracts" ("datesigned"); +CREATE INDEX ON "user_contracts" ("daterevoked"); diff --git a/src/club/wpia/gigi/dbObjects/Contract.java b/src/club/wpia/gigi/dbObjects/Contract.java new file mode 100644 index 00000000..6886dc26 --- /dev/null +++ b/src/club/wpia/gigi/dbObjects/Contract.java @@ -0,0 +1,188 @@ +package club.wpia.gigi.dbObjects; + +import java.io.IOException; +import java.util.Date; +import java.util.HashMap; + +import club.wpia.gigi.GigiApiException; +import club.wpia.gigi.database.DBEnum; +import club.wpia.gigi.database.GigiPreparedStatement; +import club.wpia.gigi.database.GigiResultSet; +import club.wpia.gigi.localisation.Language; +import club.wpia.gigi.output.template.MailTemplate; +import club.wpia.gigi.util.RandomToken; + +public class Contract { + + public enum ContractType implements DBEnum { + RA_AGENT_CONTRACT("RA Agent Contract"), ORG_RA_AGENT_CONTRACT("Org RA Agent Contract"); + + private final String description; + + private ContractType(String description) { + this.description = description; + } + + public String getDBName() { + return description; + } + } + + private final ContractType contractType; + + private final User user; + + private String agentname = ""; + + private String token = ""; + + private Date dateSigned = null; + + private Date dateRevoked = null; + + private int contractID; + + private static final MailTemplate contractNotice = new MailTemplate(Contract.class.getResource("ContractNotice.templ")); + + public Contract(User u, ContractType contractType) throws GigiApiException { + this.contractType = contractType; + this.user = u; + try (GigiPreparedStatement query = new GigiPreparedStatement("SELECT * FROM `user_contracts` WHERE `memid`=? AND `document`=?::`contractType` and `daterevoked` IS NULL ORDER BY `datesigned` DESC LIMIT 1")) { + query.setInt(1, user.getId()); + query.setEnum(2, contractType); + GigiResultSet rs = query.executeQuery(); + if (rs.next()) { + throw new GigiApiException("Contract exists"); + } else { + signContract(); + } + } + + } + + private void signContract() throws GigiApiException { + agentname = user.getPreferredName().toString(); + token = RandomToken.generateToken(32); + try (GigiPreparedStatement ps = new GigiPreparedStatement("INSERT INTO `user_contracts` SET `memid`=?, `token`=?, `document`=?::`contractType`,`agentname`=?")) { + ps.setInt(1, user.getId()); + ps.setString(2, token); + ps.setEnum(3, this.contractType); + ps.setString(4, agentname); + ps.execute(); + contractID = ps.lastInsertId(); + dateSigned = new Date(); + + HashMap vars = new HashMap<>(); + Language l = Language.getInstance(user.getPreferredLocale()); + vars.put("user", agentname); + vars.put("actionsubject", "Signing"); + vars.put("actionbody", "signed"); + + try { + contractNotice.sendMail(l, vars, user.getEmail()); + } catch (IOException e) { + throw new GigiApiException("Sending the notification mail failed."); + } + } + } + + public void revokeContract() throws GigiApiException { + try (GigiPreparedStatement ps = new GigiPreparedStatement("UPDATE `user_contracts` SET `daterevoked`=NOW() WHERE `id`=?")) { + ps.setInt(1, contractID); + ps.execute(); + } + dateRevoked = new Date(); + HashMap vars = new HashMap<>(); + Language l = Language.getInstance(user.getPreferredLocale()); + vars.put("user", user.getPreferredName()); + vars.put("actionsubject", "Revoking"); + vars.put("actionbody", "revoked"); + + try { + contractNotice.sendMail(l, vars, user.getEmail()); + } catch (IOException e) { + throw new GigiApiException("Sending the notification mail failed."); + } + } + + private Contract(GigiResultSet rs) { + contractID = rs.getInt("id"); + user = User.getById(rs.getInt("memid")); + token = rs.getString("token"); + contractType = ContractType.valueOf(rs.getString("document").toUpperCase().replace(" ", "_")); + dateSigned = rs.getDate("datesigned"); + dateRevoked = rs.getDate("daterevoked"); + agentname = rs.getString("agentname"); + } + + public static Contract getById(int id) { + try (GigiPreparedStatement ps = new GigiPreparedStatement("SELECT * FROM `user_contracts` WHERE `id` = ?")) { + ps.setInt(1, id); + GigiResultSet rs = ps.executeQuery(); + if ( !rs.next()) { + return null; + } + + Contract c = new Contract(rs); + + return c; + } + } + + public int getID() { + return contractID; + } + + public Date getDateSigned() { + return dateSigned; + } + + public Date getDateRevoked() { + return dateRevoked; + } + + public String getRAAgentName() { + return agentname; + } + + public ContractType getContractType() { + return contractType; + } + + public String getToken() { + return token; + } + + public static boolean hasSignedContract(User u, Contract.ContractType ct) { + return getContractByUser(u, ct) != null; + } + + public static Contract getRAAgentContractByUser(User u) { + return getContractByUser(u, Contract.ContractType.RA_AGENT_CONTRACT); + } + + public static Contract getContractByUser(User u, ContractType ct) { + try (GigiPreparedStatement query = new GigiPreparedStatement("SELECT * FROM `user_contracts` WHERE `memid`=? AND `document`=?::`contractType` and `daterevoked` IS NULL ORDER BY `datesigned` DESC LIMIT 1")) { + query.setInt(1, u.getId()); + query.setEnum(2, ct); + GigiResultSet rs = query.executeQuery(); + if ( !rs.next()) { + return null; + } + Contract c = new Contract(rs); + return c; + } + } + + public static Contract getRAAgentContractByToken(String token) throws GigiApiException { + try (GigiPreparedStatement query = new GigiPreparedStatement("SELECT * FROM `user_contracts` WHERE `token`=? LIMIT 1")) { + query.setString(1, token); + GigiResultSet rs = query.executeQuery(); + if ( !rs.next()) { + return null; + } + Contract c = new Contract(rs); + return c; + } + } +} diff --git a/src/club/wpia/gigi/dbObjects/ContractNotice.templ b/src/club/wpia/gigi/dbObjects/ContractNotice.templ new file mode 100644 index 00000000..e0e499d5 --- /dev/null +++ b/src/club/wpia/gigi/dbObjects/ContractNotice.templ @@ -0,0 +1,6 @@ +Subject: + + + + + diff --git a/src/club/wpia/gigi/dbObjects/User.java b/src/club/wpia/gigi/dbObjects/User.java index 4612d033..714bfc3a 100644 --- a/src/club/wpia/gigi/dbObjects/User.java +++ b/src/club/wpia/gigi/dbObjects/User.java @@ -242,6 +242,10 @@ public class User extends CertificateOwner { return false; } + if ( !Contract.hasSignedContract(this, Contract.ContractType.RA_AGENT_CONTRACT)) { + return false; + } + return hasPassedCATS(); } diff --git a/src/club/wpia/gigi/pages/account/MyContracts.java b/src/club/wpia/gigi/pages/account/MyContracts.java new file mode 100644 index 00000000..bf0574b5 --- /dev/null +++ b/src/club/wpia/gigi/pages/account/MyContracts.java @@ -0,0 +1,42 @@ +package club.wpia.gigi.pages.account; + +import java.io.IOException; +import java.io.PrintWriter; +import java.text.SimpleDateFormat; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import club.wpia.gigi.dbObjects.Contract; +import club.wpia.gigi.dbObjects.User; +import club.wpia.gigi.localisation.Language; +import club.wpia.gigi.pages.LoginPage; +import club.wpia.gigi.pages.Page; + +public class MyContracts extends Page { + + public static final String PATH = "/account/contracts"; + + public MyContracts() { + super("My Contracts"); + } + + @Override + public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { + PrintWriter out = resp.getWriter(); + Map vars = getDefaultVars(req); + Language l = LoginPage.getLanguage(req); + User u = getUser(req); + vars.put("raname", u.getPreferredName()); + vars.put("csdate", l.getTranslation("not yet")); + + Contract c = Contract.getRAAgentContractByUser(u); + if (c != null) { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + vars.put("csdate", sdf.format(c.getDateSigned())); + } + + getDefaultTemplate().output(out, getLanguage(req), vars); + } +} diff --git a/src/club/wpia/gigi/pages/account/MyContracts.templ b/src/club/wpia/gigi/pages/account/MyContracts.templ new file mode 100644 index 00000000..ed1bfe97 --- /dev/null +++ b/src/club/wpia/gigi/pages/account/MyContracts.templ @@ -0,0 +1,18 @@ +
+
+
+ +

This contract concludes an agreement between

+ +

Name: - RA Agent hereafter -

+ +

and

+ +

SomeCA - CA hereafter -

+

SomeAddress

+ +

regarding the conduction of registration authority tasks.

+ +

signed

+
+
diff --git a/src/club/wpia/gigi/pages/account/MyDetailsContracts.templ b/src/club/wpia/gigi/pages/account/MyDetailsContracts.templ new file mode 100644 index 00000000..81e0b13e --- /dev/null +++ b/src/club/wpia/gigi/pages/account/MyDetailsContracts.templ @@ -0,0 +1,8 @@ +
+
+
+ + + +
+
diff --git a/src/club/wpia/gigi/pages/account/MyDetailsForm.java b/src/club/wpia/gigi/pages/account/MyDetailsForm.java index 13d03880..bf7cbcfd 100644 --- a/src/club/wpia/gigi/pages/account/MyDetailsForm.java +++ b/src/club/wpia/gigi/pages/account/MyDetailsForm.java @@ -7,6 +7,7 @@ import java.util.Set; import javax.servlet.http.HttpServletRequest; import club.wpia.gigi.GigiApiException; +import club.wpia.gigi.dbObjects.Contract; import club.wpia.gigi.dbObjects.Group; import club.wpia.gigi.dbObjects.Name; import club.wpia.gigi.dbObjects.User; @@ -30,6 +31,8 @@ public class MyDetailsForm extends Form { private static final Template roles = new Template(MyDetailsForm.class.getResource("MyDetailsRoles.templ")); + private static final Template contracts = new Template(MyDetailsForm.class.getResource("MyDetailsContracts.templ")); + private User target; private DateSelector ds; @@ -110,6 +113,17 @@ public class MyDetailsForm extends Form { target.revokeGroup(target, toMod); } return new RedirectResult(MyDetails.PATH); + } else if ("viewContract".equals(action)) { + return new RedirectResult(MyContracts.PATH); + } else if ("signContract".equals(action)) { + new Contract(target, Contract.ContractType.RA_AGENT_CONTRACT); + return new RedirectResult(MyDetails.PATH); + } else if ("revokeContract".equals(action)) { + Contract c = Contract.getRAAgentContractByUser(target); + if (c != null) { + c.revokeContract(); + } + return new RedirectResult(MyDetails.PATH); } else { throw new GigiApiException("Invalid action."); } @@ -161,6 +175,11 @@ public class MyDetailsForm extends Form { vars.put("groups", new GroupList(gr, false)); vars.put("groupSelector", selectedGroup); roles.output(out, l, vars); + + boolean hasSignedContract = Contract.hasSignedContract(target, Contract.ContractType.RA_AGENT_CONTRACT); + vars.put("contractsign", hasSignedContract ? "disabled" : ""); + vars.put("contractrevoke", hasSignedContract ? "" : "disabled"); + contracts.output(out, l, vars); } } diff --git a/tests/club/wpia/gigi/dbObjects/TestContract.java b/tests/club/wpia/gigi/dbObjects/TestContract.java new file mode 100644 index 00000000..98648f0a --- /dev/null +++ b/tests/club/wpia/gigi/dbObjects/TestContract.java @@ -0,0 +1,91 @@ +package club.wpia.gigi.dbObjects; + +import static org.junit.Assert.*; + +import org.hamcrest.CoreMatchers; +import org.junit.Test; + +import club.wpia.gigi.GigiApiException; +import club.wpia.gigi.testUtils.ClientBusinessTest; +import club.wpia.gigi.testUtils.TestEmailReceiver.TestMail; +import club.wpia.gigi.util.RandomToken; + +public class TestContract extends ClientBusinessTest { + + @Test + public void testContract() throws GigiApiException { + + assertEquals(Contract.getContractByUser(u, Contract.ContractType.RA_AGENT_CONTRACT), null); + + assertFalse(Contract.hasSignedContract(u, Contract.ContractType.RA_AGENT_CONTRACT)); + + Contract c = Contract.getRAAgentContractByUser(u); + assertEquals(c, null); + + c = new Contract(u, Contract.ContractType.RA_AGENT_CONTRACT); + TestMail rc = getMailReceiver().receive(u.getEmail()); + + assertEquals(u.getEmail(), rc.getTo()); + assertThat(rc.getMessage(), CoreMatchers.containsString("signed the RA Agent Contract")); + assertEquals(u.getPreferredName().toString(), c.getRAAgentName()); + assertTrue(Contract.hasSignedContract(u, Contract.ContractType.RA_AGENT_CONTRACT)); + + Contract c1 = null; + try { + c1 = new Contract(u, Contract.ContractType.RA_AGENT_CONTRACT); + fail("double add contract must fail"); + } catch (GigiApiException e) { + assertEquals("Contract exists", e.getMessage()); + } + + c1 = Contract.getContractByUser(u, Contract.ContractType.RA_AGENT_CONTRACT); + assertEquals(c.getID(), c1.getID()); + + c1 = Contract.getRAAgentContractByUser(u); + assertEquals(c.getID(), c1.getID()); + + c1 = Contract.getRAAgentContractByToken(c.getToken()); + assertEquals(c.getID(), c1.getID()); + + c1 = Contract.getRAAgentContractByToken(RandomToken.generateToken(16)); + assertEquals(c1, null); + + } + + @Test + public void testRevokeContract() throws GigiApiException { + Contract c = new Contract(u, Contract.ContractType.RA_AGENT_CONTRACT); + + TestMail rc = getMailReceiver().receive(u.getEmail()); + assertThat(rc.getMessage(), CoreMatchers.containsString("signed the RA Agent Contract")); + + c.revokeContract(); + + rc = getMailReceiver().receive(u.getEmail()); + assertEquals(u.getEmail(), rc.getTo()); + assertThat(rc.getMessage(), CoreMatchers.containsString("revoked the RA Agent Contract")); + assertFalse(Contract.hasSignedContract(u, Contract.ContractType.RA_AGENT_CONTRACT)); + + Contract c1 = new Contract(u, Contract.ContractType.RA_AGENT_CONTRACT); + rc = getMailReceiver().receive(u.getEmail()); + + assertNotEquals(c.getID(), c1.getID()); + } + + @Test + public void testContractInt() throws GigiApiException { + Contract c = new Contract(u, Contract.ContractType.RA_AGENT_CONTRACT); + + TestMail rc = getMailReceiver().receive(u.getEmail()); + assertThat(rc.getMessage(), CoreMatchers.containsString("signed the RA Agent Contract")); + + Contract c1 = Contract.getById(c.getID()); + + assertEquals(c.getID(), c1.getID()); + assertEquals(c.getContractType(), c1.getContractType()); + + c1 = Contract.getById(0); + assertEquals(null, c1); + } + +} diff --git a/tests/club/wpia/gigi/dbObjects/TestUser.java b/tests/club/wpia/gigi/dbObjects/TestUser.java index 6ec0abec..e7aa70cf 100644 --- a/tests/club/wpia/gigi/dbObjects/TestUser.java +++ b/tests/club/wpia/gigi/dbObjects/TestUser.java @@ -107,6 +107,19 @@ public class TestUser extends ClientBusinessTest { assertTrue(u.hasValidTTPAgentChallenge()); } + @Test + public void testHasContract() throws GigiApiException { + assertEquals(false, Contract.hasSignedContract(u, Contract.ContractType.RA_AGENT_CONTRACT)); + + Contract c = new Contract(u, Contract.ContractType.RA_AGENT_CONTRACT); + getMailReceiver().receive(u.getEmail()); + assertEquals(true, Contract.hasSignedContract(u, Contract.ContractType.RA_AGENT_CONTRACT)); + + c.revokeContract(); + getMailReceiver().receive(u.getEmail()); + assertEquals(false, Contract.hasSignedContract(u, Contract.ContractType.RA_AGENT_CONTRACT)); + } + @Test public void testWriteUserLog() throws GigiApiException { String type = "Log test"; diff --git a/tests/club/wpia/gigi/testUtils/ConfiguredTest.java b/tests/club/wpia/gigi/testUtils/ConfiguredTest.java index c0d6d4f7..845f6950 100644 --- a/tests/club/wpia/gigi/testUtils/ConfiguredTest.java +++ b/tests/club/wpia/gigi/testUtils/ConfiguredTest.java @@ -42,6 +42,7 @@ import club.wpia.gigi.database.SQLFileManager.ImportType; import club.wpia.gigi.dbObjects.CATS; import club.wpia.gigi.dbObjects.CATS.CATSType; import club.wpia.gigi.dbObjects.CertificateProfile; +import club.wpia.gigi.dbObjects.Contract.ContractType; import club.wpia.gigi.dbObjects.Domain; import club.wpia.gigi.dbObjects.DomainPingType; import club.wpia.gigi.dbObjects.User; @@ -52,6 +53,7 @@ import club.wpia.gigi.util.DomainAssessment; import club.wpia.gigi.util.Notary; import club.wpia.gigi.util.PEM; import club.wpia.gigi.util.PasswordHash; +import club.wpia.gigi.util.RandomToken; import club.wpia.gigi.util.ServerConstants; import club.wpia.gigi.util.TimeConditions; import sun.security.pkcs10.PKCS10; @@ -361,6 +363,15 @@ public abstract class ConfiguredTest { ps2.setInt(2, User.getById(uid).getPreferredName().getId()); ps2.execute(); } + + // insert signed RA Contract + try (GigiPreparedStatement ps = new GigiPreparedStatement("INSERT INTO `user_contracts` SET `memid`=?, `token`=?, `document`=?::`contractType`,`agentname`=?")) { + ps.setInt(1, uid); + ps.setString(2, RandomToken.generateToken(32)); + ps.setEnum(3, ContractType.RA_AGENT_CONTRACT); + ps.setString(4, User.getById(uid).getPreferredName().toString()); + ps.execute(); + } } public MailReceiver getMailReceiver() { diff --git a/tests/club/wpia/gigi/util/TestNotary.java b/tests/club/wpia/gigi/util/TestNotary.java index 4028ebda..6c6780e9 100644 --- a/tests/club/wpia/gigi/util/TestNotary.java +++ b/tests/club/wpia/gigi/util/TestNotary.java @@ -12,6 +12,7 @@ import club.wpia.gigi.GigiApiException; import club.wpia.gigi.database.GigiPreparedStatement; import club.wpia.gigi.dbObjects.CATS; import club.wpia.gigi.dbObjects.CATS.CATSType; +import club.wpia.gigi.dbObjects.Contract; import club.wpia.gigi.dbObjects.Country; import club.wpia.gigi.dbObjects.Country.CountryCodeType; import club.wpia.gigi.dbObjects.Group; @@ -23,6 +24,7 @@ import club.wpia.gigi.dbObjects.User; import club.wpia.gigi.dbObjects.Verification.VerificationType; import club.wpia.gigi.output.DateSelector; import club.wpia.gigi.testUtils.BusinessTest; +import club.wpia.gigi.testUtils.TestEmailReceiver.TestMail; public class TestNotary extends BusinessTest { @@ -167,6 +169,8 @@ public class TestNotary extends BusinessTest { assertEquals(100, applicant.getVerificationPoints()); assertFalse(applicant.canVerify()); CATS.enterResult(applicant, CATSType.AGENT_CHALLENGE, new Date(), "de", "1"); + new Contract(applicant, Contract.ContractType.RA_AGENT_CONTRACT); + TestMail rc = getMailReceiver().receive(applicant.getEmail()); assertTrue(applicant.canVerify()); } } diff --git a/util-testing/club/wpia/gigi/pages/Manager.java b/util-testing/club/wpia/gigi/pages/Manager.java index c9dba62f..6cce345e 100644 --- a/util-testing/club/wpia/gigi/pages/Manager.java +++ b/util-testing/club/wpia/gigi/pages/Manager.java @@ -38,6 +38,8 @@ import club.wpia.gigi.dbObjects.CATS.CATSType; import club.wpia.gigi.dbObjects.Certificate; import club.wpia.gigi.dbObjects.Certificate.CertificateStatus; import club.wpia.gigi.dbObjects.CertificateOwner; +import club.wpia.gigi.dbObjects.Contract; +import club.wpia.gigi.dbObjects.Contract.ContractType; import club.wpia.gigi.dbObjects.Country; import club.wpia.gigi.dbObjects.Digest; import club.wpia.gigi.dbObjects.Domain; @@ -164,6 +166,7 @@ public class Manager extends Page { ps.setString(6, getRandomCountry().getCode()); ps.execute(); } + new Contract(u, ContractType.RA_AGENT_CONTRACT); return u; } }