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