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