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 x = packet.findChild("x","http://jabber.org/protocol/muc#user");
162				if (x != null) {
163					Element item = x.findChild("item");
164					if (item != null) {
165						user.setName(name);
166						user.setAffiliation(item.getAttribute("affiliation"));
167						user.setRole(item.getAttribute("role"));
168						user.setJid(item.getAttribute("jid"));
169						user.setName(name);
170						if (name.equals(this.joinnick)) {
171							this.isOnline = true;
172							this.error = ERROR_NO_ERROR;
173							self = user;
174							if (aboutToRename) {
175								if (renameListener != null) {
176									renameListener.onRename(true);
177								}
178								aboutToRename = false;
179							}
180						} else {
181							addUser(user);
182						}
183						if (pgp != null) {
184							Element signed = packet.findChild("x", "jabber:x:signed");
185							if (signed != null) {
186								Element status = packet.findChild("status");
187								String msg;
188								if (status != null) {
189									msg = status.getContent();
190								} else {
191									msg = "";
192								}
193								user.setPgpKeyId(pgp.fetchKeyId(account, msg,
194										signed.getContent()));
195							}
196						}
197					}
198				}
199			} else if (type.equals("unavailable") && name.equals(this.joinnick)) {
200				Element x = packet.findChild("x",
201						"http://jabber.org/protocol/muc#user");
202				if (x != null) {
203					Element status = x.findChild("status");
204					if (status != null) {
205						String code = status.getAttribute("code");
206						if (STATUS_CODE_KICKED.equals(code)) {
207							this.isOnline = false;
208							this.error = KICKED_FROM_ROOM;
209						} else if (STATUS_CODE_BANNED.equals(code)) {
210							this.isOnline = false;
211							this.error = ERROR_BANNED;
212						}
213					}
214				}
215			} else if (type.equals("unavailable")) {
216				deleteUser(packet.getAttribute("from").split("/", 2)[1]);
217			} else if (type.equals("error")) {
218				Element error = packet.findChild("error");
219				if (error != null && error.hasChild("conflict")) {
220					if (aboutToRename) {
221						if (renameListener != null) {
222							renameListener.onRename(false);
223						}
224						aboutToRename = false;
225						this.setJoinNick(getActualNick());
226					} else {
227						this.error = ERROR_NICK_IN_USE;
228					}
229				} else if (error != null && error.hasChild("not-authorized")) {
230					this.error = ERROR_PASSWORD_REQUIRED;
231				} else if (error != null && error.hasChild("forbidden")) {
232					this.error = ERROR_BANNED;
233				} else if (error != null
234						&& error.hasChild("registration-required")) {
235					this.error = ERROR_MEMBERS_ONLY;
236				}
237			}
238		}
239	}
240
241	public List<User> getUsers() {
242		return this.users;
243	}
244
245	public String getProposedNick() {
246		if (conversation.getBookmark() != null
247				&& conversation.getBookmark().getNick() != null) {
248			return conversation.getBookmark().getNick();
249		} else {
250			if (!conversation.getContactJid().isBareJid()) {
251				return conversation.getContactJid().getResourcepart();
252			} else {
253				return account.getUsername();
254			}
255		}
256	}
257
258	public String getActualNick() {
259		if (this.self.getName() != null) {
260			return this.self.getName();
261		} else {
262			return this.getProposedNick();
263		}
264	}
265
266	public void setJoinNick(String nick) {
267		this.joinnick = nick;
268	}
269
270	public boolean online() {
271		return this.isOnline;
272	}
273
274	public int getError() {
275		return this.error;
276	}
277
278	public void setOnRenameListener(OnRenameListener listener) {
279		this.renameListener = listener;
280	}
281
282	public OnRenameListener getOnRenameListener() {
283		return this.renameListener;
284	}
285
286	public void setOffline() {
287		this.users.clear();
288		this.error = 0;
289		this.isOnline = false;
290	}
291
292	public User getSelf() {
293		return self;
294	}
295
296	public void setSubject(String content) {
297		this.subject = content;
298	}
299
300	public String getSubject() {
301		return this.subject;
302	}
303
304	public void flagAboutToRename() {
305		this.aboutToRename = true;
306	}
307
308	public long[] getPgpKeyIds() {
309		List<Long> ids = new ArrayList<>();
310		for (User user : getUsers()) {
311			if (user.getPgpKeyId() != 0) {
312				ids.add(user.getPgpKeyId());
313			}
314		}
315		long[] primitivLongArray = new long[ids.size()];
316		for (int i = 0; i < ids.size(); ++i) {
317			primitivLongArray[i] = ids.get(i);
318		}
319		return primitivLongArray;
320	}
321
322	public boolean pgpKeysInUse() {
323		for (User user : getUsers()) {
324			if (user.getPgpKeyId() != 0) {
325				return true;
326			}
327		}
328		return false;
329	}
330
331	public boolean everybodyHasKeys() {
332		for (User user : getUsers()) {
333			if (user.getPgpKeyId() == 0) {
334				return false;
335			}
336		}
337		return true;
338	}
339
340	public Jid getJoinJid() {
341        try {
342            return Jid.fromString(this.conversation.getContactJid().toBareJid().toString() + "/"
343+ this.joinnick);
344        } catch (final InvalidJidException e) {
345            return null;
346        }
347    }
348
349	public String getTrueCounterpart(String counterpart) {
350		for (User user : this.getUsers()) {
351			if (user.getName().equals(counterpart)) {
352				return user.getJid();
353			}
354		}
355		return null;
356	}
357
358	public String getPassword() {
359		this.password = conversation
360				.getAttribute(Conversation.ATTRIBUTE_MUC_PASSWORD);
361		if (this.password == null && conversation.getBookmark() != null
362				&& conversation.getBookmark().getPassword() != null) {
363			return conversation.getBookmark().getPassword();
364		} else {
365			return this.password;
366		}
367	}
368
369	public void setPassword(String password) {
370		if (conversation.getBookmark() != null) {
371			conversation.getBookmark().setPassword(password);
372		} else {
373			this.password = password;
374		}
375		conversation
376				.setAttribute(Conversation.ATTRIBUTE_MUC_PASSWORD, password);
377	}
378
379	public Conversation getConversation() {
380		return this.conversation;
381	}
382}