1 package club.wpia.gigi.testUtils;
3 import static org.junit.Assert.*;
6 import java.io.FileInputStream;
7 import java.io.FileOutputStream;
8 import java.io.IOException;
9 import java.io.ObjectInputStream;
10 import java.io.ObjectOutputStream;
11 import java.security.GeneralSecurityException;
12 import java.security.KeyPair;
13 import java.security.KeyPairGenerator;
14 import java.security.Signature;
15 import java.sql.SQLException;
16 import java.text.SimpleDateFormat;
17 import java.util.Calendar;
18 import java.util.Date;
19 import java.util.Properties;
20 import java.util.Random;
21 import java.util.TimeZone;
22 import java.util.regex.Matcher;
23 import java.util.regex.Pattern;
25 import org.junit.AfterClass;
26 import org.junit.BeforeClass;
28 import club.wpia.gigi.GigiApiException;
29 import club.wpia.gigi.database.DatabaseConnection;
30 import club.wpia.gigi.database.DatabaseConnection.Link;
31 import club.wpia.gigi.database.GigiPreparedStatement;
32 import club.wpia.gigi.database.SQLFileManager.ImportType;
33 import club.wpia.gigi.dbObjects.CATS.CATSType;
34 import club.wpia.gigi.dbObjects.CertificateProfile;
35 import club.wpia.gigi.dbObjects.Domain;
36 import club.wpia.gigi.dbObjects.DomainPingType;
37 import club.wpia.gigi.dbObjects.User;
38 import club.wpia.gigi.testUtils.TestEmailReceiver.TestMail;
39 import club.wpia.gigi.util.DatabaseManager;
40 import club.wpia.gigi.util.DomainAssessment;
41 import club.wpia.gigi.util.Notary;
42 import club.wpia.gigi.util.PEM;
43 import club.wpia.gigi.util.PasswordHash;
44 import club.wpia.gigi.util.ServerConstants;
45 import club.wpia.gigi.util.TimeConditions;
46 import sun.security.pkcs10.PKCS10;
47 import sun.security.pkcs10.PKCS10Attributes;
48 import sun.security.x509.X500Name;
51 * Base class for a Testsuite that makes use of the config variables that define
54 public abstract class ConfiguredTest {
56 static Properties testProps = new Properties();
58 public static Properties getTestProps() {
62 private static boolean envInited = false;
65 * Some password that fulfills the password criteria.
67 public static final String TEST_PASSWORD = "xvXV12°§";
69 public static final String DIFFICULT_CHARS = "ÜÖÄß𐀀";
72 public static void initEnvironmentHook() throws IOException {
76 private static Link l;
78 public static Properties initEnvironment() throws IOException {
79 TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
82 synchronized (ConfiguredTest.class) {
84 l = DatabaseConnection.newLink(false);
87 } catch (InterruptedException e) {
90 return generateProps();
93 try (FileInputStream inStream = new FileInputStream("config/test.properties")) {
94 testProps.load(inStream);
96 Properties props = generateProps();
97 ServerConstants.init(props);
98 TimeConditions.init(props);
99 DomainAssessment.init(props);
100 PasswordHash.init(props);
102 if ( !DatabaseConnection.isInited()) {
103 DatabaseConnection.init(testProps);
105 synchronized (ConfiguredTest.class) {
107 l = DatabaseConnection.newLink(false);
110 } catch (InterruptedException e) {
119 public static void closeDBLink() {
120 synchronized (ConfiguredTest.class) {
128 private static Properties generateProps() throws Error {
129 Properties mainProps = new Properties();
130 mainProps.setProperty("name.secure", testProps.getProperty("name.secure"));
131 mainProps.setProperty("name.www", testProps.getProperty("name.www"));
132 mainProps.setProperty("name.static", testProps.getProperty("name.static"));
133 mainProps.setProperty("name.api", testProps.getProperty("name.api"));
134 mainProps.setProperty("name.suffix", testProps.getProperty("name.suffix"));
136 mainProps.setProperty("appName", "SomeCA");
137 mainProps.setProperty("appIdentifier", "someca");
139 mainProps.setProperty("https.port", testProps.getProperty("serverPort.https"));
140 mainProps.setProperty("http.port", testProps.getProperty("serverPort.http"));
142 File out = new File("financial.dat");
143 if ( !out.exists()) {
144 try (FileOutputStream fos = new FileOutputStream(out)) {
145 fos.write("google.com\ntwitter.com\n".getBytes("UTF-8"));
146 } catch (IOException e) {
150 mainProps.setProperty("highFinancialValue", out.getAbsolutePath());
151 mainProps.setProperty("scrypt.params", "1;1;1");
155 public static KeyPair generateKeypair() throws GeneralSecurityException {
156 KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
157 kpg.initialize(4096);
158 KeyPair keyPair = null;
159 File f = new File("testKeypair");
161 try (ObjectInputStream ois = new ObjectInputStream(new FileInputStream(f))) {
162 keyPair = (KeyPair) ois.readObject();
163 } catch (ClassNotFoundException e) {
165 } catch (IOException e) {
169 keyPair = kpg.generateKeyPair();
170 try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(f))) {
171 oos.writeObject(keyPair);
173 } catch (IOException e) {
180 public static String generatePEMCSR(KeyPair kp, String dn) throws GeneralSecurityException, IOException {
181 return generatePEMCSR(kp, dn, new PKCS10Attributes());
184 public static String generatePEMCSR(KeyPair kp, String dn, PKCS10Attributes atts) throws GeneralSecurityException, IOException {
185 return generatePEMCSR(kp, dn, atts, "SHA512WithRSA");
188 public static String generatePEMCSR(KeyPair kp, String dn, PKCS10Attributes atts, String signature) throws GeneralSecurityException, IOException {
189 PKCS10 p10 = new PKCS10(kp.getPublic(), atts);
190 Signature s = Signature.getInstance(signature);
191 s.initSign(kp.getPrivate());
192 p10.encodeAndSign(new X500Name(dn), s);
193 return PEM.encode("CERTIFICATE REQUEST", p10.getEncoded());
196 static int count = 0;
198 public static String createRandomIDString() {
199 final char[] chars = "abcdefghijklmnopqrstuvwxyz0123456789".toCharArray();
200 final int idStringLength = 16;
205 StringBuilder sb = new StringBuilder(idStringLength);
206 for (int i = 0; i < idStringLength; i++) {
207 sb.append(chars[sr.nextInt(chars.length)]);
210 return sb.toString();
213 public static synchronized String createUniqueName() {
214 return "test" + createRandomIDString() + "a" + (count++) + "u";
217 public static CertificateProfile getClientProfile() {
218 return CertificateProfile.getByName("client");
221 public static int countRegex(String text, String pattern) {
222 Pattern p = Pattern.compile(pattern);
223 Matcher m = p.matcher(text);
231 public static void makeAgent(int uid) {
232 try (GigiPreparedStatement ps1 = new GigiPreparedStatement("INSERT INTO cats_passed SET user_id=?, variant_id=?, language='en_EN', version='1'")) {
234 ps1.setInt(2, CATSType.AGENT_CHALLENGE.getId());
238 try (GigiPreparedStatement ps2 = new GigiPreparedStatement("INSERT INTO `notary` SET `from`=?, `to`=?, points='100'")) {
240 ps2.setInt(2, User.getById(uid).getPreferredName().getId());
245 public MailReceiver getMailReceiver() {
246 throw new Error("Feature requires Business or ManagedTest.");
249 public void verify(Domain d) {
251 d.addPing(DomainPingType.EMAIL, "admin");
252 TestMail testMail = getMailReceiver().receive("admin@" + d.getSuffix());
254 assertTrue(d.isVerified());
255 } catch (GigiApiException e) {
257 } catch (IOException e) {
262 public static void purgeOnlyDB() throws SQLException, IOException {
263 System.out.println("... resetting Database");
264 long ms = System.currentTimeMillis();
266 DatabaseManager.run(new String[] {
267 testProps.getProperty("sql.driver"), testProps.getProperty("sql.url"), testProps.getProperty("sql.user"), testProps.getProperty("sql.password")
268 }, ImportType.TRUNCATE);
269 } catch (ClassNotFoundException e) {
272 System.out.println("Database reset complete in " + (System.currentTimeMillis() - ms) + " ms.");
275 public static String validVerificationDateString() {
276 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
277 Calendar c = Calendar.getInstance();
278 c.setTimeInMillis(System.currentTimeMillis());
279 c.add(Calendar.MONTH, -Notary.LIMIT_MAX_MONTHS_VERIFICATION + 1);
280 return sdf.format(new Date(c.getTimeInMillis()));