]> WPIA git - gigi.git/blob - src/club/wpia/gigi/dbObjects/Job.java
add: key-compromise revocation
[gigi.git] / src / club / wpia / gigi / dbObjects / Job.java
1 package club.wpia.gigi.dbObjects;
2
3 import java.sql.Date;
4
5 import club.wpia.gigi.GigiApiException;
6 import club.wpia.gigi.database.DBEnum;
7 import club.wpia.gigi.database.GigiPreparedStatement;
8 import club.wpia.gigi.database.GigiResultSet;
9 import club.wpia.gigi.dbObjects.Certificate.RevocationType;
10 import club.wpia.gigi.output.CertificateValiditySelector;
11
12 public class Job implements IdCachable {
13
14     private int id;
15
16     private Job(int id) {
17         this.id = id;
18     }
19
20     public static enum JobType implements DBEnum {
21         SIGN("sign"), REVOKE("revoke");
22
23         private final String name;
24
25         private JobType(String name) {
26             this.name = name;
27         }
28
29         @Override
30         public String getDBName() {
31             return name;
32         }
33     }
34
35     protected synchronized static Job sign(Certificate targetId, Date start, String period) throws GigiApiException {
36         CertificateValiditySelector.checkValidityLength(period);
37         try (GigiPreparedStatement ps = new GigiPreparedStatement("INSERT INTO `jobs` SET targetId=?, task=?::`jobType`, executeFrom=?, executeTo=?")) {
38             ps.setInt(1, targetId.getId());
39             ps.setEnum(2, JobType.SIGN);
40             ps.setDate(3, start);
41             ps.setString(4, period);
42             ps.execute();
43             return cache.put(new Job(ps.lastInsertId()));
44         }
45     }
46
47     protected synchronized static Job revoke(Certificate targetId, RevocationType type) {
48         return revoke(targetId, type, null, null, null);
49     }
50
51     protected synchronized static Job revoke(Certificate targetId, String challenge, String signature, String message) {
52         return revoke(targetId, RevocationType.KEY_COMPROMISE, challenge, signature, message);
53     }
54
55     private synchronized static Job revoke(Certificate targetId, RevocationType type, String challenge, String signature, String message) {
56         try (GigiPreparedStatement ps = new GigiPreparedStatement("UPDATE `certs` SET `revocationType`=?::`revocationType`, `revocationChallenge`=?, `revocationSignature`=?, `revocationMessage`=? WHERE id=?")) {
57             ps.setEnum(1, type);
58             ps.setString(2, challenge);
59             ps.setString(3, signature);
60             ps.setString(4, message);
61             ps.setInt(5, targetId.getId());
62             ps.execute();
63         }
64
65         try (GigiPreparedStatement ps = new GigiPreparedStatement("INSERT INTO `jobs` SET targetId=?, task=?::`jobType`")) {
66             ps.setInt(1, targetId.getId());
67             ps.setEnum(2, JobType.REVOKE);
68             ps.execute();
69             return cache.put(new Job(ps.lastInsertId()));
70         }
71     }
72
73     public synchronized boolean waitFor(int max) {
74         long start = System.currentTimeMillis();
75         try (GigiPreparedStatement ps = new GigiPreparedStatement("SELECT 1 FROM `jobs` WHERE id=? AND state='open'")) {
76             ps.setInt(1, id);
77             GigiResultSet rs = ps.executeQuery();
78             while (rs.next()) {
79                 rs.close();
80                 if (max != 0 && System.currentTimeMillis() - start > max) {
81                     return false;
82                 }
83                 try {
84                     this.wait((long) (2000 + Math.random() * 2000));
85                 } catch (InterruptedException ie) {
86                     // Ignore the interruption
87                     ie.printStackTrace();
88                 }
89                 rs = ps.executeQuery();
90             }
91         }
92         return true;
93     }
94
95     @Override
96     public int getId() {
97         return id;
98     }
99
100     static ObjectCache<Job> cache = new ObjectCache<>();
101
102     public synchronized static Job getById(int id) {
103         Job i = cache.get(id);
104         if (i != null) {
105             return i;
106         }
107         try (GigiPreparedStatement ps = new GigiPreparedStatement("SELECT 1 FROM `jobs` WHERE id=?")) {
108             ps.setInt(1, id);
109             GigiResultSet rs = ps.executeQuery();
110             if (rs.next()) {
111                 Job j = new Job(id);
112                 cache.put(j);
113                 return j;
114             }
115             return null;
116         }
117
118     }
119 }