1package eu.siacs.conversations.entities;
2
3import java.security.interfaces.DSAPublicKey;
4
5import net.java.otr4j.crypto.OtrCryptoEngineImpl;
6import net.java.otr4j.crypto.OtrCryptoException;
7
8import org.json.JSONException;
9import org.json.JSONObject;
10
11import eu.siacs.conversations.crypto.OtrEngine;
12import eu.siacs.conversations.xmpp.XmppConnection;
13import android.content.ContentValues;
14import android.content.Context;
15import android.database.Cursor;
16
17public class Account extends AbstractEntity{
18
19 private static final long serialVersionUID = 6174825093869578035L;
20
21 public static final String TABLENAME = "accounts";
22
23 public static final String USERNAME = "username";
24 public static final String SERVER = "server";
25 public static final String PASSWORD = "password";
26 public static final String OPTIONS = "options";
27 public static final String ROSTERVERSION = "rosterversion";
28 public static final String KEYS = "keys";
29
30 public static final int OPTION_USETLS = 0;
31 public static final int OPTION_DISABLED = 1;
32 public static final int OPTION_REGISTER = 2;
33 public static final int OPTION_USECOMPRESSION = 3;
34
35 public static final int STATUS_CONNECTING = 0;
36 public static final int STATUS_DISABLED = -2;
37 public static final int STATUS_OFFLINE = -1;
38 public static final int STATUS_ONLINE = 1;
39 public static final int STATUS_NO_INTERNET = 2;
40 public static final int STATUS_UNAUTHORIZED = 3;
41 public static final int STATUS_TLS_ERROR = 4;
42 public static final int STATUS_SERVER_NOT_FOUND = 5;
43
44 public static final int STATUS_SERVER_REQUIRES_TLS = 6;
45
46 public static final int STATUS_REGISTRATION_FAILED = 7;
47 public static final int STATUS_REGISTRATION_CONFLICT = 8;
48 public static final int STATUS_REGISTRATION_SUCCESSFULL = 9;
49 public static final int STATUS_REGISTRATION_NOT_SUPPORTED = 10;
50
51 protected String username;
52 protected String server;
53 protected String password;
54 protected int options = 0;
55 protected String rosterVersion;
56 protected String resource = "mobile";
57 protected int status = -1;
58 protected JSONObject keys = new JSONObject();
59
60 protected boolean online = false;
61
62 transient OtrEngine otrEngine = null;
63 transient XmppConnection xmppConnection = null;
64 transient protected Presences presences = new Presences();
65
66 private String otrFingerprint;
67
68 private Roster roster = null;
69
70 public Account() {
71 this.uuid = "0";
72 }
73
74 public Account(String username, String server, String password) {
75 this(java.util.UUID.randomUUID().toString(),username,server,password,0,null,"");
76 }
77 public Account(String uuid, String username, String server,String password, int options, String rosterVersion, String keys) {
78 this.uuid = uuid;
79 this.username = username;
80 this.server = server;
81 this.password = password;
82 this.options = options;
83 this.rosterVersion = rosterVersion;
84 try {
85 this.keys = new JSONObject(keys);
86 } catch (JSONException e) {
87
88 }
89 }
90
91 public boolean isOptionSet(int option) {
92 return ((options & (1 << option)) != 0);
93 }
94
95 public void setOption(int option, boolean value) {
96 if (value) {
97 this.options |= 1 << option;
98 } else {
99 this.options &= ~(1 << option);
100 }
101 }
102
103 public String getUsername() {
104 return username;
105 }
106
107 public void setUsername(String username) {
108 this.username = username;
109 }
110
111 public String getServer() {
112 return server;
113 }
114
115 public void setServer(String server) {
116 this.server = server;
117 }
118
119 public String getPassword() {
120 return password;
121 }
122
123 public void setPassword(String password) {
124 this.password = password;
125 }
126
127 public void setStatus(int status) {
128 this.status = status;
129 }
130
131 public int getStatus() {
132 if (isOptionSet(OPTION_DISABLED)) {
133 return STATUS_DISABLED;
134 } else {
135 return this.status;
136 }
137 }
138
139 public boolean hasErrorStatus() {
140 return getStatus() > STATUS_NO_INTERNET && (getXmppConnection().getAttempt() >= 2);
141 }
142
143 public void setResource(String resource) {
144 this.resource = resource;
145 }
146
147 public String getResource() {
148 return this.resource;
149 }
150
151 public String getJid() {
152 return username+"@"+server;
153 }
154
155 public JSONObject getKeys() {
156 return keys;
157 }
158
159 public String getSSLFingerprint() {
160 if (keys.has("ssl_cert")) {
161 try {
162 return keys.getString("ssl_cert");
163 } catch (JSONException e) {
164 return null;
165 }
166 } else {
167 return null;
168 }
169 }
170
171 public void setSSLCertFingerprint(String fingerprint) {
172 this.setKey("ssl_cert", fingerprint);
173 }
174
175 public boolean setKey(String keyName, String keyValue) {
176 try {
177 this.keys.put(keyName, keyValue);
178 return true;
179 } catch (JSONException e) {
180 return false;
181 }
182 }
183
184 @Override
185 public ContentValues getContentValues() {
186 ContentValues values = new ContentValues();
187 values.put(UUID,uuid);
188 values.put(USERNAME, username);
189 values.put(SERVER, server);
190 values.put(PASSWORD, password);
191 values.put(OPTIONS,options);
192 values.put(KEYS,this.keys.toString());
193 values.put(ROSTERVERSION,rosterVersion);
194 return values;
195 }
196
197 public static Account fromCursor(Cursor cursor) {
198 return new Account(cursor.getString(cursor.getColumnIndex(UUID)),
199 cursor.getString(cursor.getColumnIndex(USERNAME)),
200 cursor.getString(cursor.getColumnIndex(SERVER)),
201 cursor.getString(cursor.getColumnIndex(PASSWORD)),
202 cursor.getInt(cursor.getColumnIndex(OPTIONS)),
203 cursor.getString(cursor.getColumnIndex(ROSTERVERSION)),
204 cursor.getString(cursor.getColumnIndex(KEYS))
205 );
206 }
207
208
209 public OtrEngine getOtrEngine(Context context) {
210 if (otrEngine==null) {
211 otrEngine = new OtrEngine(context,this);
212 }
213 return this.otrEngine;
214 }
215
216 public XmppConnection getXmppConnection() {
217 return this.xmppConnection;
218 }
219
220 public void setXmppConnection(XmppConnection connection) {
221 this.xmppConnection = connection;
222 }
223
224 public String getFullJid() {
225 return this.getJid()+"/"+this.resource;
226 }
227
228 public String getOtrFingerprint() {
229 if (this.otrFingerprint == null) {
230 try {
231 DSAPublicKey pubkey = (DSAPublicKey) this.otrEngine.getPublicKey();
232 if (pubkey == null) {
233 return null;
234 }
235 StringBuilder builder = new StringBuilder(new OtrCryptoEngineImpl().getFingerprint(pubkey));
236 builder.insert(8, " ");
237 builder.insert(17, " ");
238 builder.insert(26, " ");
239 builder.insert(35, " ");
240 this.otrFingerprint = builder.toString();
241 } catch (OtrCryptoException e) {
242
243 }
244 }
245 return this.otrFingerprint;
246 }
247
248 public String getRosterVersion() {
249 if (this.rosterVersion==null) {
250 return "";
251 } else {
252 return this.rosterVersion;
253 }
254 }
255
256 public void setRosterVersion(String version) {
257 this.rosterVersion = version;
258 }
259
260 public String getOtrFingerprint(Context applicationContext) {
261 this.getOtrEngine(applicationContext);
262 return this.getOtrFingerprint();
263 }
264
265 public void updatePresence(String resource, int status) {
266 this.presences.updatePresence(resource, status);
267 }
268
269 public void removePresence(String resource) {
270 this.presences.removePresence(resource);
271 }
272
273 public void clearPresences() {
274 this.presences = new Presences();
275 }
276
277 public int countPresences() {
278 return this.presences.size();
279 }
280
281 public String getPgpSignature() {
282 if (keys.has("pgp_signature")) {
283 try {
284 return keys.getString("pgp_signature");
285 } catch (JSONException e) {
286 return null;
287 }
288 } else {
289 return null;
290 }
291 }
292
293 public Roster getRoster() {
294 if (this.roster==null) {
295 this.roster = new Roster(this);
296 }
297 return this.roster;
298 }
299}