aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/CoreModules/Hypergrid/HGStandaloneInventoryService.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/CoreModules/Hypergrid/HGStandaloneInventoryService.cs')
-rw-r--r--OpenSim/Region/CoreModules/Hypergrid/HGStandaloneInventoryService.cs272
1 files changed, 266 insertions, 6 deletions
diff --git a/OpenSim/Region/CoreModules/Hypergrid/HGStandaloneInventoryService.cs b/OpenSim/Region/CoreModules/Hypergrid/HGStandaloneInventoryService.cs
index cff3611..35db298 100644
--- a/OpenSim/Region/CoreModules/Hypergrid/HGStandaloneInventoryService.cs
+++ b/OpenSim/Region/CoreModules/Hypergrid/HGStandaloneInventoryService.cs
@@ -27,6 +27,7 @@
27 */ 27 */
28 28
29using System; 29using System;
30using System.Collections;
30using System.Collections.Generic; 31using System.Collections.Generic;
31using System.Reflection; 32using System.Reflection;
32using log4net; 33using log4net;
@@ -38,6 +39,9 @@ using OpenSim.Framework.Servers;
38using OpenSim.Framework.Servers.Interfaces; 39using OpenSim.Framework.Servers.Interfaces;
39using OpenSim.Region.Framework.Interfaces; 40using OpenSim.Region.Framework.Interfaces;
40using OpenSim.Region.Framework.Scenes; 41using OpenSim.Region.Framework.Scenes;
42using OpenSim.Region.CoreModules.Communications.REST;
43
44using OpenMetaverse.StructuredData;
41 45
42namespace OpenSim.Region.CoreModules.Hypergrid 46namespace OpenSim.Region.CoreModules.Hypergrid
43{ 47{
@@ -97,8 +101,10 @@ namespace OpenSim.Region.CoreModules.Hypergrid
97 = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 101 = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
98 102
99 private InventoryServiceBase m_inventoryService; 103 private InventoryServiceBase m_inventoryService;
100 private IUserService m_userService; 104 private UserManagerBase m_userService;
105 private Scene m_scene;
101 private bool m_doLookup = false; 106 private bool m_doLookup = false;
107 private string m_thisInventoryUrl = "http://localhost:9000";
102 108
103 public bool DoLookup 109 public bool DoLookup
104 { 110 {
@@ -106,17 +112,24 @@ namespace OpenSim.Region.CoreModules.Hypergrid
106 set { m_doLookup = value; } 112 set { m_doLookup = value; }
107 } 113 }
108 114
109 public InventoryService(Scene m_scene) 115 public InventoryService(Scene _m_scene)
110 { 116 {
117 m_scene = _m_scene;
111 m_inventoryService = (InventoryServiceBase)m_scene.CommsManager.SecureInventoryService; 118 m_inventoryService = (InventoryServiceBase)m_scene.CommsManager.SecureInventoryService;
112 m_userService = m_scene.CommsManager.UserService; 119 m_userService = (UserManagerBase)m_scene.CommsManager.UserService;
113 AddHttpHandlers(m_scene); 120 m_thisInventoryUrl = m_scene.CommsManager.NetworkServersInfo.InventoryURL;
121 if (!m_thisInventoryUrl.EndsWith("/"))
122 m_thisInventoryUrl += "/";
123
124 AddHttpHandlers();
114 } 125 }
115 126
116 protected void AddHttpHandlers(Scene m_scene) 127 protected void AddHttpHandlers()
117 { 128 {
118 IHttpServer httpServer = m_scene.CommsManager.HttpServer; 129 IHttpServer httpServer = m_scene.CommsManager.HttpServer;
119 130
131 httpServer.AddHTTPHandler("/InvCap/", CapHandler);
132
120 httpServer.AddStreamHandler( 133 httpServer.AddStreamHandler(
121 new RestDeserialiseSecureHandler<Guid, InventoryCollection>( 134 new RestDeserialiseSecureHandler<Guid, InventoryCollection>(
122 "POST", "/GetInventory/", GetUserInventory, CheckAuthSession)); 135 "POST", "/GetInventory/", GetUserInventory, CheckAuthSession));
@@ -231,6 +244,17 @@ namespace OpenSim.Region.CoreModules.Hypergrid
231 } 244 }
232 } 245 }
233 246
247 // In truth, this is not called from the outside, for standalones. I'm just making it
248 // a handler already so that this can be reused for the InventoryServer.
249 public string CreateCapUrl(Guid _userid)
250 {
251 UUID userID = new UUID(_userid);
252 UUID random = UUID.Random();
253 string url = m_thisInventoryUrl + random.ToString() + "/";
254 m_log.InfoFormat("[HGStandaloneInvService] Creating Cap URL {0} for user {1}", url, userID.ToString());
255 return url;
256 }
257
234 258
235 /// <summary> 259 /// <summary>
236 /// Return a user's entire inventory 260 /// Return a user's entire inventory
@@ -290,6 +314,37 @@ namespace OpenSim.Region.CoreModules.Hypergrid
290 return invCollection; 314 return invCollection;
291 } 315 }
292 316
317 public InventoryCollection FetchDescendants(InventoryFolderBase fb)
318 {
319 m_log.Info("[HGStandaloneInvService]: Processing request for folder " + fb.ID);
320
321 // Uncomment me to simulate a slow responding inventory server
322 //Thread.Sleep(16000);
323
324 InventoryCollection invCollection = new InventoryCollection();
325
326 List<InventoryItemBase> items = ((InventoryServiceBase)m_inventoryService).RequestFolderItems(fb.ID);
327 List<InventoryFolderBase> folders = ((InventoryServiceBase)m_inventoryService).RequestSubFolders(fb.ID);
328
329 invCollection.UserID = fb.Owner;
330 invCollection.Folders = folders;
331 invCollection.Items = items;
332
333 m_log.DebugFormat("[HGStandaloneInvService]: Found {0} items and {1} folders", items.Count, folders.Count);
334
335 return invCollection;
336 }
337
338 public InventoryItemBase GetInventoryItem(InventoryItemBase item)
339 {
340 m_log.Info("[HGStandaloneInvService]: Processing request for item " + item.ID);
341
342 item = ((InventoryServiceBase)m_inventoryService).GetInventoryItem(item.ID);
343 if (item == null)
344 m_log.Debug("[HGStandaloneInvService]: null item");
345 return item;
346 }
347
293 /// <summary> 348 /// <summary>
294 /// Guid to UUID wrapper for same name IInventoryServices method 349 /// Guid to UUID wrapper for same name IInventoryServices method
295 /// </summary> 350 /// </summary>
@@ -309,5 +364,210 @@ namespace OpenSim.Region.CoreModules.Hypergrid
309 364
310 return ((InventoryServiceBase)m_inventoryService).GetActiveGestures(userID); 365 return ((InventoryServiceBase)m_inventoryService).GetActiveGestures(userID);
311 } 366 }
367
368
369 #region Caps
370
371 Dictionary<UUID, List<string>> invCaps = new Dictionary<UUID, List<string>>();
372
373 public Hashtable CapHandler(Hashtable request)
374 {
375 m_log.Debug("[CONNECTION DEBUGGING]: InvCapHandler Called");
376
377 m_log.Debug("---------------------------");
378 m_log.Debug(" >> uri=" + request["uri"]);
379 m_log.Debug(" >> content-type=" + request["content-type"]);
380 m_log.Debug(" >> http-method=" + request["http-method"]);
381 m_log.Debug("---------------------------\n");
382
383 // these are requests if the type
384 // http://inventoryserver/InvCap/uuuuuuuu-uuuu-uuuu-uuuu-uuuuuuuuuuuu/kkkkkkkk-kkkk-kkkk-kkkk-kkkkkkkkkkkk/
385
386 Hashtable responsedata = new Hashtable();
387 responsedata["content_type"] = "text/plain";
388
389 UUID userID;
390 string authToken = string.Empty;
391 string authority = string.Empty;
392 if (!GetParams(request, out userID, out authority, out authToken))
393 {
394 m_log.InfoFormat("[HGStandaloneInvService]: Invalid parameters for InvCap message {0}", request["uri"]);
395 responsedata["int_response_code"] = 404;
396 responsedata["str_response_string"] = "Not found";
397
398 return responsedata;
399 }
400
401 // Next, let's parse the verb
402 string method = (string)request["http-method"];
403 if (method.Equals("GET"))
404 {
405 DoInvCapPost(request, responsedata, userID, authToken);
406 return responsedata;
407 }
408 //else if (method.Equals("DELETE"))
409 //{
410 // DoAgentDelete(request, responsedata, agentID, action, regionHandle);
411
412 // return responsedata;
413 //}
414 else
415 {
416 m_log.InfoFormat("[HGStandaloneInvService]: method {0} not supported in agent message", method);
417 responsedata["int_response_code"] = 405;
418 responsedata["str_response_string"] = "Method not allowed";
419
420 return responsedata;
421 }
422
423 }
424
425 public virtual void DoInvCapPost(Hashtable request, Hashtable responsedata, UUID userID, string authToken)
426 {
427
428 // This is the meaning of POST agent
429
430 // Check Auth Token
431 if (!(m_userService is IAuthentication))
432 {
433 m_log.Debug("[HGStandaloneInvService]: UserService is not IAuthentication. Denying access to inventory.");
434 responsedata["int_response_code"] = 501;
435 responsedata["str_response_string"] = "Not implemented";
436 return;
437 }
438
439 bool success = ((IAuthentication)m_userService).VerifyKey(userID, authToken);
440
441 if (success)
442 {
443
444 m_log.DebugFormat("[HGStandaloneInvService]: User has been authorized. Creating service handlers.");
445
446 // Then establish secret service handlers
447
448 RegisterCaps(userID, authToken);
449
450 responsedata["int_response_code"] = 200;
451 responsedata["str_response_string"] = "OK";
452 }
453 else
454 {
455 m_log.DebugFormat("[HGStandaloneInvService]: User has is unauthorized. Denying service handlers.");
456 responsedata["int_response_code"] = 403;
457 responsedata["str_response_string"] = "Forbidden";
458 }
459 }
460
461
462 /// <summary>
463 /// Extract the params from a request.
464 /// </summary>
465 public static bool GetParams(Hashtable request, out UUID uuid, out string authority, out string authKey)
466 {
467 uuid = UUID.Zero;
468 authority = string.Empty;
469 authKey = string.Empty;
470
471 string uri = (string)request["uri"];
472 uri = uri.Trim(new char[] { '/' });
473 string[] parts = uri.Split('/');
474 if (parts.Length <= 1)
475 {
476 return false;
477 }
478 else
479 {
480 if (!UUID.TryParse(parts[1], out uuid))
481 return false;
482
483 if (parts.Length >= 3)
484 {
485 authKey = parts[2];
486 return true;
487 }
488 }
489
490 Uri authUri;
491 Hashtable headers = (Hashtable)request["headers"];
492
493 // Authorization keys look like this:
494 // http://orgrid.org:8002/<uuid>
495 if (headers.ContainsKey("authorization"))
496 {
497 if (Uri.TryCreate((string)headers["authorization"], UriKind.Absolute, out authUri))
498 {
499 authority = authUri.Authority;
500 authKey = authUri.PathAndQuery.Trim('/');
501 m_log.DebugFormat("[HGStandaloneInvService]: Got authority {0} and key {1}", authority, authKey);
502 return true;
503 }
504 else
505 m_log.Debug("[HGStandaloneInvService]: Wrong format for Authorization header: " + (string)headers["authorization"]);
506 }
507 else
508 m_log.Debug("[HGStandaloneInvService]: Authorization header not found");
509
510 return false;
511 }
512
513 void RegisterCaps(UUID userID, string authToken)
514 {
515 IHttpServer httpServer = m_scene.CommsManager.HttpServer;
516
517 lock (invCaps)
518 {
519 if (invCaps.ContainsKey(userID))
520 {
521 // Remove the old ones
522 DeregisterCaps(httpServer, invCaps[userID]);
523 invCaps.Remove(userID);
524 }
525 }
526
527 List<string> caps = new List<string>();
528
529 httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<Guid, InventoryCollection>(
530 "POST", AddAndGetCapUrl(authToken, "/GetInventory/", caps), GetUserInventory, CheckAuthSession));
531
532 httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<InventoryFolderBase, InventoryCollection>(
533 "POST", AddAndGetCapUrl(authToken, "/FetchDescendants/", caps), FetchDescendants, CheckAuthSession));
534 httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<InventoryItemBase, InventoryItemBase>(
535 "POST", AddAndGetCapUrl(authToken, "/GetItem/", caps), GetInventoryItem, CheckAuthSession));
536 httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<InventoryFolderBase, bool>(
537 "POST", AddAndGetCapUrl(authToken, "/NewFolder/", caps), m_inventoryService.AddFolder, CheckAuthSession));
538 httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<InventoryFolderBase, bool>(
539 "POST", AddAndGetCapUrl(authToken, "/UpdateFolder/", caps), m_inventoryService.UpdateFolder, CheckAuthSession));
540 httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<InventoryFolderBase, bool>(
541 "POST", AddAndGetCapUrl(authToken, "/MoveFolder/", caps), m_inventoryService.MoveFolder, CheckAuthSession));
542 httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<InventoryFolderBase, bool>(
543 "POST", AddAndGetCapUrl(authToken, "/PurgeFolder/", caps), m_inventoryService.PurgeFolder, CheckAuthSession));
544 httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<InventoryItemBase, bool>(
545 "POST", AddAndGetCapUrl(authToken, "/NewItem/", caps), m_inventoryService.AddItem, CheckAuthSession));
546 httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<InventoryItemBase, bool>(
547 "POST", AddAndGetCapUrl(authToken, "/DeleteItem/", caps), m_inventoryService.DeleteItem, CheckAuthSession));
548
549 lock (invCaps)
550 invCaps.Add(userID, caps);
551 }
552
553 string AddAndGetCapUrl(string authToken, string capType, List<string> caps)
554 {
555 string capUrl = "/" + authToken + capType;
556
557 m_log.Debug("[HGStandaloneInvService] Adding inventory cap " + capUrl);
558 caps.Add(capUrl);
559 return capUrl;
560 }
561
562 void DeregisterCaps(IHttpServer httpServer, List<string> caps)
563 {
564 foreach (string capUrl in caps)
565 {
566 m_log.Debug("[HGStandaloneInvService] Removing inventory cap " + capUrl);
567 httpServer.RemoveStreamHandler("POST", capUrl);
568 }
569 }
570
571 #endregion Caps
312 } 572 }
313} 573}