diff options
author | Diva Canto | 2009-08-09 13:59:26 -0700 |
---|---|---|
committer | Diva Canto | 2009-08-09 13:59:26 -0700 |
commit | 04aca663300bcf823ae25d9cc82e727e58e24c21 (patch) | |
tree | 0349ef251a41412f12048306e94d9191884f9696 /OpenSim/Framework/Communications/Services | |
parent | * FreeContext may be a bit too buggy for my tastes in some environments. * ... (diff) | |
download | opensim-SC-04aca663300bcf823ae25d9cc82e727e58e24c21.zip opensim-SC-04aca663300bcf823ae25d9cc82e727e58e24c21.tar.gz opensim-SC-04aca663300bcf823ae25d9cc82e727e58e24c21.tar.bz2 opensim-SC-04aca663300bcf823ae25d9cc82e727e58e24c21.tar.xz |
Removed HGInventory out of core. This is part of HG2, which it now being developed outside.
Diffstat (limited to 'OpenSim/Framework/Communications/Services')
-rw-r--r-- | OpenSim/Framework/Communications/Services/HGInventoryService.cs | 744 |
1 files changed, 0 insertions, 744 deletions
diff --git a/OpenSim/Framework/Communications/Services/HGInventoryService.cs b/OpenSim/Framework/Communications/Services/HGInventoryService.cs deleted file mode 100644 index e253474..0000000 --- a/OpenSim/Framework/Communications/Services/HGInventoryService.cs +++ /dev/null | |||
@@ -1,744 +0,0 @@ | |||
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.Collections; | ||
30 | using System.Collections.Generic; | ||
31 | using System.Reflection; | ||
32 | using log4net; | ||
33 | using Nini.Config; | ||
34 | using OpenMetaverse; | ||
35 | using OpenSim.Data; | ||
36 | using OpenSim.Framework; | ||
37 | using OpenSim.Framework.Communications.Clients; | ||
38 | using OpenSim.Framework.Communications.Cache; | ||
39 | using Caps = OpenSim.Framework.Capabilities.Caps; | ||
40 | using LLSDHelpers = OpenSim.Framework.Capabilities.LLSDHelpers; | ||
41 | using OpenSim.Framework.Servers; | ||
42 | using OpenSim.Framework.Servers.HttpServer; | ||
43 | using OpenSim.Services.Interfaces; | ||
44 | |||
45 | using OpenMetaverse.StructuredData; | ||
46 | |||
47 | namespace OpenSim.Framework.Communications.Services | ||
48 | { | ||
49 | public class HGInventoryService | ||
50 | { | ||
51 | private static readonly ILog m_log | ||
52 | = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
53 | |||
54 | private InventoryServiceBase m_inventoryService; | ||
55 | IHttpServer httpServer; | ||
56 | private string m_thisInventoryUrl = "http://localhost:9000"; | ||
57 | private string m_thisHostname = "127.0.0.1"; | ||
58 | private uint m_thisPort = 9000; | ||
59 | |||
60 | // These two used for local access, standalone mode | ||
61 | private UserManagerBase m_userService = null; | ||
62 | IAssetService m_assetProvider = null; | ||
63 | |||
64 | // These two used for remote access | ||
65 | //string m_UserServerURL = string.Empty; | ||
66 | string m_AssetServerURL = string.Empty; | ||
67 | SynchronousGridAssetClient m_AssetClient = null; | ||
68 | |||
69 | // Constructor for grid inventory server | ||
70 | public HGInventoryService(InventoryServiceBase invService, string assetServiceURL, string userServiceURL, IHttpServer httpserver, string thisurl) | ||
71 | { | ||
72 | //m_UserServerURL = userServiceURL; | ||
73 | m_AssetServerURL = assetServiceURL; | ||
74 | |||
75 | m_AssetClient = new SynchronousGridAssetClient(m_AssetServerURL); | ||
76 | |||
77 | Init(invService, thisurl, httpserver); | ||
78 | } | ||
79 | |||
80 | // Constructor for standalone mode | ||
81 | public HGInventoryService(InventoryServiceBase invService, IAssetService assetService, UserManagerBase userService, IHttpServer httpserver, string thisurl) | ||
82 | { | ||
83 | m_userService = userService; | ||
84 | m_assetProvider = assetService; | ||
85 | |||
86 | Init(invService, thisurl, httpserver); | ||
87 | } | ||
88 | |||
89 | private void Init(InventoryServiceBase invService, string thisurl, IHttpServer httpserver) | ||
90 | { | ||
91 | m_inventoryService = invService; | ||
92 | m_thisInventoryUrl = thisurl; | ||
93 | if (!m_thisInventoryUrl.EndsWith("/")) | ||
94 | m_thisInventoryUrl += "/"; | ||
95 | |||
96 | Uri uri = new Uri(m_thisInventoryUrl); | ||
97 | if (uri != null) | ||
98 | { | ||
99 | m_thisHostname = uri.Host; | ||
100 | m_thisPort = (uint)uri.Port; | ||
101 | } | ||
102 | |||
103 | httpServer = httpserver; | ||
104 | |||
105 | AddHttpHandlers(); | ||
106 | } | ||
107 | |||
108 | public virtual void AddHttpHandlers() | ||
109 | { | ||
110 | httpServer.AddHTTPHandler("/InvCap/", CapHandler); | ||
111 | |||
112 | // Un-cap'ed for now | ||
113 | httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<Guid, InventoryItemBase>( | ||
114 | "POST", "/GetItem/", GetInventoryItem, CheckAuthSession)); | ||
115 | |||
116 | } | ||
117 | |||
118 | public InventoryItemBase GetInventoryItem(Guid id) | ||
119 | { | ||
120 | UUID itemID = new UUID(id); | ||
121 | return m_inventoryService.GetInventoryItem(itemID); | ||
122 | } | ||
123 | |||
124 | public bool CheckAuthSession(string session_id, string avatar_id) | ||
125 | { | ||
126 | return true; | ||
127 | } | ||
128 | |||
129 | |||
130 | // In truth, this is not called from the outside, for standalones. I'm just making it | ||
131 | // a handler already so that this can be reused for the InventoryServer. | ||
132 | public string CreateCapUrl(Guid _userid) | ||
133 | { | ||
134 | UUID userID = new UUID(_userid); | ||
135 | UUID random = UUID.Random(); | ||
136 | string url = m_thisInventoryUrl + random.ToString() + "/"; | ||
137 | m_log.InfoFormat("[HGStandaloneInvService] Creating Cap URL {0} for user {1}", url, userID.ToString()); | ||
138 | return url; | ||
139 | } | ||
140 | |||
141 | /// <summary> | ||
142 | /// Return a user's entire inventory | ||
143 | /// </summary> | ||
144 | /// <param name="rawUserID"></param> | ||
145 | /// <returns>The user's inventory. If an inventory cannot be found then an empty collection is returned.</returns> | ||
146 | public InventoryCollection GetUserInventory(Guid rawUserID) | ||
147 | { | ||
148 | UUID userID = new UUID(rawUserID); | ||
149 | |||
150 | m_log.Info("[HGStandaloneInvModule]: Processing request for inventory of " + userID); | ||
151 | |||
152 | // Uncomment me to simulate a slow responding inventory server | ||
153 | //Thread.Sleep(16000); | ||
154 | |||
155 | InventoryCollection invCollection = new InventoryCollection(); | ||
156 | |||
157 | List<InventoryFolderBase> allFolders = m_inventoryService.GetInventorySkeleton(userID); | ||
158 | |||
159 | if (null == allFolders) | ||
160 | { | ||
161 | m_log.WarnFormat("[HGStandaloneInvModule]: No inventory found for user {0}", rawUserID); | ||
162 | |||
163 | return invCollection; | ||
164 | } | ||
165 | |||
166 | List<InventoryItemBase> allItems = new List<InventoryItemBase>(); | ||
167 | |||
168 | foreach (InventoryFolderBase folder in allFolders) | ||
169 | { | ||
170 | List<InventoryItemBase> items = m_inventoryService.RequestFolderItems(folder.ID); | ||
171 | |||
172 | if (items != null) | ||
173 | { | ||
174 | allItems.InsertRange(0, items); | ||
175 | } | ||
176 | } | ||
177 | |||
178 | invCollection.UserID = userID; | ||
179 | invCollection.Folders = allFolders; | ||
180 | invCollection.Items = allItems; | ||
181 | |||
182 | // foreach (InventoryFolderBase folder in invCollection.Folders) | ||
183 | // { | ||
184 | // m_log.DebugFormat("[GRID AGENT INVENTORY]: Sending back folder {0} {1}", folder.Name, folder.ID); | ||
185 | // } | ||
186 | // | ||
187 | // foreach (InventoryItemBase item in invCollection.Items) | ||
188 | // { | ||
189 | // m_log.DebugFormat("[GRID AGENT INVENTORY]: Sending back item {0} {1}, folder {2}", item.Name, item.ID, item.Folder); | ||
190 | // } | ||
191 | |||
192 | m_log.InfoFormat( | ||
193 | "[HGStandaloneInvModule]: Sending back inventory response to user {0} containing {1} folders and {2} items", | ||
194 | invCollection.UserID, invCollection.Folders.Count, invCollection.Items.Count); | ||
195 | |||
196 | return invCollection; | ||
197 | } | ||
198 | |||
199 | public InventoryCollection FetchDescendants(InventoryFolderBase fb) | ||
200 | { | ||
201 | m_log.Info("[HGStandaloneInvService]: Processing request for folder " + fb.ID); | ||
202 | |||
203 | // Uncomment me to simulate a slow responding inventory server | ||
204 | //Thread.Sleep(16000); | ||
205 | |||
206 | InventoryCollection invCollection = new InventoryCollection(); | ||
207 | |||
208 | List<InventoryItemBase> items = m_inventoryService.RequestFolderItems(fb.ID); | ||
209 | List<InventoryFolderBase> folders = m_inventoryService.RequestSubFolders(fb.ID); | ||
210 | |||
211 | invCollection.UserID = fb.Owner; | ||
212 | invCollection.Folders = folders; | ||
213 | invCollection.Items = items; | ||
214 | |||
215 | m_log.DebugFormat("[HGStandaloneInvService]: Found {0} items and {1} folders", items.Count, folders.Count); | ||
216 | |||
217 | return invCollection; | ||
218 | } | ||
219 | |||
220 | public bool RemoveFolder(InventoryFolderBase folder) | ||
221 | { | ||
222 | m_log.Debug("[HGStandaloneInvService]: Removefolder: Operation not implemented yet."); | ||
223 | return false; | ||
224 | } | ||
225 | |||
226 | public InventoryItemBase GetInventoryItem(InventoryItemBase item) | ||
227 | { | ||
228 | m_log.Info("[HGStandaloneInvService]: Get item " + item.ID); | ||
229 | |||
230 | item = m_inventoryService.GetInventoryItem(item.ID); | ||
231 | if (item == null) | ||
232 | m_log.Debug("[HGStandaloneInvService]: null item"); | ||
233 | return item; | ||
234 | } | ||
235 | |||
236 | public InventoryItemBase AddItem(InventoryItemBase item) | ||
237 | { | ||
238 | m_log.DebugFormat("[HGStandaloneInvService]: Add item {0} from {1}", item.ID, item.Owner); | ||
239 | if (m_inventoryService.AddItem(item)) | ||
240 | return item; | ||
241 | else | ||
242 | { | ||
243 | item.ID = UUID.Zero; | ||
244 | return item; | ||
245 | } | ||
246 | } | ||
247 | |||
248 | public void AddUploadedInventoryItem(UUID agentID, InventoryItemBase item) | ||
249 | { | ||
250 | AddItem(item); | ||
251 | } | ||
252 | |||
253 | public InventoryItemBase UpdateItem(InventoryItemBase item) | ||
254 | { | ||
255 | m_log.DebugFormat("[HGStandaloneInvService]: Update item {0} from {1}", item.ID, item.Owner); | ||
256 | InventoryItemBase it = m_inventoryService.GetInventoryItem(item.ID); | ||
257 | item.CurrentPermissions = it.CurrentPermissions; | ||
258 | item.AssetID = it.AssetID; | ||
259 | if (m_inventoryService.UpdateItem(item)) | ||
260 | return item; | ||
261 | else | ||
262 | { | ||
263 | item.ID = UUID.Zero; | ||
264 | return item; | ||
265 | } | ||
266 | } | ||
267 | |||
268 | public InventoryItemBase MoveItem(InventoryItemBase newitem) | ||
269 | { | ||
270 | m_log.DebugFormat("[HGStandaloneInvService]: Move item {0} from {1}", newitem.ID, newitem.Owner); | ||
271 | InventoryItemBase Item = m_inventoryService.GetInventoryItem(newitem.ID); | ||
272 | if (Item != null) | ||
273 | { | ||
274 | if (newitem.Name != String.Empty) | ||
275 | { | ||
276 | Item.Name = newitem.Name; | ||
277 | } | ||
278 | Item.Folder = newitem.Folder; | ||
279 | m_inventoryService.UpdateItem(Item); | ||
280 | return Item; | ||
281 | } | ||
282 | else | ||
283 | { | ||
284 | m_log.Debug("[HGStandaloneInvService]: Failed to find item " + newitem.ID); | ||
285 | newitem.ID = UUID.Zero; | ||
286 | return newitem; | ||
287 | } | ||
288 | |||
289 | } | ||
290 | |||
291 | public InventoryItemBase DeleteItem(InventoryItemBase item) | ||
292 | { | ||
293 | item = m_inventoryService.GetInventoryItem(item.ID); | ||
294 | if (m_inventoryService.DeleteItem(item)) | ||
295 | return item; | ||
296 | else | ||
297 | { | ||
298 | item.ID = UUID.Zero; | ||
299 | return item; | ||
300 | } | ||
301 | } | ||
302 | |||
303 | public InventoryItemBase CopyItem(InventoryItemBase olditem) | ||
304 | { | ||
305 | m_log.DebugFormat("[HGStandaloneInvService]: Copy item {0} from {1}", olditem.ID, olditem.Owner); | ||
306 | InventoryItemBase Item = m_inventoryService.GetInventoryItem(olditem.ID); // this is the old item id | ||
307 | // BIG HACK here | ||
308 | UUID newID = olditem.AssetID; | ||
309 | if (Item != null) | ||
310 | { | ||
311 | if (olditem.Name != String.Empty) | ||
312 | { | ||
313 | Item.Name = olditem.Name; | ||
314 | } | ||
315 | Item.ID = newID; | ||
316 | Item.Folder = olditem.Folder; | ||
317 | Item.Owner = olditem.Owner; | ||
318 | // There should be some tests here about the owner, etc but I'm going to ignore that | ||
319 | // because I'm not sure it makes any sense | ||
320 | // Also I should probably clone the asset... | ||
321 | m_inventoryService.AddItem(Item); | ||
322 | return Item; | ||
323 | } | ||
324 | else | ||
325 | { | ||
326 | m_log.Debug("[HGStandaloneInvService]: Failed to find item " + olditem.ID); | ||
327 | olditem.ID = UUID.Zero; | ||
328 | return olditem; | ||
329 | } | ||
330 | |||
331 | } | ||
332 | |||
333 | /// <summary> | ||
334 | /// Guid to UUID wrapper for same name IInventoryServices method | ||
335 | /// </summary> | ||
336 | /// <param name="rawUserID"></param> | ||
337 | /// <returns></returns> | ||
338 | public List<InventoryFolderBase> GetInventorySkeleton(Guid rawUserID) | ||
339 | { | ||
340 | UUID userID = new UUID(rawUserID); | ||
341 | return m_inventoryService.GetInventorySkeleton(userID); | ||
342 | } | ||
343 | |||
344 | public List<InventoryItemBase> GetActiveGestures(Guid rawUserID) | ||
345 | { | ||
346 | UUID userID = new UUID(rawUserID); | ||
347 | |||
348 | m_log.InfoFormat("[HGStandaloneInvService]: fetching active gestures for user {0}", userID); | ||
349 | |||
350 | return m_inventoryService.GetActiveGestures(userID); | ||
351 | } | ||
352 | |||
353 | public AssetBase GetAsset(InventoryItemBase item) | ||
354 | { | ||
355 | m_log.Info("[HGStandaloneInvService]: Get asset " + item.AssetID + " for item " + item.ID); | ||
356 | AssetBase asset = new AssetBase(item.AssetID, "NULL"); // send an asset with no data | ||
357 | InventoryItemBase item2 = m_inventoryService.GetInventoryItem(item.ID); | ||
358 | if (item2 == null) | ||
359 | { | ||
360 | m_log.Debug("[HGStandaloneInvService]: null item"); | ||
361 | return asset; | ||
362 | } | ||
363 | if (item2.Owner != item.Owner) | ||
364 | { | ||
365 | m_log.DebugFormat("[HGStandaloneInvService]: client with uuid {0} is trying to get an item of owner {1}", item.Owner, item2.Owner); | ||
366 | return asset; | ||
367 | } | ||
368 | UUID assetID = item2.AssetID; | ||
369 | if (assetID != item.AssetID) | ||
370 | { | ||
371 | m_log.WarnFormat("[HGStandaloneInvService]: asset IDs don't match {0}, {1}", item.AssetID, item2.AssetID); | ||
372 | } | ||
373 | |||
374 | // All good, get the asset | ||
375 | //AssetBase theasset = m_assetProvider.FetchAsset(item.AssetID); | ||
376 | AssetBase theasset = FetchAsset(assetID, (item.InvType == (int)InventoryType.Texture)); | ||
377 | |||
378 | m_log.Debug("[HGStandaloneInvService] Found asset " + ((theasset == null) ? "NULL" : "Not Null")); | ||
379 | if (theasset != null) | ||
380 | { | ||
381 | asset = theasset; | ||
382 | //m_log.Debug(" >> Sending assetID " + item.AssetID); | ||
383 | } | ||
384 | return asset; | ||
385 | } | ||
386 | |||
387 | public bool PostAsset(AssetBase asset) | ||
388 | { | ||
389 | m_log.Info("[HGStandaloneInvService]: Post asset " + asset.FullID); | ||
390 | //m_assetProvider.CreateAsset(asset); | ||
391 | StoreAsset(asset); | ||
392 | |||
393 | return true; | ||
394 | } | ||
395 | |||
396 | public void PostAnAsset(AssetBase asset) | ||
397 | { | ||
398 | PostAsset(asset); | ||
399 | } | ||
400 | |||
401 | /// <summary> | ||
402 | /// <see>CapsUpdatedInventoryItemAsset(IClientAPI, UUID, byte[])</see> | ||
403 | /// </summary> | ||
404 | public UUID UpdateInventoryItemAsset(UUID userID, UUID itemID, byte[] data) | ||
405 | { | ||
406 | m_log.Debug("[HGStandaloneInvService]: UpdateInventoryitemAsset for user " + userID + " item " + itemID); | ||
407 | InventoryItemBase item = m_inventoryService.GetInventoryItem(itemID); | ||
408 | |||
409 | if (item != null) | ||
410 | { | ||
411 | // We're still not dealing with permissions | ||
412 | //if ((InventoryType)item.InvType == InventoryType.Notecard) | ||
413 | //{ | ||
414 | // if (!Permissions.CanEditNotecard(itemID, UUID.Zero, userID)) | ||
415 | // { | ||
416 | // //remoteClient.SendAgentAlertMessage("Insufficient permissions to edit notecard", false); | ||
417 | // return UUID.Zero; | ||
418 | // } | ||
419 | |||
420 | // //remoteClient.SendAgentAlertMessage("Notecard saved", false); | ||
421 | //} | ||
422 | //else if ((InventoryType)item.InvType == InventoryType.LSL) | ||
423 | //{ | ||
424 | // if (!Permissions.CanEditScript(itemID, UUID.Zero, remoteClient.AgentId)) | ||
425 | // { | ||
426 | // //remoteClient.SendAgentAlertMessage("Insufficient permissions to edit script", false); | ||
427 | // return UUID.Zero; | ||
428 | // } | ||
429 | |||
430 | // //remoteClient.SendAgentAlertMessage("Script saved", false); | ||
431 | //} | ||
432 | |||
433 | AssetBase asset = CreateAsset(item.Name, item.Description, (sbyte)item.AssetType, data); | ||
434 | PostAsset(asset); | ||
435 | |||
436 | item.AssetID = asset.FullID; | ||
437 | item.Owner = userID; | ||
438 | m_inventoryService.UpdateItem(item); | ||
439 | |||
440 | return (asset.FullID); | ||
441 | } | ||
442 | return UUID.Zero; | ||
443 | } | ||
444 | |||
445 | private AssetBase CreateAsset(string name, string description, sbyte assetType, byte[] data) | ||
446 | { | ||
447 | AssetBase asset = new AssetBase(); | ||
448 | asset.Name = name; | ||
449 | asset.Description = description; | ||
450 | asset.Type = assetType; | ||
451 | asset.FullID = UUID.Random(); | ||
452 | asset.Data = (data == null) ? new byte[1] : data; | ||
453 | |||
454 | return asset; | ||
455 | } | ||
456 | |||
457 | #region Caps | ||
458 | |||
459 | Dictionary<UUID, Hashtable> invCaps = new Dictionary<UUID, Hashtable>(); | ||
460 | |||
461 | public Hashtable CapHandler(Hashtable request) | ||
462 | { | ||
463 | m_log.Debug("[CONNECTION DEBUGGING]: InvCapHandler Called"); | ||
464 | |||
465 | m_log.Debug("---------------------------"); | ||
466 | m_log.Debug(" >> uri=" + request["uri"]); | ||
467 | m_log.Debug(" >> content-type=" + request["content-type"]); | ||
468 | m_log.Debug(" >> http-method=" + request["http-method"]); | ||
469 | m_log.Debug("---------------------------\n"); | ||
470 | |||
471 | // these are requests if the type | ||
472 | // http://inventoryserver/InvCap/uuuuuuuu-uuuu-uuuu-uuuu-uuuuuuuuuuuu/kkkkkkkk-kkkk-kkkk-kkkk-kkkkkkkkkkkk/ | ||
473 | |||
474 | Hashtable responsedata = new Hashtable(); | ||
475 | responsedata["content_type"] = "text/plain"; | ||
476 | |||
477 | UUID userID; | ||
478 | string authToken = string.Empty; | ||
479 | string authority = string.Empty; | ||
480 | if (!GetParams(request, out userID, out authority, out authToken)) | ||
481 | { | ||
482 | m_log.InfoFormat("[HGStandaloneInvService]: Invalid parameters for InvCap message {0}", request["uri"]); | ||
483 | responsedata["int_response_code"] = 404; | ||
484 | responsedata["str_response_string"] = "Not found"; | ||
485 | |||
486 | return responsedata; | ||
487 | } | ||
488 | |||
489 | // Next, let's parse the verb | ||
490 | string method = (string)request["http-method"]; | ||
491 | if (method.Equals("GET")) | ||
492 | { | ||
493 | DoInvCapPost(request, responsedata, userID, authority, authToken); | ||
494 | return responsedata; | ||
495 | } | ||
496 | //else if (method.Equals("DELETE")) | ||
497 | //{ | ||
498 | // DoAgentDelete(request, responsedata, agentID, action, regionHandle); | ||
499 | |||
500 | // return responsedata; | ||
501 | //} | ||
502 | else | ||
503 | { | ||
504 | m_log.InfoFormat("[HGStandaloneInvService]: method {0} not supported in agent message", method); | ||
505 | responsedata["int_response_code"] = 405; | ||
506 | responsedata["str_response_string"] = "Method not allowed"; | ||
507 | |||
508 | return responsedata; | ||
509 | } | ||
510 | |||
511 | } | ||
512 | |||
513 | public virtual void DoInvCapPost(Hashtable request, Hashtable responsedata, UUID userID, string authority, string authToken) | ||
514 | { | ||
515 | |||
516 | // This is the meaning of POST agent | ||
517 | |||
518 | // Check Auth Token | ||
519 | if ((m_userService != null) && !(m_userService is IAuthentication)) | ||
520 | { | ||
521 | m_log.Debug("[HGStandaloneInvService]: UserService is not IAuthentication. Denying access to inventory."); | ||
522 | responsedata["int_response_code"] = 501; | ||
523 | responsedata["str_response_string"] = "Not implemented"; | ||
524 | return; | ||
525 | } | ||
526 | |||
527 | bool success = VerifyKey(userID, authority, authToken); | ||
528 | |||
529 | if (success) | ||
530 | { | ||
531 | |||
532 | m_log.DebugFormat("[HGStandaloneInvService]: User has been authorized. Creating service handlers."); | ||
533 | |||
534 | // Then establish secret service handlers | ||
535 | |||
536 | Hashtable usercaps = RegisterCaps(userID, authToken); | ||
537 | |||
538 | responsedata["int_response_code"] = 200; | ||
539 | //responsedata["str_response_string"] = "OK"; | ||
540 | responsedata["str_response_string"] = SerializeHashtable(usercaps); | ||
541 | } | ||
542 | else | ||
543 | { | ||
544 | m_log.DebugFormat("[HGStandaloneInvService]: User has is unauthorized. Denying service handlers."); | ||
545 | responsedata["int_response_code"] = 403; | ||
546 | responsedata["str_response_string"] = "Forbidden"; | ||
547 | } | ||
548 | } | ||
549 | |||
550 | |||
551 | /// <summary> | ||
552 | /// Extract the params from a request. | ||
553 | /// </summary> | ||
554 | public static bool GetParams(Hashtable request, out UUID uuid, out string authority, out string authKey) | ||
555 | { | ||
556 | uuid = UUID.Zero; | ||
557 | authority = string.Empty; | ||
558 | authKey = string.Empty; | ||
559 | |||
560 | string uri = (string)request["uri"]; | ||
561 | uri = uri.Trim(new char[] { '/' }); | ||
562 | string[] parts = uri.Split('/'); | ||
563 | if (parts.Length <= 1) | ||
564 | { | ||
565 | return false; | ||
566 | } | ||
567 | else | ||
568 | { | ||
569 | if (!UUID.TryParse(parts[1], out uuid)) | ||
570 | return false; | ||
571 | |||
572 | if (parts.Length >= 3) | ||
573 | { | ||
574 | authKey = parts[2]; | ||
575 | return true; | ||
576 | } | ||
577 | } | ||
578 | |||
579 | Uri authUri; | ||
580 | Hashtable headers = (Hashtable)request["headers"]; | ||
581 | |||
582 | // Authorization keys look like this: | ||
583 | // http://orgrid.org:8002/<uuid> | ||
584 | if (headers.ContainsKey("authorization")) | ||
585 | { | ||
586 | if (Uri.TryCreate((string)headers["authorization"], UriKind.Absolute, out authUri)) | ||
587 | { | ||
588 | authority = authUri.Authority; | ||
589 | authKey = authUri.PathAndQuery.Trim('/'); | ||
590 | m_log.DebugFormat("[HGStandaloneInvService]: Got authority {0} and key {1}", authority, authKey); | ||
591 | return true; | ||
592 | } | ||
593 | else | ||
594 | m_log.Debug("[HGStandaloneInvService]: Wrong format for Authorization header: " + (string)headers["authorization"]); | ||
595 | } | ||
596 | else | ||
597 | m_log.Debug("[HGStandaloneInvService]: Authorization header not found"); | ||
598 | |||
599 | return false; | ||
600 | } | ||
601 | |||
602 | string SerializeHashtable(Hashtable hash) | ||
603 | { | ||
604 | string result = string.Empty; | ||
605 | foreach (object key in hash.Keys) | ||
606 | { | ||
607 | result += key.ToString() + "," + hash[key].ToString() + ";"; | ||
608 | } | ||
609 | return result; | ||
610 | } | ||
611 | |||
612 | Hashtable RegisterCaps(UUID userID, string authToken) | ||
613 | { | ||
614 | lock (invCaps) | ||
615 | { | ||
616 | if (invCaps.ContainsKey(userID)) | ||
617 | { | ||
618 | // Remove the old ones | ||
619 | DeregisterCaps(httpServer, invCaps[userID]); | ||
620 | invCaps.Remove(userID); | ||
621 | } | ||
622 | } | ||
623 | |||
624 | Caps caps = new Caps(null, httpServer, m_thisHostname, m_thisPort, authToken, userID, false, "Inventory"); | ||
625 | caps.RegisterInventoryServiceHandlers("/" + authToken + "/InventoryCap/"); | ||
626 | caps.ItemUpdatedCall = UpdateInventoryItemAsset; | ||
627 | caps.AddNewInventoryItem = AddUploadedInventoryItem; | ||
628 | caps.AddNewAsset = PostAnAsset; | ||
629 | //caps.GetClient = | ||
630 | |||
631 | Hashtable capsHandlers = caps.CapsHandlers.CapsDetails; | ||
632 | |||
633 | httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<Guid, InventoryCollection>( | ||
634 | "POST", AddAndGetCapUrl(authToken, "GetInventory", capsHandlers), GetUserInventory, CheckAuthSession)); | ||
635 | |||
636 | httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<InventoryFolderBase, InventoryCollection>( | ||
637 | "POST", AddAndGetCapUrl(authToken, "FetchDescendants", capsHandlers), FetchDescendants, CheckAuthSession)); | ||
638 | httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<InventoryFolderBase, bool>( | ||
639 | "POST", AddAndGetCapUrl(authToken, "NewFolder", capsHandlers), m_inventoryService.AddFolder, CheckAuthSession)); | ||
640 | httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<InventoryFolderBase, bool>( | ||
641 | "POST", AddAndGetCapUrl(authToken, "UpdateFolder", capsHandlers), m_inventoryService.UpdateFolder, CheckAuthSession)); | ||
642 | httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<InventoryFolderBase, bool>( | ||
643 | "POST", AddAndGetCapUrl(authToken, "MoveFolder", capsHandlers), m_inventoryService.MoveFolder, CheckAuthSession)); | ||
644 | httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<InventoryFolderBase, bool>( | ||
645 | "POST", AddAndGetCapUrl(authToken, "PurgeFolder", capsHandlers), m_inventoryService.PurgeFolder, CheckAuthSession)); | ||
646 | httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<InventoryFolderBase, bool>( | ||
647 | "POST", AddAndGetCapUrl(authToken, "RemoveFolder", capsHandlers), RemoveFolder, CheckAuthSession)); | ||
648 | |||
649 | httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<InventoryItemBase, InventoryItemBase>( | ||
650 | "POST", AddAndGetCapUrl(authToken, "GetItem", capsHandlers), GetInventoryItem, CheckAuthSession)); | ||
651 | httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<InventoryItemBase, InventoryItemBase>( | ||
652 | "POST", AddAndGetCapUrl(authToken, "NewItem", capsHandlers), AddItem, CheckAuthSession)); | ||
653 | httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<InventoryItemBase, InventoryItemBase>( | ||
654 | "POST", AddAndGetCapUrl(authToken, "UpdateItem", capsHandlers), UpdateItem, CheckAuthSession)); | ||
655 | httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<InventoryItemBase, InventoryItemBase>( | ||
656 | "POST", AddAndGetCapUrl(authToken, "MoveItem", capsHandlers), MoveItem, CheckAuthSession)); | ||
657 | httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<InventoryItemBase, InventoryItemBase>( | ||
658 | "POST", AddAndGetCapUrl(authToken, "DeleteItem", capsHandlers), DeleteItem, CheckAuthSession)); | ||
659 | httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<InventoryItemBase, InventoryItemBase>( | ||
660 | "POST", AddAndGetCapUrl(authToken, "CopyItem", capsHandlers), CopyItem, CheckAuthSession)); | ||
661 | |||
662 | httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<InventoryItemBase, AssetBase>( | ||
663 | "POST", AddAndGetCapUrl(authToken, "GetAsset", capsHandlers), GetAsset, CheckAuthSession)); | ||
664 | httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<AssetBase, bool>( | ||
665 | "POST", AddAndGetCapUrl(authToken, "PostAsset", capsHandlers), PostAsset, CheckAuthSession)); | ||
666 | |||
667 | lock (invCaps) | ||
668 | invCaps.Add(userID, capsHandlers); | ||
669 | |||
670 | return capsHandlers; | ||
671 | } | ||
672 | |||
673 | string AddAndGetCapUrl(string authToken, string capType, Hashtable caps) | ||
674 | { | ||
675 | string capUrl = "/" + authToken + "/" + capType + "/"; | ||
676 | |||
677 | m_log.Debug("[HGStandaloneInvService] Adding inventory cap " + capUrl); | ||
678 | caps.Add(capType, capUrl); | ||
679 | return capUrl; | ||
680 | } | ||
681 | |||
682 | void DeregisterCaps(IHttpServer httpServer, Hashtable caps) | ||
683 | { | ||
684 | foreach (string capUrl in caps.Values) | ||
685 | { | ||
686 | m_log.Debug("[HGStandaloneInvService] Removing inventory cap " + capUrl); | ||
687 | httpServer.RemoveStreamHandler("POST", capUrl); | ||
688 | } | ||
689 | } | ||
690 | |||
691 | #endregion Caps | ||
692 | |||
693 | #region Local vs Remote | ||
694 | |||
695 | bool VerifyKey(UUID userID, string authority, string key) | ||
696 | { | ||
697 | // Remote call to the Authorization server | ||
698 | if (m_userService == null) | ||
699 | return AuthClient.VerifyKey("http://" + authority, userID, key); | ||
700 | // local call | ||
701 | else | ||
702 | return ((IAuthentication)m_userService).VerifyKey(userID, key); | ||
703 | } | ||
704 | |||
705 | AssetBase FetchAsset(UUID assetID, bool isTexture) | ||
706 | { | ||
707 | // Remote call to the Asset server | ||
708 | if (m_assetProvider == null) | ||
709 | return m_AssetClient.SyncGetAsset(assetID, isTexture); | ||
710 | // local call | ||
711 | else | ||
712 | return m_assetProvider.Get(assetID.ToString()); | ||
713 | } | ||
714 | |||
715 | void StoreAsset(AssetBase asset) | ||
716 | { | ||
717 | // Remote call to the Asset server | ||
718 | if (m_assetProvider == null) | ||
719 | m_AssetClient.StoreAsset(asset); | ||
720 | // local call | ||
721 | else | ||
722 | m_assetProvider.Store(asset); | ||
723 | } | ||
724 | |||
725 | #endregion Local vs Remote | ||
726 | } | ||
727 | |||
728 | class SynchronousGridAssetClient : GridAssetClient | ||
729 | { | ||
730 | public SynchronousGridAssetClient(string url) | ||
731 | : base(url) | ||
732 | { | ||
733 | } | ||
734 | |||
735 | public AssetBase SyncGetAsset(UUID assetID, bool isTexture) | ||
736 | { | ||
737 | AssetRequest assReq = new AssetRequest(); | ||
738 | assReq.AssetID = assetID; | ||
739 | assReq.IsTexture = isTexture; | ||
740 | return base.GetAsset(assReq); | ||
741 | } | ||
742 | |||
743 | } | ||
744 | } | ||