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
112 public MucOptions(Account account) {
113 this.account = account;
114 }
115
116 public void deleteUser(String name) {
117 for (int i = 0; i < users.size(); ++i) {
118 if (users.get(i).getName().equals(name)) {
119 users.remove(i);
120 return;
121 }
122 }
123 }
124
125 public void addUser(User user) {
126 for (int i = 0; i < users.size(); ++i) {
127 if (users.get(i).getName().equals(user.getName())) {
128 users.set(i, user);
129 return;
130 }
131 }
132 users.add(user);
133 }
134
135 public void processPacket(PresencePacket packet, PgpEngine pgp) {
136 String[] fromParts = packet.getFrom().split("/");
137 if (fromParts.length >= 2) {
138 String name = fromParts[1];
139 String type = packet.getAttribute("type");
140 if (type == null) {
141 User user = new User();
142 Element item = packet.findChild("x",
143 "http://jabber.org/protocol/muc#user")
144 .findChild("item");
145 user.setName(name);
146 user.setAffiliation(item.getAttribute("affiliation"));
147 user.setRole(item.getAttribute("role"));
148 user.setJid(item.getAttribute("jid"));
149 user.setName(name);
150 if (name.equals(this.joinnick)) {
151 this.isOnline = true;
152 this.error = ERROR_NO_ERROR;
153 self = user;
154 if (aboutToRename) {
155 if (renameListener != null) {
156 renameListener.onRename(true);
157 }
158 aboutToRename = false;
159 }
160 } else {
161 addUser(user);
162 }
163 if (pgp != null) {
164 Element x = packet.findChild("x", "jabber:x:signed");
165 if (x != null) {
166 Element status = packet.findChild("status");
167 String msg;
168 if (status != null) {
169 msg = status.getContent();
170 } else {
171 msg = "";
172 }
173 user.setPgpKeyId(pgp.fetchKeyId(account, msg,
174 x.getContent()));
175 }
176 }
177 } else if (type.equals("unavailable")) {
178 deleteUser(packet.getAttribute("from").split("/")[1]);
179 } else if (type.equals("error")) {
180 Element error = packet.findChild("error");
181 if (error.hasChild("conflict")) {
182 if (aboutToRename) {
183 if (renameListener != null) {
184 renameListener.onRename(false);
185 }
186 aboutToRename = false;
187 this.setJoinNick(getActualNick());
188 } else {
189 this.error = ERROR_NICK_IN_USE;
190 }
191 } else if (error.hasChild("not-authorized")) {
192 this.error = ERROR_PASSWORD_REQUIRED;
193 }
194 }
195 }
196 }
197
198 public List<User> getUsers() {
199 return this.users;
200 }
201
202 public String getProposedNick() {
203 String[] mucParts = conversation.getContactJid().split("/");
204 if (conversation.getBookmark() != null
205 && conversation.getBookmark().getNick() != null) {
206 return conversation.getBookmark().getNick();
207 } else {
208 if (mucParts.length == 2) {
209 return mucParts[1];
210 } else {
211 return account.getUsername();
212 }
213 }
214 }
215
216 public String getActualNick() {
217 if (this.self.getName() != null) {
218 return this.self.getName();
219 } else {
220 return this.getProposedNick();
221 }
222 }
223
224 public void setJoinNick(String nick) {
225 this.joinnick = nick;
226 }
227
228 public void setConversation(Conversation conversation) {
229 this.conversation = conversation;
230 }
231
232 public boolean online() {
233 return this.isOnline;
234 }
235
236 public int getError() {
237 return this.error;
238 }
239
240 public void setOnRenameListener(OnRenameListener listener) {
241 this.renameListener = listener;
242 }
243
244 public OnRenameListener getOnRenameListener() {
245 return this.renameListener;
246 }
247
248 public void setOffline() {
249 this.users.clear();
250 this.error = 0;
251 this.isOnline = false;
252 }
253
254 public User getSelf() {
255 return self;
256 }
257
258 public void setSubject(String content) {
259 this.subject = content;
260 }
261
262 public String getSubject() {
263 return this.subject;
264 }
265
266 public void flagAboutToRename() {
267 this.aboutToRename = true;
268 }
269
270 public long[] getPgpKeyIds() {
271 List<Long> ids = new ArrayList<Long>();
272 for (User user : getUsers()) {
273 if (user.getPgpKeyId() != 0) {
274 ids.add(user.getPgpKeyId());
275 }
276 }
277 long[] primitivLongArray = new long[ids.size()];
278 for (int i = 0; i < ids.size(); ++i) {
279 primitivLongArray[i] = ids.get(i);
280 }
281 return primitivLongArray;
282 }
283
284 public boolean pgpKeysInUse() {
285 for (User user : getUsers()) {
286 if (user.getPgpKeyId() != 0) {
287 return true;
288 }
289 }
290 return false;
291 }
292
293 public boolean everybodyHasKeys() {
294 for (User user : getUsers()) {
295 if (user.getPgpKeyId() == 0) {
296 return false;
297 }
298 }
299 return true;
300 }
301
302 public String getJoinJid() {
303 return this.conversation.getContactJid().split("/")[0] + "/"
304 + this.joinnick;
305 }
306
307 public String getTrueCounterpart(String counterpart) {
308 for (User user : this.getUsers()) {
309 if (user.getName().equals(counterpart)) {
310 return user.getJid();
311 }
312 }
313 return null;
314 }
315
316 public String getPassword() {
317 return this.password;
318 }
319
320 public void setPassword(String password) {
321 this.password = password;
322 }
323}