OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
HGFriendsServerPostHandler.cs
Go to the documentation of this file.
1 /*
2  * Copyright (c) Contributors, http://opensimulator.org/
3  * See CONTRIBUTORS.TXT for a full list of copyright holders.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * * Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * * Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * * Neither the name of the OpenSimulator Project nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19  * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 using Nini.Config;
29 using log4net;
30 using System;
31 using System.Reflection;
32 using System.IO;
33 using System.Net;
34 using System.Text;
35 using System.Text.RegularExpressions;
36 using System.Xml;
37 using System.Xml.Serialization;
38 using System.Collections.Generic;
39 using OpenSim.Server.Base;
40 using OpenSim.Services.Interfaces;
43 using OpenSim.Framework;
44 using OpenSim.Framework.Servers.HttpServer;
45 using OpenMetaverse;
46 
47 namespace OpenSim.Server.Handlers.Hypergrid
48 {
50  {
51  private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
52 
53  private IUserAgentService m_UserAgentService;
54  private IFriendsSimConnector m_FriendsLocalSimConnector;
55  private IHGFriendsService m_TheService;
56 
58  base("POST", "/hgfriends")
59  {
60  m_TheService = service;
61  m_UserAgentService = uas;
62  m_FriendsLocalSimConnector = friendsConn;
63 
64  m_log.DebugFormat("[HGFRIENDS HANDLER]: HGFriendsServerPostHandler is On ({0})",
65  (m_FriendsLocalSimConnector == null ? "robust" : "standalone"));
66 
67  if (m_TheService == null)
68  m_log.ErrorFormat("[HGFRIENDS HANDLER]: TheService is null!");
69  }
70 
71  protected override byte[] ProcessRequest(string path, Stream requestData,
72  IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
73  {
74  StreamReader sr = new StreamReader(requestData);
75  string body = sr.ReadToEnd();
76  sr.Close();
77  body = body.Trim();
78 
79  //m_log.DebugFormat("[XXX]: query String: {0}", body);
80 
81  try
82  {
83  Dictionary<string, object> request =
84  ServerUtils.ParseQueryString(body);
85 
86  if (!request.ContainsKey("METHOD"))
87  return FailureResult();
88 
89  string method = request["METHOD"].ToString();
90 
91  switch (method)
92  {
93  case "getfriendperms":
94  return GetFriendPerms(request);
95 
96  case "newfriendship":
97  return NewFriendship(request);
98 
99  case "deletefriendship":
100  return DeleteFriendship(request);
101 
102  /* Same as inter-sim */
103  case "friendship_offered":
104  return FriendshipOffered(request);
105 
106  case "validate_friendship_offered":
107  return ValidateFriendshipOffered(request);
108 
109  case "statusnotification":
110  return StatusNotification(request);
111  /*
112  case "friendship_approved":
113  return FriendshipApproved(request);
114 
115  case "friendship_denied":
116  return FriendshipDenied(request);
117 
118  case "friendship_terminated":
119  return FriendshipTerminated(request);
120 
121  case "grant_rights":
122  return GrantRights(request);
123  */
124  }
125 
126  m_log.DebugFormat("[HGFRIENDS HANDLER]: unknown method {0}", method);
127  }
128  catch (Exception e)
129  {
130  m_log.DebugFormat("[HGFRIENDS HANDLER]: Exception {0}", e);
131  }
132 
133  return FailureResult();
134  }
135 
136  #region Method-specific handlers
137 
138  byte[] GetFriendPerms(Dictionary<string, object> request)
139  {
140  if (!VerifyServiceKey(request))
141  return FailureResult();
142 
143  UUID principalID = UUID.Zero;
144  if (request.ContainsKey("PRINCIPALID"))
145  UUID.TryParse(request["PRINCIPALID"].ToString(), out principalID);
146  else
147  {
148  m_log.WarnFormat("[HGFRIENDS HANDLER]: no principalID in request to get friend perms");
149  return FailureResult();
150  }
151 
152  UUID friendID = UUID.Zero;
153  if (request.ContainsKey("FRIENDID"))
154  UUID.TryParse(request["FRIENDID"].ToString(), out friendID);
155  else
156  {
157  m_log.WarnFormat("[HGFRIENDS HANDLER]: no friendID in request to get friend perms");
158  return FailureResult();
159  }
160 
161  int perms = m_TheService.GetFriendPerms(principalID, friendID);
162  if (perms < 0)
163  return FailureResult("Friend not found");
164 
165  return SuccessResult(perms.ToString());
166  }
167 
168  byte[] NewFriendship(Dictionary<string, object> request)
169  {
170  bool verified = VerifyServiceKey(request);
171 
172  FriendInfo friend = new FriendInfo(request);
173 
174  bool success = m_TheService.NewFriendship(friend, verified);
175 
176  if (success)
177  return SuccessResult();
178  else
179  return FailureResult();
180  }
181 
182  byte[] DeleteFriendship(Dictionary<string, object> request)
183  {
184  FriendInfo friend = new FriendInfo(request);
185  string secret = string.Empty;
186  if (request.ContainsKey("SECRET"))
187  secret = request["SECRET"].ToString();
188 
189  if (secret == string.Empty)
190  return BoolResult(false);
191 
192  bool success = m_TheService.DeleteFriendship(friend, secret);
193 
194  return BoolResult(success);
195  }
196 
197  byte[] FriendshipOffered(Dictionary<string, object> request)
198  {
199  UUID fromID = UUID.Zero;
200  UUID toID = UUID.Zero;
201  string message = string.Empty;
202  string name = string.Empty;
203 
204  if (!request.ContainsKey("FromID") || !request.ContainsKey("ToID"))
205  return BoolResult(false);
206 
207  if (!UUID.TryParse(request["ToID"].ToString(), out toID))
208  return BoolResult(false);
209 
210  message = request["Message"].ToString();
211 
212  if (!UUID.TryParse(request["FromID"].ToString(), out fromID))
213  return BoolResult(false);
214 
215  if (request.ContainsKey("FromName"))
216  name = request["FromName"].ToString();
217 
218  bool success = m_TheService.FriendshipOffered(fromID, name, toID, message);
219 
220  return BoolResult(success);
221  }
222 
223  byte[] ValidateFriendshipOffered(Dictionary<string, object> request)
224  {
225  FriendInfo friend = new FriendInfo(request);
226  UUID friendID = UUID.Zero;
227  if (!UUID.TryParse(friend.Friend, out friendID))
228  return BoolResult(false);
229 
230  bool success = m_TheService.ValidateFriendshipOffered(friend.PrincipalID, friendID);
231 
232  return BoolResult(success);
233  }
234 
235  byte[] StatusNotification(Dictionary<string, object> request)
236  {
237  UUID principalID = UUID.Zero;
238  if (request.ContainsKey("userID"))
239  UUID.TryParse(request["userID"].ToString(), out principalID);
240  else
241  {
242  m_log.WarnFormat("[HGFRIENDS HANDLER]: no userID in request to notify");
243  return FailureResult();
244  }
245 
246  bool online = true;
247  if (request.ContainsKey("online"))
248  Boolean.TryParse(request["online"].ToString(), out online);
249  else
250  {
251  m_log.WarnFormat("[HGFRIENDS HANDLER]: no online in request to notify");
252  return FailureResult();
253  }
254 
255  List<string> friends = new List<string>();
256  int i = 0;
257  foreach (KeyValuePair<string, object> kvp in request)
258  {
259  if (kvp.Key.Equals("friend_" + i.ToString()))
260  {
261  friends.Add(kvp.Value.ToString());
262  i++;
263  }
264  }
265 
266  List<UUID> onlineFriends = m_TheService.StatusNotification(friends, principalID, online);
267 
268  Dictionary<string, object> result = new Dictionary<string, object>();
269  if ((onlineFriends == null) || ((onlineFriends != null) && (onlineFriends.Count == 0)))
270  result["RESULT"] = "NULL";
271  else
272  {
273  i = 0;
274  foreach (UUID f in onlineFriends)
275  {
276  result["friend_" + i] = f.ToString();
277  i++;
278  }
279  }
280 
281  string xmlString = ServerUtils.BuildXmlResponse(result);
282 
283  //m_log.DebugFormat("[GRID HANDLER]: resp string: {0}", xmlString);
284  return Util.UTF8NoBomEncoding.GetBytes(xmlString);
285  }
286 
287  #endregion
288 
289  #region Misc
290 
291  private bool VerifyServiceKey(Dictionary<string, object> request)
292  {
293  if (!request.ContainsKey("KEY") || !request.ContainsKey("SESSIONID"))
294  {
295  m_log.WarnFormat("[HGFRIENDS HANDLER]: ignoring request without Key or SessionID");
296  return false;
297  }
298 
299  if (request["KEY"] == null || request["SESSIONID"] == null)
300  return false;
301 
302  string serviceKey = request["KEY"].ToString();
303  string sessionStr = request["SESSIONID"].ToString();
304 
305  UUID sessionID;
306  if (!UUID.TryParse(sessionStr, out sessionID) || serviceKey == string.Empty)
307  return false;
308 
309  if (!m_UserAgentService.VerifyAgent(sessionID, serviceKey))
310  {
311  m_log.WarnFormat("[HGFRIENDS HANDLER]: Key {0} for session {1} did not match existing key. Ignoring request", serviceKey, sessionID);
312  return false;
313  }
314 
315  m_log.DebugFormat("[HGFRIENDS HANDLER]: Verification ok");
316  return true;
317  }
318 
319  private byte[] SuccessResult()
320  {
321  XmlDocument doc = new XmlDocument();
322 
323  XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration,
324  "", "");
325 
326  doc.AppendChild(xmlnode);
327 
328  XmlElement rootElement = doc.CreateElement("", "ServerResponse",
329  "");
330 
331  doc.AppendChild(rootElement);
332 
333  XmlElement result = doc.CreateElement("", "Result", "");
334  result.AppendChild(doc.CreateTextNode("Success"));
335 
336  rootElement.AppendChild(result);
337 
338  return Util.DocToBytes(doc);
339  }
340 
341  private byte[] SuccessResult(string value)
342  {
343  XmlDocument doc = new XmlDocument();
344 
345  XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration,
346  "", "");
347 
348  doc.AppendChild(xmlnode);
349 
350  XmlElement rootElement = doc.CreateElement("", "ServerResponse",
351  "");
352 
353  doc.AppendChild(rootElement);
354 
355  XmlElement result = doc.CreateElement("", "RESULT", "");
356  result.AppendChild(doc.CreateTextNode("Success"));
357 
358  rootElement.AppendChild(result);
359 
360  XmlElement message = doc.CreateElement("", "Value", "");
361  message.AppendChild(doc.CreateTextNode(value));
362 
363  rootElement.AppendChild(message);
364 
365  return Util.DocToBytes(doc);
366  }
367 
368 
369  private byte[] FailureResult()
370  {
371  return FailureResult(String.Empty);
372  }
373 
374  private byte[] FailureResult(string msg)
375  {
376  XmlDocument doc = new XmlDocument();
377 
378  XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration,
379  "", "");
380 
381  doc.AppendChild(xmlnode);
382 
383  XmlElement rootElement = doc.CreateElement("", "ServerResponse",
384  "");
385 
386  doc.AppendChild(rootElement);
387 
388  XmlElement result = doc.CreateElement("", "RESULT", "");
389  result.AppendChild(doc.CreateTextNode("Failure"));
390 
391  rootElement.AppendChild(result);
392 
393  XmlElement message = doc.CreateElement("", "Message", "");
394  message.AppendChild(doc.CreateTextNode(msg));
395 
396  rootElement.AppendChild(message);
397 
398  return Util.DocToBytes(doc);
399  }
400 
401  private byte[] BoolResult(bool value)
402  {
403  XmlDocument doc = new XmlDocument();
404 
405  XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration,
406  "", "");
407 
408  doc.AppendChild(xmlnode);
409 
410  XmlElement rootElement = doc.CreateElement("", "ServerResponse",
411  "");
412 
413  doc.AppendChild(rootElement);
414 
415  XmlElement result = doc.CreateElement("", "RESULT", "");
416  result.AppendChild(doc.CreateTextNode(value.ToString()));
417 
418  rootElement.AppendChild(result);
419 
420  return Util.DocToBytes(doc);
421  }
422 
423  #endregion
424  }
425 }
override byte[] ProcessRequest(string path, Stream requestData, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
HGFriendsServerPostHandler(IHGFriendsService service, IUserAgentService uas, IFriendsSimConnector friendsConn)
OpenSim.Services.Interfaces.FriendInfo FriendInfo
OpenSim.Services.Interfaces.GridRegion GridRegion