gloox  1.0
privacymanager.cpp
1 /*
2  Copyright (c) 2005-2009 by Jakob Schroeter <js@camaya.net>
3  This file is part of the gloox library. http://camaya.net/gloox
4 
5  This software is distributed under a license. The full license
6  agreement can be found in the file LICENSE in this distribution.
7  This software may not be copied, modified, sold or distributed
8  other than expressed in the named license agreement.
9 
10  This software is distributed without any warranty.
11 */
12 
13 
14 
15 #include "privacymanager.h"
16 #include "clientbase.h"
17 #include "error.h"
18 
19 namespace gloox
20 {
21 
22  // ---- PrivacyManager::Query ----
23  PrivacyManager::Query::Query( const Tag* tag )
24  : StanzaExtension( ExtPrivacy )
25  {
26  if( !tag )
27  return;
28 
29  const TagList& l = tag->children();
30  TagList::const_iterator it = l.begin();
31  for( ; it != l.end(); ++it )
32  {
33  const std::string& name = (*it)->findAttribute( "name" );
34  if( (*it)->name() == "default" )
35  m_default = name;
36  else if( (*it)->name() == "active" )
37  m_active = name;
38  else if( (*it)->name() == "list" )
39  {
40  m_names.push_back( name );
41 
42  const TagList& l = (*it)->children();
43  TagList::const_iterator it_l = l.begin();
44  for( ; it_l != l.end(); ++it_l )
45  {
48  int packetType = 0;
49 
50  const std::string& t = (*it_l)->findAttribute( TYPE );
51  if( t == "jid" )
52  type = PrivacyItem::TypeJid;
53  else if( t == "group" )
55  else if( t == "subscription" )
57  else
59 
60  const std::string& a = (*it_l)->findAttribute( "action" );
61  if( a == "allow" )
62  action = PrivacyItem::ActionAllow;
63  else if( a == "deny" )
64  action = PrivacyItem::ActionDeny;
65  else
66  action = PrivacyItem::ActionAllow;
67 
68  const std::string& value = (*it_l)->findAttribute( "value" );
69 
70  const TagList& c = (*it_l)->children();
71  TagList::const_iterator it_c = c.begin();
72  for( ; it_c != c.end(); ++it_c )
73  {
74  if( (*it_c)->name() == "iq" )
75  packetType |= PrivacyItem::PacketIq;
76  else if( (*it_c)->name() == "presence-out" )
77  packetType |= PrivacyItem::PacketPresenceOut;
78  else if( (*it_c)->name() == "presence-in" )
79  packetType |= PrivacyItem::PacketPresenceIn;
80  else if( (*it_c)->name() == "message" )
81  packetType |= PrivacyItem::PacketMessage;
82  }
83 
84  PrivacyItem item( type, action, packetType, value );
85  m_items.push_back( item );
86  }
87  }
88  }
89  }
90 
91  PrivacyManager::Query::Query( IdType context, const std::string& name,
93  : StanzaExtension( ExtPrivacy ), m_context( context ), m_items( list )
94  {
95  m_names.push_back( name );
96  }
97 
98  PrivacyManager::Query::~Query()
99  {
100  }
101 
102  const std::string& PrivacyManager::Query::filterString() const
103  {
104  static const std::string filter = "/iq/query[@xmlns='" + XMLNS_PRIVACY + "']";
105  return filter;
106  }
107 
108  Tag* PrivacyManager::Query::tag() const
109  {
110  Tag* t = new Tag( "query" );
111  t->setXmlns( XMLNS_PRIVACY );
112 
113  std::string child;
114  switch( m_context )
115  {
116  case PLRequestList:
117  case PLRemove:
118  case PLStore:
119  child = "list";
120  break;
121  case PLDefault:
122  case PLUnsetDefault:
123  child = "default";
124  break;
125  case PLActivate:
126  case PLUnsetActivate:
127  child = "active";
128  break;
129  default:
130  case PLRequestNames:
131  return t;
132  break;
133  }
134  Tag* c = new Tag( t, child );
135 
136  if( !m_names.empty() )
137  c->addAttribute( "name", (*m_names.begin()) );
138 
139  int count = 0;
140  PrivacyListHandler::PrivacyList::const_iterator it = m_items.begin();
141  for( ; it != m_items.end(); ++it )
142  {
143  Tag* i = new Tag( c, "item" );
144 
145  switch( (*it).type() )
146  {
148  i->addAttribute( TYPE, "jid" );
149  break;
151  i->addAttribute( TYPE, "group" );
152  break;
154  i->addAttribute( TYPE, "subscription" );
155  break;
156  default:
157  break;
158  }
159 
160  switch( (*it).action() )
161  {
163  i->addAttribute( "action", "allow" );
164  break;
166  i->addAttribute( "action", "deny" );
167  break;
168  }
169 
170  int pType = (*it).packetType();
171  if( pType != 15 )
172  {
173  if( pType & PrivacyItem::PacketMessage )
174  new Tag( i, "message" );
175  if( pType & PrivacyItem::PacketPresenceIn )
176  new Tag( i, "presence-in" );
177  if( pType & PrivacyItem::PacketPresenceOut )
178  new Tag( i, "presence-out" );
179  if( pType & PrivacyItem::PacketIq )
180  new Tag( i, "iq" );
181  }
182 
183  i->addAttribute( "value", (*it).value() );
184  i->addAttribute( "order", ++count );
185  }
186 
187  return t;
188  }
189  // ---- ~PrivacyManager::Query ----
190 
191  // ---- PrivacyManager ----
193  : m_parent( parent ), m_privacyListHandler( 0 )
194  {
195  if( m_parent )
196  {
197  m_parent->registerStanzaExtension( new Query() );
198  m_parent->registerIqHandler( this, ExtPrivacy );
199  }
200  }
201 
203  {
204  if( m_parent )
205  {
206  m_parent->removeIqHandler( this, ExtPrivacy );
207  m_parent->removeIDHandler( this );
208  }
209  }
210 
211  std::string PrivacyManager::operation( IdType context, const std::string& name )
212  {
213  const std::string& id = m_parent->getID();
214  IQ::IqType iqType = IQ::Set;
215  if( context == PLRequestNames || context == PLRequestList )
216  iqType = IQ::Get;
217  IQ iq( iqType, JID(), id );
218  iq.addExtension( new Query( context, name ) );
219  m_parent->send( iq, this, context );
220  return id;
221  }
222 
223  std::string PrivacyManager::store( const std::string& name, const PrivacyListHandler::PrivacyList& list )
224  {
225  if( list.empty() )
226  return EmptyString;
227 
228  const std::string& id = m_parent->getID();
229 
230  IQ iq( IQ::Set, JID(), id );
231  iq.addExtension( new Query( PLStore, name, list ) );
232  m_parent->send( iq, this, PLStore );
233  return id;
234  }
235 
236  bool PrivacyManager::handleIq( const IQ& iq )
237  {
238  const Query* q = iq.findExtension<Query>( ExtPrivacy );
239  if( iq.subtype() != IQ::Set || !m_privacyListHandler
240  || !q || q->name().empty() )
241  return false;
242 
243  m_privacyListHandler->handlePrivacyListChanged( q->name() );
244  IQ re( IQ::Result, JID(), iq.id() );
245  m_parent->send( re );
246  return true;
247  }
248 
249  void PrivacyManager::handleIqID( const IQ& iq, int context )
250  {
251  if( !m_privacyListHandler )
252  return;
253 
254  switch( iq.subtype() )
255  {
256  case IQ::Result:
257  switch( context )
258  {
259  case PLStore:
260  m_privacyListHandler->handlePrivacyListResult( iq.id(), ResultStoreSuccess );
261  break;
262  case PLActivate:
263  m_privacyListHandler->handlePrivacyListResult( iq.id(), ResultActivateSuccess );
264  break;
265  case PLDefault:
266  m_privacyListHandler->handlePrivacyListResult( iq.id(), ResultDefaultSuccess );
267  break;
268  case PLRemove:
269  m_privacyListHandler->handlePrivacyListResult( iq.id(), ResultRemoveSuccess );
270  break;
271  case PLRequestNames:
272  {
273  const Query* q = iq.findExtension<Query>( ExtPrivacy );
274  if( !q )
275  return;
276  m_privacyListHandler->handlePrivacyListNames( q->def(), q->active(),
277  q->names() );
278  break;
279  }
280  case PLRequestList:
281  {
282  const Query* q = iq.findExtension<Query>( ExtPrivacy );
283  if( !q )
284  return;
285  m_privacyListHandler->handlePrivacyList( q->name(), q->items() );
286  break;
287  }
288  }
289  break;
290 
291  case IQ::Error:
292  {
293  switch( iq.error()->error() )
294  {
295  case StanzaErrorConflict:
296  m_privacyListHandler->handlePrivacyListResult( iq.id(), ResultConflict );
297  break;
299  m_privacyListHandler->handlePrivacyListResult( iq.id(), ResultItemNotFound );
300  break;
302  m_privacyListHandler->handlePrivacyListResult( iq.id(), ResultBadRequest );
303  break;
304  default:
305  m_privacyListHandler->handlePrivacyListResult( iq.id(), ResultUnknownError );
306  break;
307  }
308  break;
309  }
310 
311  default:
312  break;
313  }
314  }
315 
316 }