1 /*
2  * privacymanager.cpp
3  * Copyright (C) 2006  Remko Troncon
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  *
19  */
20 #include "privacymanager.h"
21 #include "xmpp_xmlcommon.h"
22 #include "xmpp_jid.h"
23 
24 #include "jabber_protocol_debug.h"
25 #include "jabberprotocol.h"
26 
27 #define PRIVACY_NS "jabber:iq:privacy"
28 
29 using namespace XMPP;
30 
31 // -----------------------------------------------------------------------------
32 //
33 
PrivacyListListener(Task * parent)34 PrivacyListListener::PrivacyListListener ( Task* parent ) : Task ( parent ) {
35 }
36 
take(const QDomElement & e)37 bool PrivacyListListener::take ( const QDomElement &e ) {
38 	if ( e.tagName() != QLatin1String("iq") || e.attribute ( QStringLiteral("type") ) != QLatin1String("set") )
39 		return false;
40 
41 	QString ns = queryNS ( e );
42 	if ( ns == QLatin1String("jabber:iq:privacy") ) {
43 		// TODO: Do something with update
44 
45 		// Confirm receipt
46 		QDomElement iq = createIQ ( doc(), QStringLiteral("result"), e.attribute ( QStringLiteral("from") ), e.attribute ( QStringLiteral("id") ) );
47 		send ( iq );
48 		return true;
49 	}
50 
51 	return false;
52 }
53 
54 // -----------------------------------------------------------------------------
55 
GetPrivacyListsTask(Task * parent)56 GetPrivacyListsTask::GetPrivacyListsTask ( Task* parent ) : Task ( parent ) {
57 	iq_ = createIQ ( doc(), QStringLiteral("get"), QLatin1String(""), id() );
58 	QDomElement query = doc()->createElement ( QStringLiteral("query") );
59 	query.setAttribute ( QStringLiteral("xmlns"),PRIVACY_NS );
60 	iq_.appendChild ( query );
61 }
62 
onGo()63 void GetPrivacyListsTask::onGo() {
64 	send ( iq_ );
65 }
66 
take(const QDomElement & x)67 bool GetPrivacyListsTask::take ( const QDomElement &x ) {
68 	if ( !iqVerify ( x, "", id() ) )
69 		return false;
70 
71     //qDebug (JABBER_PROTOCOL_LOG) << "Got reply for privacy lists.";
72 	if ( x.attribute ( QStringLiteral("type") ) == QLatin1String("result") ) {
73 		QDomElement tag, q = queryTag ( x );
74 
75 		for ( QDomNode n = q.firstChild(); !n.isNull(); n = n.nextSibling() ) {
76 			QDomElement e = n.toElement();
77 			if ( e.tagName() == QLatin1String("active") )
78 				active_ = e.attribute ( QStringLiteral("name") );
79 			else if ( e.tagName() == QLatin1String("default") )
80 				default_ = e.attribute ( QStringLiteral("name") );
81 			else if ( e.tagName() == QLatin1String("list") )
82 				lists_.append ( e.attribute ( QStringLiteral("name") ) );
83 			else
84                 qCWarning (JABBER_PROTOCOL_LOG) << "Unknown tag in privacy lists.";
85 
86 		}
87 		setSuccess();
88 	}
89 	else {
90 		setError ( x );
91 	}
92 	return true;
93 }
94 
lists()95 const QStringList& GetPrivacyListsTask::lists() {
96 	return lists_;
97 }
98 
defaultList()99 const QString& GetPrivacyListsTask::defaultList() {
100 	return default_;
101 }
102 
activeList()103 const QString& GetPrivacyListsTask::activeList() {
104 	return active_;
105 }
106 
107 // -----------------------------------------------------------------------------
108 
SetPrivacyListsTask(Task * parent)109 SetPrivacyListsTask::SetPrivacyListsTask ( Task* parent ) : Task ( parent ), changeDefault_ ( false ), changeActive_ ( false ), changeList_ ( false ), list_ ( QLatin1String("") ) {
110 }
111 
onGo()112 void SetPrivacyListsTask::onGo() {
113 	QDomElement iq_ = createIQ ( doc(), QStringLiteral("set"), QLatin1String(""), id() );
114 	QDomElement query = doc()->createElement ( QStringLiteral("query") );
115 	query.setAttribute ( QStringLiteral("xmlns"),PRIVACY_NS );
116 	iq_.appendChild ( query );
117 
118 	QDomElement e;
119 	if ( changeDefault_ ) {
120         //qDebug (JABBER_PROTOCOL_LOG) << "Changing default privacy list.";
121 		e = doc()->createElement ( QStringLiteral("default") );
122 		if ( !value_.isEmpty() )
123 			e.setAttribute ( QStringLiteral("name"),value_ );
124 	}
125 	else if ( changeActive_ ) {
126         //qDebug (JABBER_PROTOCOL_LOG) << "Changing active privacy list.";
127 		e = doc()->createElement ( QStringLiteral("active") );
128 		if ( !value_.isEmpty() )
129 			e.setAttribute ( QStringLiteral("name"),value_ );
130 	}
131 	else if ( changeList_ ) {
132         //qDebug (JABBER_PROTOCOL_LOG) << "Changing privacy list.";
133 		e = list_.toXml ( *doc() );
134 	}
135 	else {
136         qCWarning (JABBER_PROTOCOL_LOG) << "Empty active/default list change request.";
137 		return;
138 	}
139 
140 	query.appendChild ( e );
141 	send ( iq_ );
142 }
143 
setActive(const QString & active)144 void SetPrivacyListsTask::setActive ( const QString& active ) {
145 	value_ = active;
146 	changeDefault_ = false;
147 	changeActive_ = true;
148 	changeList_ = false;
149 }
150 
setDefault(const QString & d)151 void SetPrivacyListsTask::setDefault ( const QString& d ) {
152 	value_ = d;
153 	changeDefault_ = true;
154 	changeActive_ = false;
155 	changeList_ = true;
156 }
157 
setList(const PrivacyList & list)158 void SetPrivacyListsTask::setList ( const PrivacyList& list ) {
159     //qDebug (JABBER_PROTOCOL_LOG) << "setList: " << list.toString();
160 	list_ = list;
161 	changeDefault_ = false;
162 	changeActive_ = false;
163 	changeList_ = true;
164 }
165 
take(const QDomElement & x)166 bool SetPrivacyListsTask::take ( const QDomElement &x ) {
167 	if ( !iqVerify ( x, "", id() ) )
168 		return false;
169 
170 	if ( x.attribute ( QStringLiteral("type") ) == QLatin1String("result") ) {
171         //qDebug (JABBER_PROTOCOL_LOG) << "Got successful reply for list change.";
172 		setSuccess();
173 	}
174 	else {
175         qCWarning (JABBER_PROTOCOL_LOG) << "Got error reply for list change.";
176 		setError ( x );
177 	}
178 	return true;
179 }
180 
181 // -----------------------------------------------------------------------------
182 
GetPrivacyListTask(Task * parent,const QString & name)183 GetPrivacyListTask::GetPrivacyListTask ( Task* parent, const QString& name ) : Task ( parent ), name_ ( name ), list_ ( PrivacyList ( QLatin1String("") ) ) {
184 	iq_ = createIQ ( doc(), QStringLiteral("get"), QLatin1String(""), id() );
185 	QDomElement query = doc()->createElement ( QStringLiteral("query") );
186 	query.setAttribute ( QStringLiteral("xmlns"),PRIVACY_NS );
187 	iq_.appendChild ( query );
188 	QDomElement list = doc()->createElement ( QStringLiteral("list") );
189 	list.setAttribute ( QStringLiteral("name"),name );
190 	query.appendChild ( list );
191 }
192 
onGo()193 void GetPrivacyListTask::onGo() {
194     //qDebug (JABBER_PROTOCOL_LOG) << "privacy.cpp: Requesting privacy list %1." << name_;
195 	send ( iq_ );
196 }
197 
take(const QDomElement & x)198 bool GetPrivacyListTask::take ( const QDomElement &x ) {
199 	if ( !iqVerify ( x, "", id() ) )
200 		return false;
201 
202     //qDebug (JABBER_PROTOCOL_LOG) << qPrintable (QString("Got privacy list %1 reply.").arg(name_));
203 	if ( x.attribute ( QStringLiteral("type") ) == QLatin1String("result") ) {
204 		QDomElement q = queryTag ( x );
205 		QDomElement listTag = q.firstChildElement ( QStringLiteral("list") );
206 		if ( !listTag.isNull() ) {
207 			list_ = PrivacyList ( listTag );
208 		}
209 		else {
210             qCWarning (JABBER_PROTOCOL_LOG) << "No valid list found.";
211 		}
212 		setSuccess();
213 	}
214 	else {
215 		setError ( x );
216 	}
217 	return true;
218 }
219 
list()220 const PrivacyList& GetPrivacyListTask::list() {
221 	return list_;
222 }
223 
224 // -----------------------------------------------------------------------------
225 
PrivacyManager(XMPP::Task * rootTask)226 PrivacyManager::PrivacyManager ( XMPP::Task* rootTask ) : rootTask_ ( rootTask ), getDefault_waiting_ ( false ), block_waiting_ ( false )
227 {
228 	listener_ = new PrivacyListListener ( rootTask_ );
229 }
230 
~PrivacyManager()231 PrivacyManager::~PrivacyManager()
232 {
233 	delete listener_;
234 }
235 
requestListNames()236 void PrivacyManager::requestListNames()
237 {
238 	GetPrivacyListsTask* t = new GetPrivacyListsTask ( rootTask_ );
239 	connect ( t,SIGNAL (finished()),SLOT (receiveLists()) );
240 	t->go ( true );
241 }
242 
requestList(const QString & name)243 void PrivacyManager::requestList ( const QString& name )
244 {
245 	GetPrivacyListTask* t = new GetPrivacyListTask ( rootTask_, name );
246 	connect ( t,SIGNAL (finished()),SLOT (receiveList()) );
247 	t->go ( true );
248 }
249 
block(const QString & target)250 void PrivacyManager::block ( const QString& target )
251 {
252 	block_targets_.push_back ( target );
253 	if ( !block_waiting_ ) {
254 		block_waiting_ = true;
255 		connect ( this,SIGNAL (defaultListAvailable(PrivacyList)),SLOT (block_getDefaultList_success(PrivacyList)) );
256 		connect ( this,SIGNAL (defaultListError()),SLOT (block_getDefaultList_error()) );
257 		getDefaultList();
258 	}
259 }
260 
block_getDefaultList_success(const PrivacyList & l_)261 void PrivacyManager::block_getDefaultList_success ( const PrivacyList& l_ )
262 {
263 	PrivacyList l = l_;
264 	disconnect ( this,SIGNAL (defaultListAvailable(PrivacyList)),this,SLOT (block_getDefault_success(PrivacyList)) );
265 	disconnect ( this,SIGNAL (defaultListError()),this,SLOT (block_getDefault_error()) );
266 	block_waiting_ = false;
267 	while ( !block_targets_.isEmpty() )
268 		l.insertItem ( 0,PrivacyListItem::blockItem ( block_targets_.takeFirst() ) );
269 	changeList ( l );
270 }
271 
block_getDefaultList_error()272 void PrivacyManager::block_getDefaultList_error()
273 {
274 	disconnect ( this,SIGNAL (defaultListAvailable(PrivacyList)),this,SLOT (block_getDefault_success(PrivacyList)) );
275 	disconnect ( this,SIGNAL (defaultListError()),this,SLOT (block_getDefault_error()) );
276 	block_waiting_ = false;
277 	block_targets_.clear();
278 }
279 
getDefaultList()280 void PrivacyManager::getDefaultList()
281 {
282 	connect ( this,SIGNAL (listsReceived(QString,QString,QStringList)),SLOT (getDefault_listsReceived(QString,QString,QStringList)) );
283 	connect ( this,SIGNAL (listsError()),SLOT (getDefault_listsError()) );
284 	requestListNames();
285 }
286 
getDefault_listsReceived(const QString & defaultList,const QString &,const QStringList &)287 void PrivacyManager::getDefault_listsReceived ( const QString& defaultList, const QString&, const QStringList& )
288 {
289 	disconnect ( this,SIGNAL (listsReceived(QString,QString,QStringList)),this,SLOT (getDefault_listsReceived(QString,QString,QStringList)) );
290 	disconnect ( this,SIGNAL (listsError()),this,SLOT (getDefault_listsError()) );
291 
292 	getDefault_default_ = defaultList;
293 	if ( !defaultList.isEmpty() ) {
294 		getDefault_waiting_ = true;
295 		connect ( this,SIGNAL (listReceived(PrivacyList)),SLOT (getDefault_listReceived(PrivacyList)) );
296 		connect ( this,SIGNAL (listError()),SLOT (getDefault_listError()) );
297 		requestList ( defaultList );
298 	}
299 	else {
300 		emit defaultListAvailable ( PrivacyList ( QLatin1String("") ) );
301 	}
302 }
303 
getDefault_listsError()304 void PrivacyManager::getDefault_listsError()
305 {
306 	disconnect ( this,SIGNAL (listsReceived(QString,QString,QStringList)),this,SLOT (getDefault_listsReceived(QString,QString,QStringList)) );
307 	disconnect ( this,SIGNAL (listsError()),this,SLOT (getDefault_listsError()) );
308 	emit defaultListError();
309 }
310 
getDefault_listReceived(const PrivacyList & l)311 void PrivacyManager::getDefault_listReceived ( const PrivacyList& l )
312 {
313 	if ( l.name() == getDefault_default_ && getDefault_waiting_ ) {
314 		disconnect ( this,SIGNAL (listReceived(PrivacyList)),this,SLOT (getDefault_listReceived(PrivacyList)) );
315 		disconnect ( this,SIGNAL (listError()),this,SLOT (getDefault_listError()) );
316 		getDefault_waiting_ = false;
317 		emit defaultListAvailable ( l );
318 	}
319 }
320 
getDefault_listError()321 void PrivacyManager::getDefault_listError()
322 {
323 	emit defaultListError();
324 }
325 
changeDefaultList(const QString & name)326 void PrivacyManager::changeDefaultList ( const QString& name )
327 {
328 	SetPrivacyListsTask* t = new SetPrivacyListsTask ( rootTask_ );
329 	t->setDefault ( name );
330 	connect ( t,SIGNAL (finished()),SLOT (changeDefaultList_finished()) );
331 	t->go ( true );
332 }
333 
changeDefaultList_finished()334 void PrivacyManager::changeDefaultList_finished()
335 {
336 	SetPrivacyListsTask *t = ( SetPrivacyListsTask* ) sender();
337 	if ( !t ) {
338         qCWarning (JABBER_PROTOCOL_LOG) << "Unexpected sender.";
339 		return;
340 	}
341 
342 	if ( t->success() ) {
343 		emit changeDefaultList_success();
344 	}
345 	else {
346 		emit changeDefaultList_error();
347 	}
348 }
349 
changeActiveList(const QString & name)350 void PrivacyManager::changeActiveList ( const QString& name )
351 {
352 	SetPrivacyListsTask* t = new SetPrivacyListsTask ( rootTask_ );
353 	t->setActive ( name );
354 	connect ( t,SIGNAL (finished()),SLOT (changeActiveList_finished()) );
355 	t->go ( true );
356 }
357 
changeActiveList_finished()358 void PrivacyManager::changeActiveList_finished()
359 {
360 	SetPrivacyListsTask *t = ( SetPrivacyListsTask* ) sender();
361 	if ( !t ) {
362         qCWarning (JABBER_PROTOCOL_LOG) << "Unexpected sender.";
363 		return;
364 	}
365 
366 	if ( t->success() ) {
367 		emit changeActiveList_success();
368 	}
369 	else {
370 		emit changeActiveList_error();
371 	}
372 }
373 
changeList(const PrivacyList & list)374 void PrivacyManager::changeList ( const PrivacyList& list )
375 {
376 	SetPrivacyListsTask* t = new SetPrivacyListsTask ( rootTask_ );
377 	t->setList ( list );
378 	connect ( t,SIGNAL (finished()),SLOT (changeList_finished()) );
379 	t->go ( true );
380 }
381 
changeList_finished()382 void PrivacyManager::changeList_finished()
383 {
384 	SetPrivacyListsTask *t = ( SetPrivacyListsTask* ) sender();
385 	if ( !t ) {
386         qCWarning (JABBER_PROTOCOL_LOG) << "Unexpected sender.";
387 		return;
388 	}
389 
390 	if ( t->success() ) {
391 		emit changeList_success();
392 	}
393 	else {
394 		emit changeList_error();
395 	}
396 }
397 
receiveLists()398 void PrivacyManager::receiveLists()
399 {
400 	GetPrivacyListsTask *t = ( GetPrivacyListsTask* ) sender();
401 	if ( !t ) {
402         qCWarning (JABBER_PROTOCOL_LOG) << "Unexpected sender.";
403 		return;
404 	}
405 
406 	if ( t->success() ) {
407 		emit listsReceived ( t->defaultList(),t->activeList(),t->lists() );
408 	}
409 	else {
410         qDebug (JABBER_PROTOCOL_LOG) << "Error in lists receiving.";
411 		emit listsError();
412 	}
413 }
414 
receiveList()415 void PrivacyManager::receiveList()
416 {
417 	GetPrivacyListTask *t = ( GetPrivacyListTask* ) sender();
418 	if ( !t ) {
419         qDebug (JABBER_PROTOCOL_LOG) << "Unexpected sender.";
420 		return;
421 	}
422 
423 	if ( t->success() ) {
424 		emit listReceived ( t->list() );
425 	}
426 	else {
427         qDebug (JABBER_PROTOCOL_LOG) << "Error in list receiving.";
428 		emit listError();
429 	}
430 }
431 
432