OpenSim
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros
HGGroupsServiceRobustConnector.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 System;
29 using System.Reflection;
30 using System.Text;
31 using System.Xml;
32 using System.Collections.Generic;
33 using System.IO;
34 using Nini.Config;
35 using OpenSim.Framework;
36 using OpenSim.Server.Base;
37 using OpenSim.Services.Interfaces;
38 using OpenSim.Framework.Servers.HttpServer;
39 using OpenSim.Server.Handlers.Base;
40 using log4net;
41 using OpenMetaverse;
42 
43 namespace OpenSim.Groups
44 {
46  {
47  private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
48 
49  private HGGroupsService m_GroupsService;
50  private string m_ConfigName = "Groups";
51 
52  // Called by Robust shell
53  public HGGroupsServiceRobustConnector(IConfigSource config, IHttpServer server, string configName) :
54  this(config, server, configName, null, null)
55  {
56  }
57 
58  // Called by the sim-bound module
59  public HGGroupsServiceRobustConnector(IConfigSource config, IHttpServer server, string configName, IOfflineIMService im, IUserAccountService users) :
60  base(config, server, configName)
61  {
62  if (configName != String.Empty)
63  m_ConfigName = configName;
64 
65  m_log.DebugFormat("[Groups.RobustHGConnector]: Starting with config name {0}", m_ConfigName);
66 
67  string homeURI = Util.GetConfigVarFromSections<string>(config, "HomeURI",
68  new string[] { "Startup", "Hypergrid", m_ConfigName}, string.Empty);
69  if (homeURI == string.Empty)
70  throw new Exception(String.Format("[Groups.RobustHGConnector]: please provide the HomeURI [Startup] or in section {0}", m_ConfigName));
71 
72  IConfig cnf = config.Configs[m_ConfigName];
73  if (cnf == null)
74  throw new Exception(String.Format("[Groups.RobustHGConnector]: {0} section does not exist", m_ConfigName));
75 
76  if (im == null)
77  {
78  string imDll = cnf.GetString("OfflineIMService", string.Empty);
79  if (imDll == string.Empty)
80  throw new Exception(String.Format("[Groups.RobustHGConnector]: please provide OfflineIMService in section {0}", m_ConfigName));
81 
82  Object[] args = new Object[] { config };
83  im = ServerUtils.LoadPlugin<IOfflineIMService>(imDll, args);
84  }
85 
86  if (users == null)
87  {
88  string usersDll = cnf.GetString("UserAccountService", string.Empty);
89  if (usersDll == string.Empty)
90  throw new Exception(String.Format("[Groups.RobustHGConnector]: please provide UserAccountService in section {0}", m_ConfigName));
91 
92  Object[] args = new Object[] { config };
93  users = ServerUtils.LoadPlugin<IUserAccountService>(usersDll, args);
94  }
95 
96  m_GroupsService = new HGGroupsService(config, im, users, homeURI);
97 
98  server.AddStreamHandler(new HGGroupsServicePostHandler(m_GroupsService));
99  }
100 
101  }
102 
104  {
105  private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
106 
107  private HGGroupsService m_GroupsService;
108 
110  base("POST", "/hg-groups")
111  {
112  m_GroupsService = service;
113  }
114 
115  protected override byte[] ProcessRequest(string path, Stream requestData,
116  IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
117  {
118  StreamReader sr = new StreamReader(requestData);
119  string body = sr.ReadToEnd();
120  sr.Close();
121  body = body.Trim();
122 
123  //m_log.DebugFormat("[XXX]: query String: {0}", body);
124 
125  try
126  {
127  Dictionary<string, object> request =
128  ServerUtils.ParseQueryString(body);
129 
130  if (!request.ContainsKey("METHOD"))
131  return FailureResult();
132 
133  string method = request["METHOD"].ToString();
134  request.Remove("METHOD");
135 
136  m_log.DebugFormat("[Groups.RobustHGConnector]: {0}", method);
137  switch (method)
138  {
139  case "POSTGROUP":
140  return HandleAddGroupProxy(request);
141  case "REMOVEAGENTFROMGROUP":
142  return HandleRemoveAgentFromGroup(request);
143  case "GETGROUP":
144  return HandleGetGroup(request);
145  case "ADDNOTICE":
146  return HandleAddNotice(request);
147  case "VERIFYNOTICE":
148  return HandleVerifyNotice(request);
149  case "GETGROUPMEMBERS":
150  return HandleGetGroupMembers(request);
151  case "GETGROUPROLES":
152  return HandleGetGroupRoles(request);
153  case "GETROLEMEMBERS":
154  return HandleGetRoleMembers(request);
155 
156  }
157  m_log.DebugFormat("[Groups.RobustHGConnector]: unknown method request: {0}", method);
158  }
159  catch (Exception e)
160  {
161  m_log.Error(string.Format("[Groups.RobustHGConnector]: Exception {0} ", e.Message), e);
162  }
163 
164  return FailureResult();
165  }
166 
167  byte[] HandleAddGroupProxy(Dictionary<string, object> request)
168  {
169  Dictionary<string, object> result = new Dictionary<string, object>();
170 
171  if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID")
172  || !request.ContainsKey("AgentID")
173  || !request.ContainsKey("AccessToken") || !request.ContainsKey("Location"))
174  NullResult(result, "Bad network data");
175 
176  else
177  {
178  string RequestingAgentID = request["RequestingAgentID"].ToString();
179  string agentID = request["AgentID"].ToString();
180  UUID groupID = new UUID(request["GroupID"].ToString());
181  string accessToken = request["AccessToken"].ToString();
182  string location = request["Location"].ToString();
183  string name = string.Empty;
184  if (request.ContainsKey("Name"))
185  name = request["Name"].ToString();
186 
187  string reason = string.Empty;
188  bool success = m_GroupsService.CreateGroupProxy(RequestingAgentID, agentID, accessToken, groupID, location, name, out reason);
189  result["REASON"] = reason;
190  result["RESULT"] = success.ToString();
191  }
192 
193  string xmlString = ServerUtils.BuildXmlResponse(result);
194 
195  //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
196  return Util.UTF8NoBomEncoding.GetBytes(xmlString);
197  }
198 
199  byte[] HandleRemoveAgentFromGroup(Dictionary<string, object> request)
200  {
201  Dictionary<string, object> result = new Dictionary<string, object>();
202 
203  if (!request.ContainsKey("AccessToken") || !request.ContainsKey("AgentID") ||
204  !request.ContainsKey("GroupID"))
205  NullResult(result, "Bad network data");
206  else
207  {
208  UUID groupID = new UUID(request["GroupID"].ToString());
209  string agentID = request["AgentID"].ToString();
210  string token = request["AccessToken"].ToString();
211 
212  if (!m_GroupsService.RemoveAgentFromGroup(agentID, agentID, groupID, token))
213  NullResult(result, "Internal error");
214  else
215  result["RESULT"] = "true";
216  }
217 
218  //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
219  return Util.UTF8NoBomEncoding.GetBytes(ServerUtils.BuildXmlResponse(result));
220  }
221 
222  byte[] HandleGetGroup(Dictionary<string, object> request)
223  {
224  Dictionary<string, object> result = new Dictionary<string, object>();
225 
226  if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("AccessToken"))
227  NullResult(result, "Bad network data");
228  else
229  {
230  string RequestingAgentID = request["RequestingAgentID"].ToString();
231  string token = request["AccessToken"].ToString();
232 
233  UUID groupID = UUID.Zero;
234  string groupName = string.Empty;
235 
236  if (request.ContainsKey("GroupID"))
237  groupID = new UUID(request["GroupID"].ToString());
238  if (request.ContainsKey("Name"))
239  groupName = request["Name"].ToString();
240 
241  ExtendedGroupRecord grec = m_GroupsService.GetGroupRecord(RequestingAgentID, groupID, groupName, token);
242  if (grec == null)
243  NullResult(result, "Group not found");
244  else
245  result["RESULT"] = GroupsDataUtils.GroupRecord(grec);
246  }
247 
248  string xmlString = ServerUtils.BuildXmlResponse(result);
249 
250  //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
251  return Util.UTF8NoBomEncoding.GetBytes(xmlString);
252  }
253 
254  byte[] HandleGetGroupMembers(Dictionary<string, object> request)
255  {
256  Dictionary<string, object> result = new Dictionary<string, object>();
257 
258  if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID") || !request.ContainsKey("AccessToken"))
259  NullResult(result, "Bad network data");
260  else
261  {
262  UUID groupID = new UUID(request["GroupID"].ToString());
263  string requestingAgentID = request["RequestingAgentID"].ToString();
264  string token = request["AccessToken"].ToString();
265 
266  List<ExtendedGroupMembersData> members = m_GroupsService.GetGroupMembers(requestingAgentID, groupID, token);
267  if (members == null || (members != null && members.Count == 0))
268  {
269  NullResult(result, "No members");
270  }
271  else
272  {
273  Dictionary<string, object> dict = new Dictionary<string, object>();
274  int i = 0;
275  foreach (ExtendedGroupMembersData m in members)
276  {
277  dict["m-" + i++] = GroupsDataUtils.GroupMembersData(m);
278  }
279 
280  result["RESULT"] = dict;
281  }
282  }
283 
284  string xmlString = ServerUtils.BuildXmlResponse(result);
285 
286  //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
287  return Util.UTF8NoBomEncoding.GetBytes(xmlString);
288  }
289 
290  byte[] HandleGetGroupRoles(Dictionary<string, object> request)
291  {
292  Dictionary<string, object> result = new Dictionary<string, object>();
293 
294  if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID") || !request.ContainsKey("AccessToken"))
295  NullResult(result, "Bad network data");
296  else
297  {
298  UUID groupID = new UUID(request["GroupID"].ToString());
299  string requestingAgentID = request["RequestingAgentID"].ToString();
300  string token = request["AccessToken"].ToString();
301 
302  List<GroupRolesData> roles = m_GroupsService.GetGroupRoles(requestingAgentID, groupID, token);
303  if (roles == null || (roles != null && roles.Count == 0))
304  {
305  NullResult(result, "No members");
306  }
307  else
308  {
309  Dictionary<string, object> dict = new Dictionary<string, object>();
310  int i = 0;
311  foreach (GroupRolesData r in roles)
312  dict["r-" + i++] = GroupsDataUtils.GroupRolesData(r);
313 
314  result["RESULT"] = dict;
315  }
316  }
317 
318  string xmlString = ServerUtils.BuildXmlResponse(result);
319 
320  //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
321  return Util.UTF8NoBomEncoding.GetBytes(xmlString);
322  }
323 
324  byte[] HandleGetRoleMembers(Dictionary<string, object> request)
325  {
326  Dictionary<string, object> result = new Dictionary<string, object>();
327 
328  if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID") || !request.ContainsKey("AccessToken"))
329  NullResult(result, "Bad network data");
330  else
331  {
332  UUID groupID = new UUID(request["GroupID"].ToString());
333  string requestingAgentID = request["RequestingAgentID"].ToString();
334  string token = request["AccessToken"].ToString();
335 
336  List<ExtendedGroupRoleMembersData> rmembers = m_GroupsService.GetGroupRoleMembers(requestingAgentID, groupID, token);
337  if (rmembers == null || (rmembers != null && rmembers.Count == 0))
338  {
339  NullResult(result, "No members");
340  }
341  else
342  {
343  Dictionary<string, object> dict = new Dictionary<string, object>();
344  int i = 0;
345  foreach (ExtendedGroupRoleMembersData rm in rmembers)
346  dict["rm-" + i++] = GroupsDataUtils.GroupRoleMembersData(rm);
347 
348  result["RESULT"] = dict;
349  }
350  }
351 
352  string xmlString = ServerUtils.BuildXmlResponse(result);
353 
354  //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
355  return Util.UTF8NoBomEncoding.GetBytes(xmlString);
356  }
357 
358  byte[] HandleAddNotice(Dictionary<string, object> request)
359  {
360  Dictionary<string, object> result = new Dictionary<string, object>();
361 
362  if (!request.ContainsKey("RequestingAgentID") || !request.ContainsKey("GroupID") || !request.ContainsKey("NoticeID") ||
363  !request.ContainsKey("FromName") || !request.ContainsKey("Subject") || !request.ContainsKey("Message") ||
364  !request.ContainsKey("HasAttachment"))
365  NullResult(result, "Bad network data");
366 
367  else
368  {
369 
370  bool hasAtt = bool.Parse(request["HasAttachment"].ToString());
371  byte attType = 0;
372  string attName = string.Empty;
373  string attOwner = string.Empty;
374  UUID attItem = UUID.Zero;
375  if (request.ContainsKey("AttachmentType"))
376  attType = byte.Parse(request["AttachmentType"].ToString());
377  if (request.ContainsKey("AttachmentName"))
378  attName = request["AttachmentType"].ToString();
379  if (request.ContainsKey("AttachmentItemID"))
380  attItem = new UUID(request["AttachmentItemID"].ToString());
381  if (request.ContainsKey("AttachmentOwnerID"))
382  attOwner = request["AttachmentOwnerID"].ToString();
383 
384  bool success = m_GroupsService.AddNotice(request["RequestingAgentID"].ToString(), new UUID(request["GroupID"].ToString()),
385  new UUID(request["NoticeID"].ToString()), request["FromName"].ToString(), request["Subject"].ToString(),
386  request["Message"].ToString(), hasAtt, attType, attName, attItem, attOwner);
387 
388  result["RESULT"] = success.ToString();
389  }
390 
391  string xmlString = ServerUtils.BuildXmlResponse(result);
392 
393  //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
394  return Util.UTF8NoBomEncoding.GetBytes(xmlString);
395  }
396 
397  byte[] HandleVerifyNotice(Dictionary<string, object> request)
398  {
399  Dictionary<string, object> result = new Dictionary<string, object>();
400 
401  if (!request.ContainsKey("NoticeID") || !request.ContainsKey("GroupID"))
402  NullResult(result, "Bad network data");
403 
404  else
405  {
406  UUID noticeID = new UUID(request["NoticeID"].ToString());
407  UUID groupID = new UUID(request["GroupID"].ToString());
408 
409  bool success = m_GroupsService.VerifyNotice(noticeID, groupID);
410  //m_log.DebugFormat("[XXX]: VerifyNotice returned {0}", success);
411  result["RESULT"] = success.ToString();
412  }
413 
414  string xmlString = ServerUtils.BuildXmlResponse(result);
415 
416  //m_log.DebugFormat("[XXX]: resp string: {0}", xmlString);
417  return Util.UTF8NoBomEncoding.GetBytes(xmlString);
418  }
419 
420  //
421  //
422  //
423  //
424  //
425 
426  #region Helpers
427 
428  private void NullResult(Dictionary<string, object> result, string reason)
429  {
430  result["RESULT"] = "NULL";
431  result["REASON"] = reason;
432  }
433 
434  private byte[] FailureResult()
435  {
436  Dictionary<string, object> result = new Dictionary<string, object>();
437  NullResult(result, "Unknown method");
438  string xmlString = ServerUtils.BuildXmlResponse(result);
439  return Util.UTF8NoBomEncoding.GetBytes(xmlString);
440  }
441 
442  #endregion
443  }
444 }
HGGroupsServiceRobustConnector(IConfigSource config, IHttpServer server, string configName, IOfflineIMService im, IUserAccountService users)
HGGroupsServiceRobustConnector(IConfigSource config, IHttpServer server, string configName)
override byte[] ProcessRequest(string path, Stream requestData, IOSHttpRequest httpRequest, IOSHttpResponse httpResponse)
Interface to OpenSimulator's built in HTTP server. Use this to register handlers (http, llsd, xmlrpc, etc.) for given URLs.
Definition: IHttpServer.cs:36
HGGroupsServicePostHandler(HGGroupsService service)