]> WPIA git - gigi.git/blob - src/org/cacert/gigi/dbObjects/Domain.java
13c8436cdd8fd63919d89a947b6b39cda65fb896
[gigi.git] / src / org / cacert / gigi / dbObjects / Domain.java
1 package org.cacert.gigi.dbObjects;
2
3 import java.util.Collections;
4 import java.util.LinkedList;
5 import java.util.List;
6
7 import org.cacert.gigi.GigiApiException;
8 import org.cacert.gigi.database.DatabaseConnection;
9 import org.cacert.gigi.database.GigiPreparedStatement;
10 import org.cacert.gigi.database.GigiResultSet;
11 import org.cacert.gigi.dbObjects.DomainPingConfiguration.PingType;
12
13 public class Domain implements IdCachable {
14
15     public class DomainPingExecution {
16
17         private String state;
18
19         private String type;
20
21         private String info;
22
23         private String result;
24
25         private DomainPingConfiguration config;
26
27         public DomainPingExecution(GigiResultSet rs) {
28             state = rs.getString(1);
29             type = rs.getString(2);
30             info = rs.getString(3);
31             result = rs.getString(4);
32             config = DomainPingConfiguration.getById(rs.getInt(5));
33         }
34
35         public String getState() {
36             return state;
37         }
38
39         public String getType() {
40             return type;
41         }
42
43         public String getInfo() {
44             return info;
45         }
46
47         public String getResult() {
48             return result;
49         }
50
51         public DomainPingConfiguration getConfig() {
52             return config;
53         }
54
55     }
56
57     private User owner;
58
59     private String suffix;
60
61     private int id;
62
63     private Domain(int id) {
64         GigiPreparedStatement ps = DatabaseConnection.getInstance().prepare("SELECT memid, domain FROM `domains` WHERE id=? AND deleted IS NULL");
65         ps.setInt(1, id);
66
67         GigiResultSet rs = ps.executeQuery();
68         if ( !rs.next()) {
69             throw new IllegalArgumentException("Invalid domain id " + id);
70         }
71         this.id = id;
72         owner = User.getById(rs.getInt(1));
73         suffix = rs.getString(2);
74         rs.close();
75     }
76
77     public Domain(User owner, String suffix) throws GigiApiException {
78         this.owner = owner;
79         this.suffix = suffix;
80
81     }
82
83     private static void checkInsert(String suffix) throws GigiApiException {
84         GigiPreparedStatement ps = DatabaseConnection.getInstance().prepare("SELECT 1 FROM `domains` WHERE (domain=RIGHT(?,LENGTH(domain))  OR RIGHT(domain,LENGTH(?))=?) AND deleted IS NULL");
85         ps.setString(1, suffix);
86         ps.setString(2, suffix);
87         ps.setString(3, suffix);
88         GigiResultSet rs = ps.executeQuery();
89         boolean existed = rs.next();
90         rs.close();
91         if (existed) {
92             throw new GigiApiException("Domain could not be inserted. Domain is already valid.");
93         }
94     }
95
96     public void insert() throws GigiApiException {
97         if (id != 0) {
98             throw new GigiApiException("already inserted.");
99         }
100         synchronized (Domain.class) {
101             checkInsert(suffix);
102             GigiPreparedStatement ps = DatabaseConnection.getInstance().prepare("INSERT INTO `domains` SET memid=?, domain=?");
103             ps.setInt(1, owner.getId());
104             ps.setString(2, suffix);
105             ps.execute();
106             id = ps.lastInsertId();
107             myCache.put(this);
108         }
109     }
110
111     public void delete() throws GigiApiException {
112         if (id == 0) {
113             throw new GigiApiException("not inserted.");
114         }
115         GigiPreparedStatement ps = DatabaseConnection.getInstance().prepare("UPDATE `domains` SET deleted=CURRENT_TIMESTAMP WHERE id=?");
116         ps.setInt(1, id);
117         ps.execute();
118     }
119
120     public User getOwner() {
121         return owner;
122     }
123
124     @Override
125     public int getId() {
126         return id;
127     }
128
129     public String getSuffix() {
130         return suffix;
131     }
132
133     private LinkedList<DomainPingConfiguration> configs = null;
134
135     public List<DomainPingConfiguration> getConfiguredPings() throws GigiApiException {
136         LinkedList<DomainPingConfiguration> configs = this.configs;
137         if (configs == null) {
138             configs = new LinkedList<>();
139             GigiPreparedStatement ps = DatabaseConnection.getInstance().prepare("SELECT id FROM pingconfig WHERE domainid=?");
140             ps.setInt(1, id);
141             GigiResultSet rs = ps.executeQuery();
142             while (rs.next()) {
143                 configs.add(DomainPingConfiguration.getById(rs.getInt(1)));
144             }
145             rs.close();
146             this.configs = configs;
147
148         }
149         return Collections.unmodifiableList(configs);
150     }
151
152     public void addPing(PingType type, String config) throws GigiApiException {
153         GigiPreparedStatement ps = DatabaseConnection.getInstance().prepare("INSERT INTO pingconfig SET domainid=?, type=?, info=?");
154         ps.setInt(1, id);
155         ps.setString(2, type.toString().toLowerCase());
156         ps.setString(3, config);
157         ps.execute();
158         configs = null;
159     }
160
161     public void verify(String hash) throws GigiApiException {
162         GigiPreparedStatement ps = DatabaseConnection.getInstance().prepare("UPDATE domainPinglog SET state='success' WHERE challenge=? AND configId IN (SELECT id FROM pingconfig WHERE domainId=?)");
163         ps.setString(1, hash);
164         ps.setInt(2, id);
165         ps.executeUpdate();
166     }
167
168     public boolean isVerified() {
169         GigiPreparedStatement ps = DatabaseConnection.getInstance().prepare("SELECT 1 FROM domainPinglog INNER JOIN pingconfig ON pingconfig.id=domainPinglog.configId WHERE domainid=? AND state='success'");
170         ps.setInt(1, id);
171         GigiResultSet rs = ps.executeQuery();
172         return rs.next();
173     }
174
175     public DomainPingExecution[] getPings() throws GigiApiException {
176         GigiPreparedStatement ps = DatabaseConnection.getInstance().prepare("SELECT state, type, info, result, configId FROM domainPinglog INNER JOIN pingconfig ON pingconfig.id=domainPinglog.configid WHERE pingconfig.domainid=? ORDER BY `when` DESC;");
177         ps.setInt(1, id);
178         GigiResultSet rs = ps.executeQuery();
179         rs.last();
180         DomainPingExecution[] contents = new DomainPingExecution[rs.getRow()];
181         rs.beforeFirst();
182         for (int i = 0; i < contents.length && rs.next(); i++) {
183             contents[i] = new DomainPingExecution(rs);
184         }
185         return contents;
186
187     }
188
189     private static ObjectCache<Domain> myCache = new ObjectCache<>();
190
191     public static synchronized Domain getById(int id) throws IllegalArgumentException {
192         Domain em = myCache.get(id);
193         if (em == null) {
194             myCache.put(em = new Domain(id));
195         }
196         return em;
197     }
198
199 }