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