aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authordiva2009-03-29 20:29:13 +0000
committerdiva2009-03-29 20:29:13 +0000
commit08732b65be3ce13e8dd965a4542991a766dbd920 (patch)
tree6468b2da6513dc5be0859c196d14fc015fdeeb05
parentDon't let a missing configuration cause a NRE (diff)
downloadopensim-SC_OLD-08732b65be3ce13e8dd965a4542991a766dbd920.zip
opensim-SC_OLD-08732b65be3ce13e8dd965a4542991a766dbd920.tar.gz
opensim-SC_OLD-08732b65be3ce13e8dd965a4542991a766dbd920.tar.bz2
opensim-SC_OLD-08732b65be3ce13e8dd965a4542991a766dbd920.tar.xz
Moved some files around, so that it's easier to share code between standalone and the grid services. Should not affect any functionality.
Diffstat (limited to '')
-rw-r--r--OpenSim/Framework/Communications/Services/HGInventoryService.cs (renamed from OpenSim/Region/CoreModules/Hypergrid/HGStandaloneInventoryService.cs)1443
-rw-r--r--OpenSim/Framework/Communications/Services/HGLoginAuthService.cs (renamed from OpenSim/Framework/Communications/HGLoginAuthService.cs)2
-rw-r--r--OpenSim/Grid/UserServer.Modules/UserLoginAuthService.cs1
-rw-r--r--OpenSim/Region/CoreModules/Hypergrid/HGStandaloneInventoryModule.cs165
-rw-r--r--OpenSim/Region/CoreModules/Hypergrid/HGStandaloneLoginModule.cs1
5 files changed, 804 insertions, 808 deletions
diff --git a/OpenSim/Region/CoreModules/Hypergrid/HGStandaloneInventoryService.cs b/OpenSim/Framework/Communications/Services/HGInventoryService.cs
index e619f13..f0b2259 100644
--- a/OpenSim/Region/CoreModules/Hypergrid/HGStandaloneInventoryService.cs
+++ b/OpenSim/Framework/Communications/Services/HGInventoryService.cs
@@ -1,807 +1,636 @@
1/** 1/**
2 * Copyright (c) 2008, Contributors. All rights reserved. 2 * Copyright (c) 2008, Contributors. All rights reserved.
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without modification, 5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met: 6 * are permitted provided that the following conditions are met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright notice, 8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer. 9 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright notice, 10 * * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation 11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution. 12 * and/or other materials provided with the distribution.
13 * * Neither the name of the Organizations nor the names of Individual 13 * * Neither the name of the Organizations nor the names of Individual
14 * Contributors may be used to endorse or promote products derived from 14 * Contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission. 15 * this software without specific prior written permission.
16 * 16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
20 * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 20 * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
22 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 22 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 24 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
25 * OF THE POSSIBILITY OF SUCH DAMAGE. 25 * OF THE POSSIBILITY OF SUCH DAMAGE.
26 * 26 *
27 */ 27 */
28 28
29using System; 29using System;
30using System.Collections; 30using System.Collections;
31using System.Collections.Generic; 31using System.Collections.Generic;
32using System.Reflection; 32using System.Reflection;
33using log4net; 33using log4net;
34using Nini.Config; 34using Nini.Config;
35using OpenMetaverse; 35using OpenMetaverse;
36using OpenSim.Data; 36using OpenSim.Data;
37using OpenSim.Framework; 37using OpenSim.Framework;
38using OpenSim.Framework.Communications; 38//using OpenSim.Framework.Communications;
39using OpenSim.Framework.Communications.Cache; 39using OpenSim.Framework.Communications.Cache;
40using Caps = OpenSim.Framework.Communications.Capabilities.Caps; 40using Caps = OpenSim.Framework.Communications.Capabilities.Caps;
41using LLSDHelpers = OpenSim.Framework.Communications.Capabilities.LLSDHelpers; 41using LLSDHelpers = OpenSim.Framework.Communications.Capabilities.LLSDHelpers;
42using OpenSim.Framework.Servers; 42using OpenSim.Framework.Servers;
43using OpenSim.Framework.Servers.Interfaces; 43using OpenSim.Framework.Servers.Interfaces;
44using OpenSim.Region.Framework.Interfaces; 44
45using OpenSim.Region.Framework.Scenes; 45using OpenMetaverse.StructuredData;
46using OpenSim.Region.CoreModules.Communications.REST; 46
47 47namespace OpenSim.Framework.Communications.Services
48using OpenMetaverse.StructuredData; 48{
49 49 public class HGInventoryService
50namespace OpenSim.Region.CoreModules.Hypergrid 50 {
51{ 51 private static readonly ILog m_log
52 public class HGStandaloneInventoryService : IRegionModule 52 = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
53 { 53
54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 54 private InventoryServiceBase m_inventoryService;
55 private static bool initialized = false; 55 private UserManagerBase m_userService;
56 private static bool enabled = false; 56 IAssetDataPlugin m_assetProvider;
57 57 IHttpServer httpServer;
58 Scene m_scene; 58 private string m_thisInventoryUrl = "http://localhost:9000";
59 //InventoryService m_inventoryService; 59 private string m_thisHostname = "127.0.0.1";
60 60 private uint m_thisPort = 9000;
61 #region IRegionModule interface 61
62 62
63 public void Initialise(Scene scene, IConfigSource config) 63 public HGInventoryService(InventoryServiceBase invService, IAssetDataPlugin assetService, UserManagerBase userService, IHttpServer httpserver, string url)
64 { 64 {
65 if (!initialized) 65 m_inventoryService = invService;
66 { 66 m_userService = userService;
67 initialized = true; 67 m_thisInventoryUrl = url;
68 m_scene = scene; 68 if (!m_thisInventoryUrl.EndsWith("/"))
69 69 m_thisInventoryUrl += "/";
70 // This module is only on for standalones 70
71 enabled = !config.Configs["Startup"].GetBoolean("gridmode", true) && config.Configs["Startup"].GetBoolean("hypergrid", false); 71 Uri uri = new Uri(m_thisInventoryUrl);
72 } 72 if (uri != null)
73 } 73 {
74 74 m_thisHostname = uri.Host;
75 public void PostInitialise() 75 m_thisPort = (uint)uri.Port;
76 { 76 }
77 if (enabled) 77
78 { 78 m_assetProvider = assetService;
79 m_log.Info("[HGStandaloneInvService]: Starting..."); 79 httpServer = httpserver;
80 //m_inventoryService = new InventoryService(m_scene); 80
81 new InventoryService(m_scene); 81 AddHttpHandlers();
82 } 82 }
83 } 83
84 84 public virtual void AddHttpHandlers()
85 public void Close() 85 {
86 { 86 httpServer.AddHTTPHandler("/InvCap/", CapHandler);
87 } 87 }
88 88
89 public string Name 89 public bool CheckAuthSession(string session_id, string avatar_id)
90 { 90 {
91 get { return "HGStandaloneInventoryService"; } 91 return true;
92 } 92 }
93 93
94 public bool IsSharedModule 94
95 { 95 // In truth, this is not called from the outside, for standalones. I'm just making it
96 get { return true; } 96 // a handler already so that this can be reused for the InventoryServer.
97 } 97 public string CreateCapUrl(Guid _userid)
98 98 {
99 #endregion 99 UUID userID = new UUID(_userid);
100 } 100 UUID random = UUID.Random();
101 101 string url = m_thisInventoryUrl + random.ToString() + "/";
102 public class InventoryService 102 m_log.InfoFormat("[HGStandaloneInvService] Creating Cap URL {0} for user {1}", url, userID.ToString());
103 { 103 return url;
104 private static readonly ILog m_log 104 }
105 = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 105
106 106 /// <summary>
107 private InventoryServiceBase m_inventoryService; 107 /// Return a user's entire inventory
108 private UserManagerBase m_userService; 108 /// </summary>
109 IAssetDataPlugin m_assetProvider; 109 /// <param name="rawUserID"></param>
110 private Scene m_scene; 110 /// <returns>The user's inventory. If an inventory cannot be found then an empty collection is returned.</returns>
111 private bool m_doLookup = false; 111 public InventoryCollection GetUserInventory(Guid rawUserID)
112 private string m_thisInventoryUrl = "http://localhost:9000"; 112 {
113 private string m_thisHostname = "127.0.0.1"; 113 UUID userID = new UUID(rawUserID);
114 private uint m_thisPort = 9000; 114
115 115 m_log.Info("[HGStandaloneInvModule]: Processing request for inventory of " + userID);
116 public bool DoLookup 116
117 { 117 // Uncomment me to simulate a slow responding inventory server
118 get { return m_doLookup; } 118 //Thread.Sleep(16000);
119 set { m_doLookup = value; } 119
120 } 120 InventoryCollection invCollection = new InventoryCollection();
121 121
122 public InventoryService(Scene _m_scene) 122 List<InventoryFolderBase> allFolders = m_inventoryService.GetInventorySkeleton(userID);
123 { 123
124 m_scene = _m_scene; 124 if (null == allFolders)
125 m_inventoryService = (InventoryServiceBase)m_scene.CommsManager.SecureInventoryService; 125 {
126 m_userService = (UserManagerBase)m_scene.CommsManager.UserService; 126 m_log.WarnFormat("[HGStandaloneInvModule]: No inventory found for user {0}", rawUserID);
127 m_thisInventoryUrl = m_scene.CommsManager.NetworkServersInfo.InventoryURL; 127
128 if (!m_thisInventoryUrl.EndsWith("/")) 128 return invCollection;
129 m_thisInventoryUrl += "/"; 129 }
130 130
131 Uri uri = new Uri(m_thisInventoryUrl); 131 List<InventoryItemBase> allItems = new List<InventoryItemBase>();
132 if (uri != null) 132
133 { 133 foreach (InventoryFolderBase folder in allFolders)
134 m_thisHostname = uri.Host; 134 {
135 m_thisPort = (uint)uri.Port; 135 List<InventoryItemBase> items = m_inventoryService.RequestFolderItems(folder.ID);
136 } 136
137 137 if (items != null)
138 m_assetProvider = ((AssetServerBase)m_scene.CommsManager.AssetCache.AssetServer).AssetProviderPlugin; 138 {
139 139 allItems.InsertRange(0, items);
140 AddHttpHandlers(); 140 }
141 } 141 }
142 142
143 protected void AddHttpHandlers() 143 invCollection.UserID = userID;
144 { 144 invCollection.Folders = allFolders;
145 IHttpServer httpServer = m_scene.CommsManager.HttpServer; 145 invCollection.Items = allItems;
146 146
147 httpServer.AddHTTPHandler("/InvCap/", CapHandler); 147 // foreach (InventoryFolderBase folder in invCollection.Folders)
148 148 // {
149 httpServer.AddStreamHandler( 149 // m_log.DebugFormat("[GRID AGENT INVENTORY]: Sending back folder {0} {1}", folder.Name, folder.ID);
150 new RestDeserialiseSecureHandler<Guid, InventoryCollection>( 150 // }
151 "POST", "/GetInventory/", GetUserInventory, CheckAuthSession)); 151 //
152 152 // foreach (InventoryItemBase item in invCollection.Items)
153 httpServer.AddStreamHandler( 153 // {
154 new RestDeserialiseSecureHandler<InventoryFolderBase, bool>( 154 // m_log.DebugFormat("[GRID AGENT INVENTORY]: Sending back item {0} {1}, folder {2}", item.Name, item.ID, item.Folder);
155 "POST", "/NewFolder/", m_inventoryService.AddFolder, CheckAuthSession)); 155 // }
156 156
157 httpServer.AddStreamHandler( 157 m_log.InfoFormat(
158 new RestDeserialiseSecureHandler<InventoryFolderBase, bool>( 158 "[HGStandaloneInvModule]: Sending back inventory response to user {0} containing {1} folders and {2} items",
159 "POST", "/UpdateFolder/", m_inventoryService.UpdateFolder, CheckAuthSession)); 159 invCollection.UserID, invCollection.Folders.Count, invCollection.Items.Count);
160 160
161 httpServer.AddStreamHandler( 161 return invCollection;
162 new RestDeserialiseSecureHandler<InventoryFolderBase, bool>( 162 }
163 "POST", "/MoveFolder/", m_inventoryService.MoveFolder, CheckAuthSession)); 163
164 164 public InventoryCollection FetchDescendants(InventoryFolderBase fb)
165 httpServer.AddStreamHandler( 165 {
166 new RestDeserialiseSecureHandler<InventoryFolderBase, bool>( 166 m_log.Info("[HGStandaloneInvService]: Processing request for folder " + fb.ID);
167 "POST", "/PurgeFolder/", m_inventoryService.PurgeFolder, CheckAuthSession)); 167
168 168 // Uncomment me to simulate a slow responding inventory server
169 httpServer.AddStreamHandler( 169 //Thread.Sleep(16000);
170 new RestDeserialiseSecureHandler<InventoryItemBase, bool>( 170
171 "POST", "/NewItem/", m_inventoryService.AddItem, CheckAuthSession)); 171 InventoryCollection invCollection = new InventoryCollection();
172 172
173 httpServer.AddStreamHandler( 173 List<InventoryItemBase> items = m_inventoryService.RequestFolderItems(fb.ID);
174 new RestDeserialiseSecureHandler<InventoryItemBase, bool>( 174 List<InventoryFolderBase> folders = m_inventoryService.RequestSubFolders(fb.ID);
175 "POST", "/DeleteItem/", m_inventoryService.DeleteItem, CheckAuthSession)); 175
176 176 invCollection.UserID = fb.Owner;
177 //// WARNING: Root folders no longer just delivers the root and immediate child folders (e.g 177 invCollection.Folders = folders;
178 //// system folders such as Objects, Textures), but it now returns the entire inventory skeleton. 178 invCollection.Items = items;
179 //// It would have been better to rename this request, but complexities in the BaseHttpServer 179
180 //// (e.g. any http request not found is automatically treated as an xmlrpc request) make it easier 180 m_log.DebugFormat("[HGStandaloneInvService]: Found {0} items and {1} folders", items.Count, folders.Count);
181 //// to do this for now. 181
182 //m_scene.AddStreamHandler( 182 return invCollection;
183 // new RestDeserialiseTrustedHandler<Guid, List<InventoryFolderBase>> 183 }
184 // ("POST", "/RootFolders/", GetInventorySkeleton, CheckTrustSource)); 184
185 185 public bool RemoveFolder(InventoryFolderBase folder)
186 //// for persistent active gestures 186 {
187 //m_scene.AddStreamHandler( 187 m_log.Debug("[HGStandaloneInvService]: Removefolder: Operation not implemented yet.");
188 // new RestDeserialiseTrustedHandler<Guid, List<InventoryItemBase>> 188 return false;
189 // ("POST", "/ActiveGestures/", GetActiveGestures, CheckTrustSource)); 189 }
190 } 190
191 191 public InventoryItemBase GetInventoryItem(InventoryItemBase item)
192 192 {
193 ///// <summary> 193 m_log.Info("[HGStandaloneInvService]: Get item " + item.ID);
194 ///// Check that the source of an inventory request is one that we trust. 194
195 ///// </summary> 195 item = m_inventoryService.GetInventoryItem(item.ID);
196 ///// <param name="peer"></param> 196 if (item == null)
197 ///// <returns></returns> 197 m_log.Debug("[HGStandaloneInvService]: null item");
198 //public bool CheckTrustSource(IPEndPoint peer) 198 return item;
199 //{ 199 }
200 // if (m_doLookup) 200
201 // { 201 public InventoryItemBase AddItem(InventoryItemBase item)
202 // m_log.InfoFormat("[GRID AGENT INVENTORY]: Checking trusted source {0}", peer); 202 {
203 // UriBuilder ub = new UriBuilder(m_userserver_url); 203 m_log.DebugFormat("[HGStandaloneInvService]: Add item {0} from {1}", item.ID, item.Owner);
204 // IPAddress[] uaddrs = Dns.GetHostAddresses(ub.Host); 204 if (m_inventoryService.AddItem(item))
205 // foreach (IPAddress uaddr in uaddrs) 205 return item;
206 // { 206 else
207 // if (uaddr.Equals(peer.Address)) 207 {
208 // { 208 item.ID = UUID.Zero;
209 // return true; 209 return item;
210 // } 210 }
211 // } 211 }
212 212
213 // m_log.WarnFormat( 213 public InventoryItemBase UpdateItem(InventoryItemBase item)
214 // "[GRID AGENT INVENTORY]: Rejecting request since source {0} was not in the list of trusted sources", 214 {
215 // peer); 215 m_log.DebugFormat("[HGStandaloneInvService]: Update item {0} from {1}", item.ID, item.Owner);
216 216 InventoryItemBase it = m_inventoryService.GetInventoryItem(item.ID);
217 // return false; 217 item.CurrentPermissions = it.CurrentPermissions;
218 // } 218 item.AssetID = it.AssetID;
219 // else 219 if (m_inventoryService.UpdateItem(item))
220 // { 220 return item;
221 // return true; 221 else
222 // } 222 {
223 //} 223 item.ID = UUID.Zero;
224 224 return item;
225 /// <summary> 225 }
226 /// Check that the source of an inventory request for a particular agent is a current session belonging to 226 }
227 /// that agent. 227
228 /// </summary> 228 public InventoryItemBase MoveItem(InventoryItemBase newitem)
229 /// <param name="session_id"></param> 229 {
230 /// <param name="avatar_id"></param> 230 m_log.DebugFormat("[HGStandaloneInvService]: Move item {0} from {1}", newitem.ID, newitem.Owner);
231 /// <returns></returns> 231 InventoryItemBase Item = m_inventoryService.GetInventoryItem(newitem.ID);
232 public bool CheckAuthSession(string session_id, string avatar_id) 232 if (Item != null)
233 { 233 {
234 if (m_doLookup) 234 if (newitem.Name != String.Empty)
235 { 235 {
236 m_log.InfoFormat("[HGStandaloneInvService]: checking authed session {0} {1}", session_id, avatar_id); 236 Item.Name = newitem.Name;
237 UUID userID = UUID.Zero; 237 }
238 UUID sessionID = UUID.Zero; 238 Item.Folder = newitem.Folder;
239 UUID.TryParse(avatar_id, out userID); 239 m_inventoryService.UpdateItem(Item);
240 UUID.TryParse(session_id, out sessionID); 240 return Item;
241 if (userID.Equals(UUID.Zero) || sessionID.Equals(UUID.Zero)) 241 }
242 { 242 else
243 m_log.Info("[HGStandaloneInvService]: Invalid user or session id " + avatar_id + "; " + session_id); 243 {
244 return false; 244 m_log.Debug("[HGStandaloneInvService]: Failed to find item " + newitem.ID);
245 } 245 newitem.ID = UUID.Zero;
246 UserProfileData userProfile = m_userService.GetUserProfile(userID); 246 return newitem;
247 if (userProfile != null && userProfile.CurrentAgent != null && 247 }
248 userProfile.CurrentAgent.SessionID == sessionID) 248
249 { 249 }
250 m_log.Info("[HGStandaloneInvService]: user is logged in and session is valid. Authorizing access."); 250
251 return true; 251 public InventoryItemBase DeleteItem(InventoryItemBase item)
252 } 252 {
253 253 item = m_inventoryService.GetInventoryItem(item.ID);
254 m_log.Warn("[HGStandaloneInvService]: unknown user or session_id, request rejected"); 254 if (m_inventoryService.DeleteItem(item))
255 return false; 255 return item;
256 } 256 else
257 else 257 {
258 { 258 item.ID = UUID.Zero;
259 return true; 259 return item;
260 } 260 }
261 } 261 }
262 262
263 // In truth, this is not called from the outside, for standalones. I'm just making it 263 public InventoryItemBase CopyItem(InventoryItemBase olditem)
264 // a handler already so that this can be reused for the InventoryServer. 264 {
265 public string CreateCapUrl(Guid _userid) 265 m_log.DebugFormat("[HGStandaloneInvService]: Copy item {0} from {1}", olditem.ID, olditem.Owner);
266 { 266 InventoryItemBase Item = m_inventoryService.GetInventoryItem(olditem.ID); // this is the old item id
267 UUID userID = new UUID(_userid); 267 // BIG HACK here
268 UUID random = UUID.Random(); 268 UUID newID = olditem.AssetID;
269 string url = m_thisInventoryUrl + random.ToString() + "/"; 269 if (Item != null)
270 m_log.InfoFormat("[HGStandaloneInvService] Creating Cap URL {0} for user {1}", url, userID.ToString()); 270 {
271 return url; 271 if (olditem.Name != String.Empty)
272 } 272 {
273 273 Item.Name = olditem.Name;
274 274 }
275 /// <summary> 275 Item.ID = newID;
276 /// Return a user's entire inventory 276 Item.Folder = olditem.Folder;
277 /// </summary> 277 Item.Owner = olditem.Owner;
278 /// <param name="rawUserID"></param> 278 // There should be some tests here about the owner, etc but I'm going to ignore that
279 /// <returns>The user's inventory. If an inventory cannot be found then an empty collection is returned.</returns> 279 // because I'm not sure it makes any sense
280 public InventoryCollection GetUserInventory(Guid rawUserID) 280 // Also I should probably close the asset...
281 { 281 m_inventoryService.AddItem(Item);
282 UUID userID = new UUID(rawUserID); 282 return Item;
283 283 }
284 m_log.Info("[HGStandaloneInvService]: Processing request for inventory of " + userID); 284 else
285 285 {
286 // Uncomment me to simulate a slow responding inventory server 286 m_log.Debug("[HGStandaloneInvService]: Failed to find item " + olditem.ID);
287 //Thread.Sleep(16000); 287 olditem.ID = UUID.Zero;
288 288 return olditem;
289 InventoryCollection invCollection = new InventoryCollection(); 289 }
290 290
291 List<InventoryFolderBase> allFolders = ((InventoryServiceBase)m_inventoryService).GetInventorySkeleton(userID); 291 }
292 292
293 if (null == allFolders) 293 /// <summary>
294 { 294 /// Guid to UUID wrapper for same name IInventoryServices method
295 m_log.WarnFormat("[HGStandaloneInvService]: No inventory found for user {0}", rawUserID); 295 /// </summary>
296 296 /// <param name="rawUserID"></param>
297 return invCollection; 297 /// <returns></returns>
298 } 298 public List<InventoryFolderBase> GetInventorySkeleton(Guid rawUserID)
299 299 {
300 List<InventoryItemBase> allItems = new List<InventoryItemBase>(); 300 UUID userID = new UUID(rawUserID);
301 301 return ((InventoryServiceBase)m_inventoryService).GetInventorySkeleton(userID);
302 foreach (InventoryFolderBase folder in allFolders) 302 }
303 { 303
304 List<InventoryItemBase> items = ((InventoryServiceBase)m_inventoryService).RequestFolderItems(folder.ID); 304 public List<InventoryItemBase> GetActiveGestures(Guid rawUserID)
305 305 {
306 if (items != null) 306 UUID userID = new UUID(rawUserID);
307 { 307
308 allItems.InsertRange(0, items); 308 m_log.InfoFormat("[HGStandaloneInvService]: fetching active gestures for user {0}", userID);
309 } 309
310 } 310 return ((InventoryServiceBase)m_inventoryService).GetActiveGestures(userID);
311 311 }
312 invCollection.UserID = userID; 312
313 invCollection.Folders = allFolders; 313 public AssetBase GetAsset(InventoryItemBase item)
314 invCollection.Items = allItems; 314 {
315 315 m_log.Info("[HGStandaloneInvService]: Get asset " + item.AssetID + " for item " + item.ID);
316 // foreach (InventoryFolderBase folder in invCollection.Folders) 316 AssetBase asset = new AssetBase(item.AssetID, "NULL"); // send an asset with no data
317 // { 317 InventoryItemBase item2 = m_inventoryService.GetInventoryItem(item.ID);
318 // m_log.DebugFormat("[GRID AGENT INVENTORY]: Sending back folder {0} {1}", folder.Name, folder.ID); 318 if (item2 == null)
319 // } 319 {
320 // 320 m_log.Debug("[HGStandaloneInvService]: null item");
321 // foreach (InventoryItemBase item in invCollection.Items) 321 return asset;
322 // { 322 }
323 // m_log.DebugFormat("[GRID AGENT INVENTORY]: Sending back item {0} {1}, folder {2}", item.Name, item.ID, item.Folder); 323 if (item2.Owner != item.Owner)
324 // } 324 {
325 325 m_log.DebugFormat("[HGStandaloneInvService]: client with uuid {0} is trying to get an item of owner {1}", item.Owner, item2.Owner);
326 m_log.InfoFormat( 326 return asset;
327 "[HGStandaloneInvService]: Sending back inventory response to user {0} containing {1} folders and {2} items", 327 }
328 invCollection.UserID, invCollection.Folders.Count, invCollection.Items.Count); 328
329 329 // All good, get the asset
330 return invCollection; 330 AssetBase theasset = m_assetProvider.FetchAsset(item.AssetID);
331 } 331 m_log.Debug("[HGStandaloneInvService] Found asset " + ((theasset == null)? "NULL" : "Not Null"));
332 332 if (theasset != null)
333 public InventoryCollection FetchDescendants(InventoryFolderBase fb) 333 {
334 { 334 asset = theasset;
335 m_log.Info("[HGStandaloneInvService]: Processing request for folder " + fb.ID); 335 //m_log.Debug(" >> Sending assetID " + item.AssetID);
336 336 }
337 // Uncomment me to simulate a slow responding inventory server 337 return asset;
338 //Thread.Sleep(16000); 338 }
339 339
340 InventoryCollection invCollection = new InventoryCollection(); 340 public bool PostAsset(AssetBase asset)
341 341 {
342 List<InventoryItemBase> items = ((InventoryServiceBase)m_inventoryService).RequestFolderItems(fb.ID); 342 m_log.Info("[HGStandaloneInvService]: Post asset " + asset.FullID);
343 List<InventoryFolderBase> folders = ((InventoryServiceBase)m_inventoryService).RequestSubFolders(fb.ID); 343 m_assetProvider.CreateAsset(asset);
344 344
345 invCollection.UserID = fb.Owner; 345 return true;
346 invCollection.Folders = folders; 346 }
347 invCollection.Items = items; 347
348 348 /// <summary>
349 m_log.DebugFormat("[HGStandaloneInvService]: Found {0} items and {1} folders", items.Count, folders.Count); 349 /// <see>CapsUpdatedInventoryItemAsset(IClientAPI, UUID, byte[])</see>
350 350 /// </summary>
351 return invCollection; 351 public UUID UpdateInventoryItemAsset(UUID userID, UUID itemID, byte[] data)
352 } 352 {
353 353 m_log.Debug("[HGStandaloneInvService]: UpdateInventoryitemAsset for user " + userID + " item " + itemID);
354 public bool RemoveFolder(InventoryFolderBase folder) 354 InventoryItemBase item = m_inventoryService.GetInventoryItem(itemID);
355 { 355
356 m_log.Debug("[HGStandaloneInvService]: Removefolder: Operation not implemented yet."); 356 if (item != null)
357 return false; 357 {
358 } 358 // We're still not dealing with permissions
359 359 //if ((InventoryType)item.InvType == InventoryType.Notecard)
360 public InventoryItemBase GetInventoryItem(InventoryItemBase item) 360 //{
361 { 361 // if (!Permissions.CanEditNotecard(itemID, UUID.Zero, userID))
362 m_log.Info("[HGStandaloneInvService]: Get item " + item.ID); 362 // {
363 363 // //remoteClient.SendAgentAlertMessage("Insufficient permissions to edit notecard", false);
364 item = ((InventoryServiceBase)m_inventoryService).GetInventoryItem(item.ID); 364 // return UUID.Zero;
365 if (item == null) 365 // }
366 m_log.Debug("[HGStandaloneInvService]: null item"); 366
367 return item; 367 // //remoteClient.SendAgentAlertMessage("Notecard saved", false);
368 } 368 //}
369 369 //else if ((InventoryType)item.InvType == InventoryType.LSL)
370 public InventoryItemBase AddItem(InventoryItemBase item) 370 //{
371 { 371 // if (!Permissions.CanEditScript(itemID, UUID.Zero, remoteClient.AgentId))
372 m_log.DebugFormat("[HGStandaloneInvService]: Add item {0} from {1}", item.ID, item.Owner); 372 // {
373 if (m_inventoryService.AddItem(item)) 373 // //remoteClient.SendAgentAlertMessage("Insufficient permissions to edit script", false);
374 return item; 374 // return UUID.Zero;
375 else 375 // }
376 { 376
377 item.ID = UUID.Zero; 377 // //remoteClient.SendAgentAlertMessage("Script saved", false);
378 return item; 378 //}
379 } 379
380 } 380 AssetBase asset = CreateAsset(item.Name, item.Description, (sbyte)item.AssetType, data);
381 381 PostAsset(asset);
382 public InventoryItemBase UpdateItem(InventoryItemBase item) 382
383 { 383 item.AssetID = asset.FullID;
384 m_log.DebugFormat("[HGStandaloneInvService]: Update item {0} from {1}", item.ID, item.Owner); 384 item.Owner = userID;
385 InventoryItemBase it = m_inventoryService.GetInventoryItem(item.ID); 385 m_inventoryService.UpdateItem(item);
386 item.CurrentPermissions = it.CurrentPermissions; 386
387 item.AssetID = it.AssetID; 387 return (asset.FullID);
388 if (m_inventoryService.UpdateItem(item)) 388 }
389 return item; 389 return UUID.Zero;
390 else 390 }
391 { 391
392 item.ID = UUID.Zero; 392 private AssetBase CreateAsset(string name, string description, sbyte assetType, byte[] data)
393 return item; 393 {
394 } 394 AssetBase asset = new AssetBase();
395 } 395 asset.Name = name;
396 396 asset.Description = description;
397 public InventoryItemBase MoveItem(InventoryItemBase newitem) 397 asset.Type = assetType;
398 { 398 asset.FullID = UUID.Random();
399 m_log.DebugFormat("[HGStandaloneInvService]: Move item {0} from {1}", newitem.ID, newitem.Owner); 399 asset.Data = (data == null) ? new byte[1] : data;
400 InventoryItemBase Item = m_inventoryService.GetInventoryItem(newitem.ID); 400
401 if (Item != null) 401 return asset;
402 { 402 }
403 if (newitem.Name != String.Empty) 403
404 { 404 #region Caps
405 Item.Name = newitem.Name; 405
406 } 406 Dictionary<UUID, Hashtable> invCaps = new Dictionary<UUID, Hashtable>();
407 Item.Folder = newitem.Folder; 407
408 m_inventoryService.UpdateItem(Item); 408 public Hashtable CapHandler(Hashtable request)
409 return Item; 409 {
410 } 410 m_log.Debug("[CONNECTION DEBUGGING]: InvCapHandler Called");
411 else 411
412 { 412 m_log.Debug("---------------------------");
413 m_log.Debug("[HGStandaloneInvService]: Failed to find item " + newitem.ID); 413 m_log.Debug(" >> uri=" + request["uri"]);
414 newitem.ID = UUID.Zero; 414 m_log.Debug(" >> content-type=" + request["content-type"]);
415 return newitem; 415 m_log.Debug(" >> http-method=" + request["http-method"]);
416 } 416 m_log.Debug("---------------------------\n");
417 417
418 } 418 // these are requests if the type
419 419 // http://inventoryserver/InvCap/uuuuuuuu-uuuu-uuuu-uuuu-uuuuuuuuuuuu/kkkkkkkk-kkkk-kkkk-kkkk-kkkkkkkkkkkk/
420 public InventoryItemBase DeleteItem(InventoryItemBase item) 420
421 { 421 Hashtable responsedata = new Hashtable();
422 item = m_inventoryService.GetInventoryItem(item.ID); 422 responsedata["content_type"] = "text/plain";
423 if (m_inventoryService.DeleteItem(item)) 423
424 return item; 424 UUID userID;
425 else 425 string authToken = string.Empty;
426 { 426 string authority = string.Empty;
427 item.ID = UUID.Zero; 427 if (!GetParams(request, out userID, out authority, out authToken))
428 return item; 428 {
429 } 429 m_log.InfoFormat("[HGStandaloneInvService]: Invalid parameters for InvCap message {0}", request["uri"]);
430 } 430 responsedata["int_response_code"] = 404;
431 431 responsedata["str_response_string"] = "Not found";
432 public InventoryItemBase CopyItem(InventoryItemBase olditem) 432
433 { 433 return responsedata;
434 m_log.DebugFormat("[HGStandaloneInvService]: Copy item {0} from {1}", olditem.ID, olditem.Owner); 434 }
435 InventoryItemBase Item = m_inventoryService.GetInventoryItem(olditem.ID); // this is the old item id 435
436 // BIG HACK here 436 // Next, let's parse the verb
437 UUID newID = olditem.AssetID; 437 string method = (string)request["http-method"];
438 if (Item != null) 438 if (method.Equals("GET"))
439 { 439 {
440 if (olditem.Name != String.Empty) 440 DoInvCapPost(request, responsedata, userID, authToken);
441 { 441 return responsedata;
442 Item.Name = olditem.Name; 442 }
443 } 443 //else if (method.Equals("DELETE"))
444 Item.ID = newID; 444 //{
445 Item.Folder = olditem.Folder; 445 // DoAgentDelete(request, responsedata, agentID, action, regionHandle);
446 Item.Owner = olditem.Owner; 446
447 // There should be some tests here about the owner, etc but I'm going to ignore that 447 // return responsedata;
448 // because I'm not sure it makes any sense 448 //}
449 // Also I should probably close the asset... 449 else
450 m_inventoryService.AddItem(Item); 450 {
451 return Item; 451 m_log.InfoFormat("[HGStandaloneInvService]: method {0} not supported in agent message", method);
452 } 452 responsedata["int_response_code"] = 405;
453 else 453 responsedata["str_response_string"] = "Method not allowed";
454 { 454
455 m_log.Debug("[HGStandaloneInvService]: Failed to find item " + olditem.ID); 455 return responsedata;
456 olditem.ID = UUID.Zero; 456 }
457 return olditem; 457
458 } 458 }
459 459
460 } 460 public virtual void DoInvCapPost(Hashtable request, Hashtable responsedata, UUID userID, string authToken)
461 461 {
462 /// <summary> 462
463 /// Guid to UUID wrapper for same name IInventoryServices method 463 // This is the meaning of POST agent
464 /// </summary> 464
465 /// <param name="rawUserID"></param> 465 // Check Auth Token
466 /// <returns></returns> 466 if (!(m_userService is IAuthentication))
467 public List<InventoryFolderBase> GetInventorySkeleton(Guid rawUserID) 467 {
468 { 468 m_log.Debug("[HGStandaloneInvService]: UserService is not IAuthentication. Denying access to inventory.");
469 UUID userID = new UUID(rawUserID); 469 responsedata["int_response_code"] = 501;
470 return ((InventoryServiceBase)m_inventoryService).GetInventorySkeleton(userID); 470 responsedata["str_response_string"] = "Not implemented";
471 } 471 return;
472 472 }
473 public List<InventoryItemBase> GetActiveGestures(Guid rawUserID) 473
474 { 474 bool success = ((IAuthentication)m_userService).VerifyKey(userID, authToken);
475 UUID userID = new UUID(rawUserID); 475
476 476 if (success)
477 m_log.InfoFormat("[HGStandaloneInvService]: fetching active gestures for user {0}", userID); 477 {
478 478
479 return ((InventoryServiceBase)m_inventoryService).GetActiveGestures(userID); 479 m_log.DebugFormat("[HGStandaloneInvService]: User has been authorized. Creating service handlers.");
480 } 480
481 481 // Then establish secret service handlers
482 public AssetBase GetAsset(InventoryItemBase item) 482
483 { 483 Hashtable usercaps = RegisterCaps(userID, authToken);
484 m_log.Info("[HGStandaloneInvService]: Get asset " + item.AssetID + " for item " + item.ID); 484
485 AssetBase asset = new AssetBase(item.AssetID, "NULL"); // send an asset with no data 485 responsedata["int_response_code"] = 200;
486 InventoryItemBase item2 = ((InventoryServiceBase)m_inventoryService).GetInventoryItem(item.ID); 486 //responsedata["str_response_string"] = "OK";
487 if (item2 == null) 487 responsedata["str_response_string"] = SerializeHashtable(usercaps);
488 { 488 }
489 m_log.Debug("[HGStandaloneInvService]: null item"); 489 else
490 return asset; 490 {
491 } 491 m_log.DebugFormat("[HGStandaloneInvService]: User has is unauthorized. Denying service handlers.");
492 if (item2.Owner != item.Owner) 492 responsedata["int_response_code"] = 403;
493 { 493 responsedata["str_response_string"] = "Forbidden";
494 m_log.DebugFormat("[HGStandaloneInvService]: client with uuid {0} is trying to get an item of owner {1}", item.Owner, item2.Owner); 494 }
495 return asset; 495 }
496 } 496
497 497
498 // All good, get the asset 498 /// <summary>
499 AssetBase theasset = m_assetProvider.FetchAsset(item.AssetID); 499 /// Extract the params from a request.
500 m_log.Debug("[HGStandaloneInvService] Found asset " + ((theasset == null)? "NULL" : "Not Null")); 500 /// </summary>
501 if (theasset != null) 501 public static bool GetParams(Hashtable request, out UUID uuid, out string authority, out string authKey)
502 { 502 {
503 asset = theasset; 503 uuid = UUID.Zero;
504 //m_log.Debug(" >> Sending assetID " + item.AssetID); 504 authority = string.Empty;
505 } 505 authKey = string.Empty;
506 return asset; 506
507 } 507 string uri = (string)request["uri"];
508 508 uri = uri.Trim(new char[] { '/' });
509 public bool PostAsset(AssetBase asset) 509 string[] parts = uri.Split('/');
510 { 510 if (parts.Length <= 1)
511 m_log.Info("[HGStandaloneInvService]: Post asset " + asset.FullID); 511 {
512 m_assetProvider.CreateAsset(asset); 512 return false;
513 513 }
514 return true; 514 else
515 } 515 {
516 516 if (!UUID.TryParse(parts[1], out uuid))
517 /// <summary> 517 return false;
518 /// <see>CapsUpdatedInventoryItemAsset(IClientAPI, UUID, byte[])</see> 518
519 /// </summary> 519 if (parts.Length >= 3)
520 public UUID UpdateInventoryItemAsset(UUID userID, UUID itemID, byte[] data) 520 {
521 { 521 authKey = parts[2];
522 m_log.Debug("[HGStandaloneInvService]: UpdateInventoryitemAsset for user " + userID + " item " + itemID); 522 return true;
523 InventoryItemBase item = m_inventoryService.GetInventoryItem(itemID); 523 }
524 524 }
525 if (item != null) 525
526 { 526 Uri authUri;
527 // We're still not dealing with permissions 527 Hashtable headers = (Hashtable)request["headers"];
528 //if ((InventoryType)item.InvType == InventoryType.Notecard) 528
529 //{ 529 // Authorization keys look like this:
530 // if (!Permissions.CanEditNotecard(itemID, UUID.Zero, userID)) 530 // http://orgrid.org:8002/<uuid>
531 // { 531 if (headers.ContainsKey("authorization"))
532 // //remoteClient.SendAgentAlertMessage("Insufficient permissions to edit notecard", false); 532 {
533 // return UUID.Zero; 533 if (Uri.TryCreate((string)headers["authorization"], UriKind.Absolute, out authUri))
534 // } 534 {
535 535 authority = authUri.Authority;
536 // //remoteClient.SendAgentAlertMessage("Notecard saved", false); 536 authKey = authUri.PathAndQuery.Trim('/');
537 //} 537 m_log.DebugFormat("[HGStandaloneInvService]: Got authority {0} and key {1}", authority, authKey);
538 //else if ((InventoryType)item.InvType == InventoryType.LSL) 538 return true;
539 //{ 539 }
540 // if (!Permissions.CanEditScript(itemID, UUID.Zero, remoteClient.AgentId)) 540 else
541 // { 541 m_log.Debug("[HGStandaloneInvService]: Wrong format for Authorization header: " + (string)headers["authorization"]);
542 // //remoteClient.SendAgentAlertMessage("Insufficient permissions to edit script", false); 542 }
543 // return UUID.Zero; 543 else
544 // } 544 m_log.Debug("[HGStandaloneInvService]: Authorization header not found");
545 545
546 // //remoteClient.SendAgentAlertMessage("Script saved", false); 546 return false;
547 //} 547 }
548 548
549 AssetBase asset = CreateAsset(item.Name, item.Description, (sbyte)item.AssetType, data); 549 string SerializeHashtable(Hashtable hash)
550 PostAsset(asset); 550 {
551 551 string result = string.Empty;
552 item.AssetID = asset.FullID; 552 foreach (object key in hash.Keys)
553 item.Owner = userID; 553 {
554 m_inventoryService.UpdateItem(item); 554 result += key.ToString() + "," + hash[key].ToString() + ";";
555 555 }
556 return (asset.FullID); 556 return result;
557 } 557 }
558 return UUID.Zero; 558
559 } 559 Hashtable RegisterCaps(UUID userID, string authToken)
560 560 {
561 private AssetBase CreateAsset(string name, string description, sbyte assetType, byte[] data) 561 lock (invCaps)
562 { 562 {
563 AssetBase asset = new AssetBase(); 563 if (invCaps.ContainsKey(userID))
564 asset.Name = name; 564 {
565 asset.Description = description; 565 // Remove the old ones
566 asset.Type = assetType; 566 DeregisterCaps(httpServer, invCaps[userID]);
567 asset.FullID = UUID.Random(); 567 invCaps.Remove(userID);
568 asset.Data = (data == null) ? new byte[1] : data; 568 }
569 569 }
570 return asset; 570
571 } 571 Caps caps = new Caps(null, httpServer, m_thisHostname, m_thisPort, authToken, userID, false, "Inventory");
572 572 caps.RegisterInventoryServiceHandlers("/" + authToken + "/InventoryCap/");
573 #region Caps 573 caps.ItemUpdatedCall = UpdateInventoryItemAsset;
574 574 Hashtable capsHandlers = caps.CapsHandlers.CapsDetails;
575 Dictionary<UUID, Hashtable> invCaps = new Dictionary<UUID, Hashtable>(); 575
576 576 httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<Guid, InventoryCollection>(
577 public Hashtable CapHandler(Hashtable request) 577 "POST", AddAndGetCapUrl(authToken, "GetInventory", capsHandlers), GetUserInventory, CheckAuthSession));
578 { 578
579 m_log.Debug("[CONNECTION DEBUGGING]: InvCapHandler Called"); 579 httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<InventoryFolderBase, InventoryCollection>(
580 580 "POST", AddAndGetCapUrl(authToken, "FetchDescendants", capsHandlers), FetchDescendants, CheckAuthSession));
581 m_log.Debug("---------------------------"); 581 httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<InventoryFolderBase, bool>(
582 m_log.Debug(" >> uri=" + request["uri"]); 582 "POST", AddAndGetCapUrl(authToken, "NewFolder", capsHandlers), m_inventoryService.AddFolder, CheckAuthSession));
583 m_log.Debug(" >> content-type=" + request["content-type"]); 583 httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<InventoryFolderBase, bool>(
584 m_log.Debug(" >> http-method=" + request["http-method"]); 584 "POST", AddAndGetCapUrl(authToken, "UpdateFolder", capsHandlers), m_inventoryService.UpdateFolder, CheckAuthSession));
585 m_log.Debug("---------------------------\n"); 585 httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<InventoryFolderBase, bool>(
586 586 "POST", AddAndGetCapUrl(authToken, "MoveFolder", capsHandlers), m_inventoryService.MoveFolder, CheckAuthSession));
587 // these are requests if the type 587 httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<InventoryFolderBase, bool>(
588 // http://inventoryserver/InvCap/uuuuuuuu-uuuu-uuuu-uuuu-uuuuuuuuuuuu/kkkkkkkk-kkkk-kkkk-kkkk-kkkkkkkkkkkk/ 588 "POST", AddAndGetCapUrl(authToken, "PurgeFolder", capsHandlers), m_inventoryService.PurgeFolder, CheckAuthSession));
589 589 httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<InventoryFolderBase, bool>(
590 Hashtable responsedata = new Hashtable(); 590 "POST", AddAndGetCapUrl(authToken, "RemoveFolder", capsHandlers), RemoveFolder, CheckAuthSession));
591 responsedata["content_type"] = "text/plain"; 591
592 592 httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<InventoryItemBase, InventoryItemBase>(
593 UUID userID; 593 "POST", AddAndGetCapUrl(authToken, "GetItem", capsHandlers), GetInventoryItem, CheckAuthSession));
594 string authToken = string.Empty; 594 httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<InventoryItemBase, InventoryItemBase>(
595 string authority = string.Empty; 595 "POST", AddAndGetCapUrl(authToken, "NewItem", capsHandlers), AddItem, CheckAuthSession));
596 if (!GetParams(request, out userID, out authority, out authToken)) 596 httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<InventoryItemBase, InventoryItemBase>(
597 { 597 "POST", AddAndGetCapUrl(authToken, "UpdateItem", capsHandlers), UpdateItem, CheckAuthSession));
598 m_log.InfoFormat("[HGStandaloneInvService]: Invalid parameters for InvCap message {0}", request["uri"]); 598 httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<InventoryItemBase, InventoryItemBase>(
599 responsedata["int_response_code"] = 404; 599 "POST", AddAndGetCapUrl(authToken, "MoveItem", capsHandlers), MoveItem, CheckAuthSession));
600 responsedata["str_response_string"] = "Not found"; 600 httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<InventoryItemBase, InventoryItemBase>(
601 601 "POST", AddAndGetCapUrl(authToken, "DeleteItem", capsHandlers), DeleteItem, CheckAuthSession));
602 return responsedata; 602 httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<InventoryItemBase, InventoryItemBase>(
603 } 603 "POST", AddAndGetCapUrl(authToken, "CopyItem", capsHandlers), CopyItem, CheckAuthSession));
604 604
605 // Next, let's parse the verb 605 httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<InventoryItemBase, AssetBase>(
606 string method = (string)request["http-method"]; 606 "POST", AddAndGetCapUrl(authToken, "GetAsset", capsHandlers), GetAsset, CheckAuthSession));
607 if (method.Equals("GET")) 607 httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<AssetBase, bool>(
608 { 608 "POST", AddAndGetCapUrl(authToken, "PostAsset", capsHandlers), PostAsset, CheckAuthSession));
609 DoInvCapPost(request, responsedata, userID, authToken); 609
610 return responsedata; 610 lock (invCaps)
611 } 611 invCaps.Add(userID, capsHandlers);
612 //else if (method.Equals("DELETE")) 612
613 //{ 613 return capsHandlers;
614 // DoAgentDelete(request, responsedata, agentID, action, regionHandle); 614 }
615 615
616 // return responsedata; 616 string AddAndGetCapUrl(string authToken, string capType, Hashtable caps)
617 //} 617 {
618 else 618 string capUrl = "/" + authToken + "/" + capType + "/";
619 { 619
620 m_log.InfoFormat("[HGStandaloneInvService]: method {0} not supported in agent message", method); 620 m_log.Debug("[HGStandaloneInvService] Adding inventory cap " + capUrl);
621 responsedata["int_response_code"] = 405; 621 caps.Add(capType, capUrl);
622 responsedata["str_response_string"] = "Method not allowed"; 622 return capUrl;
623 623 }
624 return responsedata; 624
625 } 625 void DeregisterCaps(IHttpServer httpServer, Hashtable caps)
626 626 {
627 } 627 foreach (string capUrl in caps.Values)
628 628 {
629 public virtual void DoInvCapPost(Hashtable request, Hashtable responsedata, UUID userID, string authToken) 629 m_log.Debug("[HGStandaloneInvService] Removing inventory cap " + capUrl);
630 { 630 httpServer.RemoveStreamHandler("POST", capUrl);
631 631 }
632 // This is the meaning of POST agent 632 }
633 633
634 // Check Auth Token 634 #endregion Caps
635 if (!(m_userService is IAuthentication)) 635 }
636 { 636}
637 m_log.Debug("[HGStandaloneInvService]: UserService is not IAuthentication. Denying access to inventory.");
638 responsedata["int_response_code"] = 501;
639 responsedata["str_response_string"] = "Not implemented";
640 return;
641 }
642
643 bool success = ((IAuthentication)m_userService).VerifyKey(userID, authToken);
644
645 if (success)
646 {
647
648 m_log.DebugFormat("[HGStandaloneInvService]: User has been authorized. Creating service handlers.");
649
650 // Then establish secret service handlers
651
652 Hashtable usercaps = RegisterCaps(userID, authToken);
653
654 responsedata["int_response_code"] = 200;
655 //responsedata["str_response_string"] = "OK";
656 responsedata["str_response_string"] = SerializeHashtable(usercaps);
657 }
658 else
659 {
660 m_log.DebugFormat("[HGStandaloneInvService]: User has is unauthorized. Denying service handlers.");
661 responsedata["int_response_code"] = 403;
662 responsedata["str_response_string"] = "Forbidden";
663 }
664 }
665
666
667 /// <summary>
668 /// Extract the params from a request.
669 /// </summary>
670 public static bool GetParams(Hashtable request, out UUID uuid, out string authority, out string authKey)
671 {
672 uuid = UUID.Zero;
673 authority = string.Empty;
674 authKey = string.Empty;
675
676 string uri = (string)request["uri"];
677 uri = uri.Trim(new char[] { '/' });
678 string[] parts = uri.Split('/');
679 if (parts.Length <= 1)
680 {
681 return false;
682 }
683 else
684 {
685 if (!UUID.TryParse(parts[1], out uuid))
686 return false;
687
688 if (parts.Length >= 3)
689 {
690 authKey = parts[2];
691 return true;
692 }
693 }
694
695 Uri authUri;
696 Hashtable headers = (Hashtable)request["headers"];
697
698 // Authorization keys look like this:
699 // http://orgrid.org:8002/<uuid>
700 if (headers.ContainsKey("authorization"))
701 {
702 if (Uri.TryCreate((string)headers["authorization"], UriKind.Absolute, out authUri))
703 {
704 authority = authUri.Authority;
705 authKey = authUri.PathAndQuery.Trim('/');
706 m_log.DebugFormat("[HGStandaloneInvService]: Got authority {0} and key {1}", authority, authKey);
707 return true;
708 }
709 else
710 m_log.Debug("[HGStandaloneInvService]: Wrong format for Authorization header: " + (string)headers["authorization"]);
711 }
712 else
713 m_log.Debug("[HGStandaloneInvService]: Authorization header not found");
714
715 return false;
716 }
717
718 string SerializeHashtable(Hashtable hash)
719 {
720 string result = string.Empty;
721 foreach (object key in hash.Keys)
722 {
723 result += key.ToString() + "," + hash[key].ToString() + ";";
724 }
725 return result;
726 }
727
728 Hashtable RegisterCaps(UUID userID, string authToken)
729 {
730 IHttpServer httpServer = m_scene.CommsManager.HttpServer;
731
732 lock (invCaps)
733 {
734 if (invCaps.ContainsKey(userID))
735 {
736 // Remove the old ones
737 DeregisterCaps(httpServer, invCaps[userID]);
738 invCaps.Remove(userID);
739 }
740 }
741
742 Caps caps = new Caps(null, httpServer, m_thisHostname, m_thisPort, authToken, userID, false, "Inventory");
743 caps.RegisterInventoryServiceHandlers("/" + authToken + "/InventoryCap/");
744 caps.ItemUpdatedCall = UpdateInventoryItemAsset;
745 Hashtable capsHandlers = caps.CapsHandlers.CapsDetails;
746
747 httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<Guid, InventoryCollection>(
748 "POST", AddAndGetCapUrl(authToken, "GetInventory", capsHandlers), GetUserInventory, CheckAuthSession));
749
750 httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<InventoryFolderBase, InventoryCollection>(
751 "POST", AddAndGetCapUrl(authToken, "FetchDescendants", capsHandlers), FetchDescendants, CheckAuthSession));
752 httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<InventoryFolderBase, bool>(
753 "POST", AddAndGetCapUrl(authToken, "NewFolder", capsHandlers), m_inventoryService.AddFolder, CheckAuthSession));
754 httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<InventoryFolderBase, bool>(
755 "POST", AddAndGetCapUrl(authToken, "UpdateFolder", capsHandlers), m_inventoryService.UpdateFolder, CheckAuthSession));
756 httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<InventoryFolderBase, bool>(
757 "POST", AddAndGetCapUrl(authToken, "MoveFolder", capsHandlers), m_inventoryService.MoveFolder, CheckAuthSession));
758 httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<InventoryFolderBase, bool>(
759 "POST", AddAndGetCapUrl(authToken, "PurgeFolder", capsHandlers), m_inventoryService.PurgeFolder, CheckAuthSession));
760 httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<InventoryFolderBase, bool>(
761 "POST", AddAndGetCapUrl(authToken, "RemoveFolder", capsHandlers), RemoveFolder, CheckAuthSession));
762
763 httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<InventoryItemBase, InventoryItemBase>(
764 "POST", AddAndGetCapUrl(authToken, "GetItem", capsHandlers), GetInventoryItem, CheckAuthSession));
765 httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<InventoryItemBase, InventoryItemBase>(
766 "POST", AddAndGetCapUrl(authToken, "NewItem", capsHandlers), AddItem, CheckAuthSession));
767 httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<InventoryItemBase, InventoryItemBase>(
768 "POST", AddAndGetCapUrl(authToken, "UpdateItem", capsHandlers), UpdateItem, CheckAuthSession));
769 httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<InventoryItemBase, InventoryItemBase>(
770 "POST", AddAndGetCapUrl(authToken, "MoveItem", capsHandlers), MoveItem, CheckAuthSession));
771 httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<InventoryItemBase, InventoryItemBase>(
772 "POST", AddAndGetCapUrl(authToken, "DeleteItem", capsHandlers), DeleteItem, CheckAuthSession));
773 httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<InventoryItemBase, InventoryItemBase>(
774 "POST", AddAndGetCapUrl(authToken, "CopyItem", capsHandlers), CopyItem, CheckAuthSession));
775
776 httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<InventoryItemBase, AssetBase>(
777 "POST", AddAndGetCapUrl(authToken, "GetAsset", capsHandlers), GetAsset, CheckAuthSession));
778 httpServer.AddStreamHandler(new RestDeserialiseSecureHandler<AssetBase, bool>(
779 "POST", AddAndGetCapUrl(authToken, "PostAsset", capsHandlers), PostAsset, CheckAuthSession));
780
781 lock (invCaps)
782 invCaps.Add(userID, capsHandlers);
783
784 return capsHandlers;
785 }
786
787 string AddAndGetCapUrl(string authToken, string capType, Hashtable caps)
788 {
789 string capUrl = "/" + authToken + "/" + capType + "/";
790
791 m_log.Debug("[HGStandaloneInvService] Adding inventory cap " + capUrl);
792 caps.Add(capType, capUrl);
793 return capUrl;
794 }
795
796 void DeregisterCaps(IHttpServer httpServer, Hashtable caps)
797 {
798 foreach (string capUrl in caps.Values)
799 {
800 m_log.Debug("[HGStandaloneInvService] Removing inventory cap " + capUrl);
801 httpServer.RemoveStreamHandler("POST", capUrl);
802 }
803 }
804
805 #endregion Caps
806 }
807}
diff --git a/OpenSim/Framework/Communications/HGLoginAuthService.cs b/OpenSim/Framework/Communications/Services/HGLoginAuthService.cs
index 49977b7..37c8846 100644
--- a/OpenSim/Framework/Communications/HGLoginAuthService.cs
+++ b/OpenSim/Framework/Communications/Services/HGLoginAuthService.cs
@@ -42,7 +42,7 @@ using log4net;
42using Nini.Config; 42using Nini.Config;
43using Nwc.XmlRpc; 43using Nwc.XmlRpc;
44 44
45namespace OpenSim.Framework.Communications 45namespace OpenSim.Framework.Communications.Services
46{ 46{
47 public class HGLoginAuthService : LoginService 47 public class HGLoginAuthService : LoginService
48 { 48 {
diff --git a/OpenSim/Grid/UserServer.Modules/UserLoginAuthService.cs b/OpenSim/Grid/UserServer.Modules/UserLoginAuthService.cs
index 774b4e1..a910136 100644
--- a/OpenSim/Grid/UserServer.Modules/UserLoginAuthService.cs
+++ b/OpenSim/Grid/UserServer.Modules/UserLoginAuthService.cs
@@ -36,6 +36,7 @@ using OpenMetaverse;
36using OpenSim.Data; 36using OpenSim.Data;
37using OpenSim.Framework; 37using OpenSim.Framework;
38using OpenSim.Framework.Communications; 38using OpenSim.Framework.Communications;
39using OpenSim.Framework.Communications.Services;
39using OpenSim.Framework.Communications.Cache; 40using OpenSim.Framework.Communications.Cache;
40using OpenSim.Framework.Communications.Capabilities; 41using OpenSim.Framework.Communications.Capabilities;
41using OpenSim.Framework.Servers; 42using OpenSim.Framework.Servers;
diff --git a/OpenSim/Region/CoreModules/Hypergrid/HGStandaloneInventoryModule.cs b/OpenSim/Region/CoreModules/Hypergrid/HGStandaloneInventoryModule.cs
new file mode 100644
index 0000000..525dda7
--- /dev/null
+++ b/OpenSim/Region/CoreModules/Hypergrid/HGStandaloneInventoryModule.cs
@@ -0,0 +1,165 @@
1/**
2 * Copyright (c) 2008, Contributors. All rights reserved.
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * * Neither the name of the Organizations nor the names of Individual
14 * Contributors may be used to endorse or promote products derived from
15 * this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
20 * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
22 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
25 * OF THE POSSIBILITY OF SUCH DAMAGE.
26 *
27 */
28
29using System;
30using System.Collections;
31using System.Collections.Generic;
32using System.Reflection;
33using log4net;
34using Nini.Config;
35using OpenMetaverse;
36using OpenSim.Data;
37using OpenSim.Framework;
38using OpenSim.Framework.Communications;
39using OpenSim.Framework.Communications.Cache;
40using OpenSim.Framework.Communications.Services;
41using Caps = OpenSim.Framework.Communications.Capabilities.Caps;
42using LLSDHelpers = OpenSim.Framework.Communications.Capabilities.LLSDHelpers;
43using OpenSim.Framework.Servers;
44using OpenSim.Framework.Servers.Interfaces;
45using OpenSim.Region.Framework.Interfaces;
46using OpenSim.Region.Framework.Scenes;
47using OpenSim.Region.CoreModules.Communications.REST;
48
49using OpenMetaverse.StructuredData;
50
51namespace OpenSim.Region.CoreModules.Hypergrid
52{
53 public class HGStandaloneInventoryModule : IRegionModule
54 {
55 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
56 private static bool initialized = false;
57 private static bool enabled = false;
58
59 private bool m_doLookup = false;
60 Scene m_scene;
61 HGInventoryService m_inventoryService;
62 InventoryServiceBase m_inventoryBase;
63
64 public bool DoLookup
65 {
66 get { return m_doLookup; }
67 set { m_doLookup = value; }
68 }
69
70 #region IRegionModule interface
71
72 public void Initialise(Scene scene, IConfigSource config)
73 {
74 if (!initialized)
75 {
76 initialized = true;
77 m_scene = scene;
78
79 // This module is only on for standalones
80 enabled = !config.Configs["Startup"].GetBoolean("gridmode", true) && config.Configs["Startup"].GetBoolean("hypergrid", false);
81 }
82 }
83
84 public void PostInitialise()
85 {
86 if (enabled)
87 {
88 m_log.Info("[HGStandaloneInvModule]: Starting...");
89 //m_inventoryService = new InventoryService(m_scene);
90 m_inventoryBase = (InventoryServiceBase)m_scene.CommsManager.SecureInventoryService;
91
92 m_inventoryService = new HGInventoryService(m_inventoryBase,
93 ((AssetServerBase)m_scene.CommsManager.AssetCache.AssetServer).AssetProviderPlugin,
94 (UserManagerBase)m_scene.CommsManager.UserService, m_scene.CommsManager.HttpServer,
95 m_scene.CommsManager.NetworkServersInfo.InventoryURL);
96
97 AddHttpHandlers(m_scene.CommsManager.HttpServer);
98 m_inventoryService.AddHttpHandlers();
99 }
100 }
101
102 public void Close()
103 {
104 }
105
106 public string Name
107 {
108 get { return "HGStandaloneInventoryModule"; }
109 }
110
111 public bool IsSharedModule
112 {
113 get { return true; }
114 }
115
116 #endregion
117
118 public virtual void AddHttpHandlers(IHttpServer httpServer)
119 {
120
121 httpServer.AddStreamHandler(
122 new RestDeserialiseSecureHandler<Guid, InventoryCollection>(
123 "POST", "/GetInventory/", m_inventoryService.GetUserInventory, CheckAuthSession));
124
125 httpServer.AddStreamHandler(
126 new RestDeserialiseSecureHandler<InventoryFolderBase, bool>(
127 "POST", "/NewFolder/", m_inventoryBase.AddFolder, CheckAuthSession));
128
129 httpServer.AddStreamHandler(
130 new RestDeserialiseSecureHandler<InventoryFolderBase, bool>(
131 "POST", "/UpdateFolder/", m_inventoryBase.UpdateFolder, CheckAuthSession));
132
133 httpServer.AddStreamHandler(
134 new RestDeserialiseSecureHandler<InventoryFolderBase, bool>(
135 "POST", "/MoveFolder/", m_inventoryBase.MoveFolder, CheckAuthSession));
136
137 httpServer.AddStreamHandler(
138 new RestDeserialiseSecureHandler<InventoryFolderBase, bool>(
139 "POST", "/PurgeFolder/", m_inventoryBase.PurgeFolder, CheckAuthSession));
140
141 httpServer.AddStreamHandler(
142 new RestDeserialiseSecureHandler<InventoryItemBase, bool>(
143 "POST", "/NewItem/", m_inventoryBase.AddItem, CheckAuthSession));
144
145 httpServer.AddStreamHandler(
146 new RestDeserialiseSecureHandler<InventoryItemBase, bool>(
147 "POST", "/DeleteItem/", m_inventoryBase.DeleteItem, CheckAuthSession));
148
149 }
150
151 /// <summary>
152 /// Check that the source of an inventory request for a particular agent is a current session belonging to
153 /// that agent.
154 /// </summary>
155 /// <param name="session_id"></param>
156 /// <param name="avatar_id"></param>
157 /// <returns></returns>
158 public bool CheckAuthSession(string session_id, string avatar_id)
159 {
160 return true;
161 }
162
163 }
164
165}
diff --git a/OpenSim/Region/CoreModules/Hypergrid/HGStandaloneLoginModule.cs b/OpenSim/Region/CoreModules/Hypergrid/HGStandaloneLoginModule.cs
index 3f4d875..9e134be 100644
--- a/OpenSim/Region/CoreModules/Hypergrid/HGStandaloneLoginModule.cs
+++ b/OpenSim/Region/CoreModules/Hypergrid/HGStandaloneLoginModule.cs
@@ -36,6 +36,7 @@ using Nini.Config;
36using OpenMetaverse; 36using OpenMetaverse;
37using OpenSim.Framework; 37using OpenSim.Framework;
38using OpenSim.Framework.Communications; 38using OpenSim.Framework.Communications;
39using OpenSim.Framework.Communications.Services;
39using OpenSim.Framework.Communications.Cache; 40using OpenSim.Framework.Communications.Cache;
40using OpenSim.Framework.Communications.Capabilities; 41using OpenSim.Framework.Communications.Capabilities;
41using OpenSim.Framework.Servers.Interfaces; 42using OpenSim.Framework.Servers.Interfaces;