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