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