aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs320
1 files changed, 320 insertions, 0 deletions
diff --git a/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs b/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs
new file mode 100644
index 0000000..5c89d0f
--- /dev/null
+++ b/OpenSim/Server/Handlers/Hypergrid/HGFriendsServerPostHandler.cs
@@ -0,0 +1,320 @@
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
28using Nini.Config;
29using log4net;
30using System;
31using System.Reflection;
32using System.IO;
33using System.Net;
34using System.Text;
35using System.Text.RegularExpressions;
36using System.Xml;
37using System.Xml.Serialization;
38using System.Collections.Generic;
39using OpenSim.Server.Base;
40using OpenSim.Services.Interfaces;
41using FriendInfo = OpenSim.Services.Interfaces.FriendInfo;
42using OpenSim.Framework;
43using OpenSim.Framework.Servers.HttpServer;
44using OpenMetaverse;
45
46namespace OpenSim.Server.Handlers.Hypergrid
47{
48 public class HGFriendsServerPostHandler : BaseStreamHandler
49 {
50 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
51
52 private IFriendsService m_FriendsService;
53 private IUserAgentService m_UserAgentService;
54
55 public HGFriendsServerPostHandler(IFriendsService service, IUserAgentService uservice) :
56 base("POST", "/hgfriends")
57 {
58 m_FriendsService = service;
59 m_UserAgentService = uservice;
60 m_log.DebugFormat("[HGFRIENDS HANDLER]: HGFriendsServerPostHandler is On");
61 }
62
63 public override byte[] Handle(string path, Stream requestData,
64 OSHttpRequest httpRequest, OSHttpResponse httpResponse)
65 {
66 StreamReader sr = new StreamReader(requestData);
67 string body = sr.ReadToEnd();
68 sr.Close();
69 body = body.Trim();
70
71 //m_log.DebugFormat("[XXX]: query String: {0}", body);
72
73 try
74 {
75 Dictionary<string, object> request =
76 ServerUtils.ParseQueryString(body);
77
78 if (!request.ContainsKey("METHOD"))
79 return FailureResult();
80
81 string method = request["METHOD"].ToString();
82
83 switch (method)
84 {
85 case "getfriendperms":
86 return GetFriendPerms(request);
87
88 case "newfriendship":
89 return NewFriendship(request);
90
91 case "deletefriendship":
92 return DeleteFriendship(request);
93 }
94 m_log.DebugFormat("[HGFRIENDS HANDLER]: unknown method {0} request {1}", method.Length, method);
95 }
96 catch (Exception e)
97 {
98 m_log.DebugFormat("[HGFRIENDS HANDLER]: Exception {0}", e);
99 }
100
101 return FailureResult();
102
103 }
104
105 #region Method-specific handlers
106
107 byte[] GetFriendPerms(Dictionary<string, object> request)
108 {
109 if (!VerifyServiceKey(request))
110 return FailureResult();
111
112 UUID principalID = UUID.Zero;
113 if (request.ContainsKey("PRINCIPALID"))
114 UUID.TryParse(request["PRINCIPALID"].ToString(), out principalID);
115 else
116 {
117 m_log.WarnFormat("[HGFRIENDS HANDLER]: no principalID in request to get friend perms");
118 return FailureResult();
119 }
120
121 UUID friendID = UUID.Zero;
122 if (request.ContainsKey("FRIENDID"))
123 UUID.TryParse(request["FRIENDID"].ToString(), out friendID);
124 else
125 {
126 m_log.WarnFormat("[HGFRIENDS HANDLER]: no friendID in request to get friend perms");
127 return FailureResult();
128 }
129
130 string perms = "0";
131 FriendInfo[] friendsInfo = m_FriendsService.GetFriends(principalID);
132 foreach (FriendInfo finfo in friendsInfo)
133 {
134 if (finfo.Friend.StartsWith(friendID.ToString()))
135 return SuccessResult(finfo.TheirFlags.ToString());
136 }
137
138 return FailureResult("Friend not found");
139 }
140
141 byte[] NewFriendship(Dictionary<string, object> request)
142 {
143 if (!VerifyServiceKey(request))
144 return FailureResult();
145
146 // OK, can proceed
147 FriendInfo friend = new FriendInfo(request);
148 UUID friendID;
149 string tmp = string.Empty;
150 if (!Util.ParseUniversalUserIdentifier(friend.Friend, out friendID, out tmp, out tmp, out tmp, out tmp))
151 return FailureResult();
152
153
154 m_log.DebugFormat("[HGFRIENDS HANDLER]: New friendship {0} {1}", friend.PrincipalID, friend.Friend);
155
156 // If the friendship already exists, return fail
157 FriendInfo[] finfos = m_FriendsService.GetFriends(friend.PrincipalID);
158 foreach (FriendInfo finfo in finfos)
159 if (finfo.Friend.StartsWith(friendID.ToString()))
160 return FailureResult();
161
162 // the user needs to confirm when he gets home
163 bool success = m_FriendsService.StoreFriend(friend.PrincipalID.ToString(), friend.Friend, 0);
164
165 if (success)
166 return SuccessResult();
167 else
168 return FailureResult();
169 }
170
171 byte[] DeleteFriendship(Dictionary<string, object> request)
172 {
173 FriendInfo friend = new FriendInfo(request);
174 string secret = string.Empty;
175 if (request.ContainsKey("SECRET"))
176 secret = request["SECRET"].ToString();
177
178 if (secret == string.Empty)
179 return FailureResult();
180
181 FriendInfo[] finfos = m_FriendsService.GetFriends(friend.PrincipalID);
182 foreach (FriendInfo finfo in finfos)
183 {
184 // We check the secret here
185 if (finfo.Friend.StartsWith(friend.Friend) && finfo.Friend.EndsWith(secret))
186 {
187 m_log.DebugFormat("[HGFRIENDS HANDLER]: Delete friendship {0} {1}", friend.PrincipalID, friend.Friend);
188 m_FriendsService.Delete(friend.PrincipalID, finfo.Friend);
189 m_FriendsService.Delete(finfo.Friend, friend.PrincipalID.ToString());
190
191 return SuccessResult();
192 }
193 }
194
195 return FailureResult();
196 }
197
198 #endregion
199
200 #region Misc
201
202 private bool VerifyServiceKey(Dictionary<string, object> request)
203 {
204 if (!request.ContainsKey("KEY") || !request.ContainsKey("SESSIONID"))
205 {
206 m_log.WarnFormat("[HGFRIENDS HANDLER]: ignoring request without Key or SessionID");
207 return false;
208 }
209
210 string serviceKey = request["KEY"].ToString();
211 string sessionStr = request["SESSIONID"].ToString();
212 UUID sessionID;
213 UUID.TryParse(sessionStr, out sessionID);
214
215 if (!m_UserAgentService.VerifyAgent(sessionID, serviceKey))
216 {
217 m_log.WarnFormat("[HGFRIENDS HANDLER]: Key {0} for session {1} did not match existing key. Ignoring request", serviceKey, sessionID);
218 return false;
219 }
220
221 m_log.DebugFormat("[HGFRIENDS HANDLER]: Verification ok");
222 return true;
223 }
224
225 private byte[] SuccessResult()
226 {
227 XmlDocument doc = new XmlDocument();
228
229 XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration,
230 "", "");
231
232 doc.AppendChild(xmlnode);
233
234 XmlElement rootElement = doc.CreateElement("", "ServerResponse",
235 "");
236
237 doc.AppendChild(rootElement);
238
239 XmlElement result = doc.CreateElement("", "Result", "");
240 result.AppendChild(doc.CreateTextNode("Success"));
241
242 rootElement.AppendChild(result);
243
244 return DocToBytes(doc);
245 }
246
247 private byte[] SuccessResult(string value)
248 {
249 XmlDocument doc = new XmlDocument();
250
251 XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration,
252 "", "");
253
254 doc.AppendChild(xmlnode);
255
256 XmlElement rootElement = doc.CreateElement("", "ServerResponse",
257 "");
258
259 doc.AppendChild(rootElement);
260
261 XmlElement result = doc.CreateElement("", "Result", "");
262 result.AppendChild(doc.CreateTextNode("Success"));
263
264 rootElement.AppendChild(result);
265
266 XmlElement message = doc.CreateElement("", "Value", "");
267 message.AppendChild(doc.CreateTextNode(value));
268
269 rootElement.AppendChild(message);
270
271 return DocToBytes(doc);
272 }
273
274
275 private byte[] FailureResult()
276 {
277 return FailureResult(String.Empty);
278 }
279
280 private byte[] FailureResult(string msg)
281 {
282 XmlDocument doc = new XmlDocument();
283
284 XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration,
285 "", "");
286
287 doc.AppendChild(xmlnode);
288
289 XmlElement rootElement = doc.CreateElement("", "ServerResponse",
290 "");
291
292 doc.AppendChild(rootElement);
293
294 XmlElement result = doc.CreateElement("", "Result", "");
295 result.AppendChild(doc.CreateTextNode("Failure"));
296
297 rootElement.AppendChild(result);
298
299 XmlElement message = doc.CreateElement("", "Message", "");
300 message.AppendChild(doc.CreateTextNode(msg));
301
302 rootElement.AppendChild(message);
303
304 return DocToBytes(doc);
305 }
306
307 private byte[] DocToBytes(XmlDocument doc)
308 {
309 MemoryStream ms = new MemoryStream();
310 XmlTextWriter xw = new XmlTextWriter(ms, null);
311 xw.Formatting = Formatting.Indented;
312 doc.WriteTo(xw);
313 xw.Flush();
314
315 return ms.ToArray();
316 }
317
318 #endregion
319 }
320}