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