MucOptions.java

  1package eu.siacs.conversations.entities;
  2
  3import java.util.ArrayList;
  4import java.util.List;
  5import java.util.concurrent.CopyOnWriteArrayList;
  6
  7import eu.siacs.conversations.crypto.PgpEngine;
  8import eu.siacs.conversations.xml.Element;
  9import eu.siacs.conversations.xmpp.jid.InvalidJidException;
 10import eu.siacs.conversations.xmpp.jid.Jid;
 11import eu.siacs.conversations.xmpp.stanzas.PresencePacket;
 12import android.annotation.SuppressLint;
 13
 14@SuppressLint("DefaultLocale")
 15public class MucOptions {
 16	public static final int ERROR_NO_ERROR = 0;
 17	public static final int ERROR_NICK_IN_USE = 1;
 18	public static final int ERROR_ROOM_NOT_FOUND = 2;
 19	public static final int ERROR_PASSWORD_REQUIRED = 3;
 20	public static final int ERROR_BANNED = 4;
 21	public static final int ERROR_MEMBERS_ONLY = 5;
 22
 23	public static final int KICKED_FROM_ROOM = 9;
 24
 25	public static final String STATUS_CODE_BANNED = "301";
 26	public static final String STATUS_CODE_KICKED = "307";
 27
 28	public interface OnRenameListener {
 29		public void onRename(boolean success);
 30	}
 31
 32	public class User {
 33		public static final int ROLE_MODERATOR = 3;
 34		public static final int ROLE_NONE = 0;
 35		public static final int ROLE_PARTICIPANT = 2;
 36		public static final int ROLE_VISITOR = 1;
 37		public static final int AFFILIATION_ADMIN = 4;
 38		public static final int AFFILIATION_OWNER = 3;
 39		public static final int AFFILIATION_MEMBER = 2;
 40		public static final int AFFILIATION_OUTCAST = 1;
 41		public static final int AFFILIATION_NONE = 0;
 42
 43		private int role;
 44		private int affiliation;
 45		private String name;
 46		private String jid;
 47		private long pgpKeyId = 0;
 48
 49		public String getName() {
 50			return name;
 51		}
 52
 53		public void setName(String user) {
 54			this.name = user;
 55		}
 56
 57		public void setJid(String jid) {
 58			this.jid = jid;
 59		}
 60
 61		public String getJid() {
 62			return this.jid;
 63		}
 64
 65		public int getRole() {
 66			return this.role;
 67		}
 68
 69		public void setRole(String role) {
 70			role = role.toLowerCase();
 71            switch (role) {
 72                case "moderator":
 73                    this.role = ROLE_MODERATOR;
 74                    break;
 75                case "participant":
 76                    this.role = ROLE_PARTICIPANT;
 77                    break;
 78                case "visitor":
 79                    this.role = ROLE_VISITOR;
 80                    break;
 81                default:
 82                    this.role = ROLE_NONE;
 83                    break;
 84            }
 85		}
 86
 87		public int getAffiliation() {
 88			return this.affiliation;
 89		}
 90
 91		public void setAffiliation(String affiliation) {
 92			if (affiliation.equalsIgnoreCase("admin")) {
 93				this.affiliation = AFFILIATION_ADMIN;
 94			} else if (affiliation.equalsIgnoreCase("owner")) {
 95				this.affiliation = AFFILIATION_OWNER;
 96			} else if (affiliation.equalsIgnoreCase("member")) {
 97				this.affiliation = AFFILIATION_MEMBER;
 98			} else if (affiliation.equalsIgnoreCase("outcast")) {
 99				this.affiliation = AFFILIATION_OUTCAST;
100			} else {
101				this.affiliation = AFFILIATION_NONE;
102			}
103		}
104
105		public void setPgpKeyId(long id) {
106			this.pgpKeyId = id;
107		}
108
109		public long getPgpKeyId() {
110			return this.pgpKeyId;
111		}
112
113		public Contact getContact() {
114			return account.getRoster().getContactFromRoster(getJid());
115		}
116	}
117
118	private Account account;
119	private List<User> users = new CopyOnWriteArrayList<>();
120	private Conversation conversation;
121	private boolean isOnline = false;
122	private int error = ERROR_ROOM_NOT_FOUND;
123	private OnRenameListener renameListener = null;
124	private boolean aboutToRename = false;
125	private User self = new User();
126	private String subject = null;
127	private String joinnick;
128	private String password = null;
129
130	public MucOptions(Conversation conversation) {
131		this.account = conversation.getAccount();
132		this.conversation = conversation;
133	}
134
135	public void deleteUser(String name) {
136		for (int i = 0; i < users.size(); ++i) {
137			if (users.get(i).getName().equals(name)) {
138				users.remove(i);
139				return;
140			}
141		}
142	}
143
144	public void addUser(User user) {
145		for (int i = 0; i < users.size(); ++i) {
146			if (users.get(i).getName().equals(user.getName())) {
147				users.set(i, user);
148				return;
149			}
150		}
151		users.add(user);
152	}
153
154	public void processPacket(PresencePacket packet, PgpEngine pgp) {
155        final Jid from = packet.getFrom();
156		if (!from.isBareJid()) {
157			final String name = from.getResourcepart();
158			String type = packet.getAttribute("type");
159			if (type == null) {
160				User user = new User();
161				Element item = packet.findChild("x",
162						"http://jabber.org/protocol/muc#user")
163						.findChild("item");
164				user.setName(name);
165				user.setAffiliation(item.getAttribute("affiliation"));
166				user.setRole(item.getAttribute("role"));
167				user.setJid(item.getAttribute("jid"));
168				user.setName(name);
169				if (name.equals(this.joinnick)) {
170					this.isOnline = true;
171					this.error = ERROR_NO_ERROR;
172					self = user;
173					if (aboutToRename) {
174						if (renameListener != null) {
175							renameListener.onRename(true);
176						}
177						aboutToRename = false;
178					}
179				} else {
180					addUser(user);
181				}
182				if (pgp != null) {
183					Element x = packet.findChild("x", "jabber:x:signed");
184					if (x != null) {
185						Element status = packet.findChild("status");
186						String msg;
187						if (status != null) {
188							msg = status.getContent();
189						} else {
190							msg = "";
191						}
192						user.setPgpKeyId(pgp.fetchKeyId(account, msg,
193								x.getContent()));
194					}
195				}
196			} else if (type.equals("unavailable") && name.equals(this.joinnick)) {
197				Element x = packet.findChild("x",
198						"http://jabber.org/protocol/muc#user");
199				if (x != null) {
200					Element status = x.findChild("status");
201					if (status != null) {
202						String code = status.getAttribute("code");
203						if (STATUS_CODE_KICKED.equals(code)) {
204							this.isOnline = false;
205							this.error = KICKED_FROM_ROOM;
206						} else if (STATUS_CODE_BANNED.equals(code)) {
207							this.isOnline = false;
208							this.error = ERROR_BANNED;
209						}
210					}
211				}
212			} else if (type.equals("unavailable")) {
213				deleteUser(packet.getAttribute("from").split("/", 2)[1]);
214			} else if (type.equals("error")) {
215				Element error = packet.findChild("error");
216				if (error != null && error.hasChild("conflict")) {
217					if (aboutToRename) {
218						if (renameListener != null) {
219							renameListener.onRename(false);
220						}
221						aboutToRename = false;
222						this.setJoinNick(getActualNick());
223					} else {
224						this.error = ERROR_NICK_IN_USE;
225					}
226				} else if (error != null && error.hasChild("not-authorized")) {
227					this.error = ERROR_PASSWORD_REQUIRED;
228				} else if (error != null && error.hasChild("forbidden")) {
229					this.error = ERROR_BANNED;
230				} else if (error != null
231						&& error.hasChild("registration-required")) {
232					this.error = ERROR_MEMBERS_ONLY;
233				}
234			}
235		}
236	}
237
238	public List<User> getUsers() {
239		return this.users;
240	}
241
242	public String getProposedNick() {
243		if (conversation.getBookmark() != null
244				&& conversation.getBookmark().getNick() != null) {
245			return conversation.getBookmark().getNick();
246		} else {
247			if (!conversation.getContactJid().isBareJid()) {
248				return conversation.getContactJid().getResourcepart();
249			} else {
250				return account.getUsername();
251			}
252		}
253	}
254
255	public String getActualNick() {
256		if (this.self.getName() != null) {
257			return this.self.getName();
258		} else {
259			return this.getProposedNick();
260		}
261	}
262
263	public void setJoinNick(String nick) {
264		this.joinnick = nick;
265	}
266
267	public boolean online() {
268		return this.isOnline;
269	}
270
271	public int getError() {
272		return this.error;
273	}
274
275	public void setOnRenameListener(OnRenameListener listener) {
276		this.renameListener = listener;
277	}
278
279	public OnRenameListener getOnRenameListener() {
280		return this.renameListener;
281	}
282
283	public void setOffline() {
284		this.users.clear();
285		this.error = 0;
286		this.isOnline = false;
287	}
288
289	public User getSelf() {
290		return self;
291	}
292
293	public void setSubject(String content) {
294		this.subject = content;
295	}
296
297	public String getSubject() {
298		return this.subject;
299	}
300
301	public void flagAboutToRename() {
302		this.aboutToRename = true;
303	}
304
305	public long[] getPgpKeyIds() {
306		List<Long> ids = new ArrayList<>();
307		for (User user : getUsers()) {
308			if (user.getPgpKeyId() != 0) {
309				ids.add(user.getPgpKeyId());
310			}
311		}
312		long[] primitivLongArray = new long[ids.size()];
313		for (int i = 0; i < ids.size(); ++i) {
314			primitivLongArray[i] = ids.get(i);
315		}
316		return primitivLongArray;
317	}
318
319	public boolean pgpKeysInUse() {
320		for (User user : getUsers()) {
321			if (user.getPgpKeyId() != 0) {
322				return true;
323			}
324		}
325		return false;
326	}
327
328	public boolean everybodyHasKeys() {
329		for (User user : getUsers()) {
330			if (user.getPgpKeyId() == 0) {
331				return false;
332			}
333		}
334		return true;
335	}
336
337	public Jid getJoinJid() {
338        try {
339            return Jid.fromString(this.conversation.getContactJid().toBareJid().toString() + "/"
340+ this.joinnick);
341        } catch (final InvalidJidException e) {
342            return null;
343        }
344    }
345
346	public String getTrueCounterpart(String counterpart) {
347		for (User user : this.getUsers()) {
348			if (user.getName().equals(counterpart)) {
349				return user.getJid();
350			}
351		}
352		return null;
353	}
354
355	public String getPassword() {
356		this.password = conversation
357				.getAttribute(Conversation.ATTRIBUTE_MUC_PASSWORD);
358		if (this.password == null && conversation.getBookmark() != null
359				&& conversation.getBookmark().getPassword() != null) {
360			return conversation.getBookmark().getPassword();
361		} else {
362			return this.password;
363		}
364	}
365
366	public void setPassword(String password) {
367		if (conversation.getBookmark() != null) {
368			conversation.getBookmark().setPassword(password);
369		} else {
370			this.password = password;
371		}
372		conversation
373				.setAttribute(Conversation.ATTRIBUTE_MUC_PASSWORD, password);
374	}
375
376	public Conversation getConversation() {
377		return this.conversation;
378	}
379}