aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Common/OpenGrid.Framework.UserManager/UserManagerBase.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Common/OpenGrid.Framework.UserManager/UserManagerBase.cs')
-rw-r--r--Common/OpenGrid.Framework.UserManager/UserManagerBase.cs721
1 files changed, 721 insertions, 0 deletions
diff --git a/Common/OpenGrid.Framework.UserManager/UserManagerBase.cs b/Common/OpenGrid.Framework.UserManager/UserManagerBase.cs
new file mode 100644
index 0000000..d6d50c1
--- /dev/null
+++ b/Common/OpenGrid.Framework.UserManager/UserManagerBase.cs
@@ -0,0 +1,721 @@
1/*
2* Copyright (c) Contributors, http://www.openmetaverse.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 OpenSim Project nor the
13* names of its contributors may be used to endorse or promote products
14* derived from this software without specific prior written permission.
15*
16* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS AND ANY
17* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*
27*/
28using System;
29using System.Collections;
30using System.Collections.Generic;
31using System.Text;
32using OpenGrid.Framework.Data;
33using libsecondlife;
34using System.Reflection;
35
36using System.Xml;
37using Nwc.XmlRpc;
38using OpenSim.Framework.Sims;
39using OpenSim.Framework.Inventory;
40using OpenSim.Framework.Utilities;
41
42using System.Security.Cryptography;
43
44namespace OpenGrid.Framework.UserManagement
45{
46 public class UserManagerBase
47 {
48 public OpenSim.Framework.Interfaces.UserConfig _config;
49 Dictionary<string, IUserData> _plugins = new Dictionary<string, IUserData>();
50
51 /// <summary>
52 /// Adds a new user server plugin - user servers will be requested in the order they were loaded.
53 /// </summary>
54 /// <param name="FileName">The filename to the user server plugin DLL</param>
55 public void AddPlugin(string FileName)
56 {
57 OpenSim.Framework.Console.MainConsole.Instance.Verbose( "Userstorage: Attempting to load " + FileName);
58 Assembly pluginAssembly = Assembly.LoadFrom(FileName);
59
60 OpenSim.Framework.Console.MainConsole.Instance.Verbose( "Userstorage: Found " + pluginAssembly.GetTypes().Length + " interfaces.");
61 foreach (Type pluginType in pluginAssembly.GetTypes())
62 {
63 if (!pluginType.IsAbstract)
64 {
65 Type typeInterface = pluginType.GetInterface("IUserData", true);
66
67 if (typeInterface != null)
68 {
69 IUserData plug = (IUserData)Activator.CreateInstance(pluginAssembly.GetType(pluginType.ToString()));
70 plug.Initialise();
71 this._plugins.Add(plug.getName(), plug);
72 OpenSim.Framework.Console.MainConsole.Instance.Verbose( "Userstorage: Added IUserData Interface");
73 }
74
75 typeInterface = null;
76 }
77 }
78
79 pluginAssembly = null;
80 }
81
82 /// <summary>
83 ///
84 /// </summary>
85 /// <param name="user"></param>
86 public void AddUserProfile(string firstName, string lastName, string pass, uint regX, uint regY)
87 {
88 UserProfileData user = new UserProfileData();
89 user.homeLocation = new LLVector3(128, 128, 100);
90 user.UUID = LLUUID.Random();
91 user.username = firstName;
92 user.surname = lastName;
93 user.passwordHash = pass;
94 user.passwordSalt = "";
95 user.created = Util.UnixTimeSinceEpoch();
96 user.homeLookAt = new LLVector3(100, 100, 100);
97 user.homeRegion = Util.UIntsToLong((regX * 256), (regY * 256));
98
99 foreach (KeyValuePair<string, IUserData> plugin in _plugins)
100 {
101 try
102 {
103 plugin.Value.addNewUserProfile(user);
104
105 }
106 catch (Exception e)
107 {
108 OpenSim.Framework.Console.MainConsole.Instance.Verbose( "Unable to find user via " + plugin.Key + "(" + e.ToString() + ")");
109 }
110 }
111 }
112
113 /// <summary>
114 /// Loads a user profile from a database by UUID
115 /// </summary>
116 /// <param name="uuid">The target UUID</param>
117 /// <returns>A user profile</returns>
118 public UserProfileData getUserProfile(LLUUID uuid)
119 {
120 foreach (KeyValuePair<string, IUserData> plugin in _plugins)
121 {
122 try
123 {
124 UserProfileData profile = plugin.Value.getUserByUUID(uuid);
125 profile.currentAgent = getUserAgent(profile.UUID);
126 return profile;
127 }
128 catch (Exception e)
129 {
130 OpenSim.Framework.Console.MainConsole.Instance.Verbose( "Unable to find user via " + plugin.Key + "(" + e.ToString() + ")");
131 }
132 }
133
134 return null;
135 }
136
137
138 /// <summary>
139 /// Loads a user profile by name
140 /// </summary>
141 /// <param name="name">The target name</param>
142 /// <returns>A user profile</returns>
143 public UserProfileData getUserProfile(string name)
144 {
145 foreach (KeyValuePair<string, IUserData> plugin in _plugins)
146 {
147 try
148 {
149 UserProfileData profile = plugin.Value.getUserByName(name);
150 profile.currentAgent = getUserAgent(profile.UUID);
151 return profile;
152 }
153 catch (Exception e)
154 {
155 OpenSim.Framework.Console.MainConsole.Instance.Verbose( "Unable to find user via " + plugin.Key + "(" + e.ToString() + ")");
156 }
157 }
158
159 return null;
160 }
161
162 /// <summary>
163 /// Loads a user profile by name
164 /// </summary>
165 /// <param name="fname">First name</param>
166 /// <param name="lname">Last name</param>
167 /// <returns>A user profile</returns>
168 public UserProfileData getUserProfile(string fname, string lname)
169 {
170 foreach (KeyValuePair<string, IUserData> plugin in _plugins)
171 {
172 try
173 {
174 UserProfileData profile = plugin.Value.getUserByName(fname,lname);
175 try
176 {
177 profile.currentAgent = getUserAgent(profile.UUID);
178 }
179 catch (Exception e)
180 {
181 // Ignore
182 }
183 return profile;
184 }
185 catch (Exception e)
186 {
187 OpenSim.Framework.Console.MainConsole.Instance.Verbose( "Unable to find user via " + plugin.Key + "(" + e.ToString() + ")");
188 }
189 }
190
191 return null;
192 }
193
194 /// <summary>
195 /// Loads a user agent by uuid (not called directly)
196 /// </summary>
197 /// <param name="uuid">The agents UUID</param>
198 /// <returns>Agent profiles</returns>
199 public UserAgentData getUserAgent(LLUUID uuid)
200 {
201 foreach (KeyValuePair<string, IUserData> plugin in _plugins)
202 {
203 try
204 {
205 return plugin.Value.getAgentByUUID(uuid);
206 }
207 catch (Exception e)
208 {
209 OpenSim.Framework.Console.MainConsole.Instance.Verbose( "Unable to find user via " + plugin.Key + "(" + e.ToString() + ")");
210 }
211 }
212
213 return null;
214 }
215
216 /// <summary>
217 /// Loads a user agent by name (not called directly)
218 /// </summary>
219 /// <param name="name">The agents name</param>
220 /// <returns>A user agent</returns>
221 public UserAgentData getUserAgent(string name)
222 {
223 foreach (KeyValuePair<string, IUserData> plugin in _plugins)
224 {
225 try
226 {
227 return plugin.Value.getAgentByName(name);
228 }
229 catch (Exception e)
230 {
231 OpenSim.Framework.Console.MainConsole.Instance.Verbose( "Unable to find user via " + plugin.Key + "(" + e.ToString() + ")");
232 }
233 }
234
235 return null;
236 }
237
238 /// <summary>
239 /// Loads a user agent by name (not called directly)
240 /// </summary>
241 /// <param name="fname">The agents firstname</param>
242 /// <param name="lname">The agents lastname</param>
243 /// <returns>A user agent</returns>
244 public UserAgentData getUserAgent(string fname, string lname)
245 {
246 foreach (KeyValuePair<string, IUserData> plugin in _plugins)
247 {
248 try
249 {
250 return plugin.Value.getAgentByName(fname,lname);
251 }
252 catch (Exception e)
253 {
254 OpenSim.Framework.Console.MainConsole.Instance.Verbose( "Unable to find user via " + plugin.Key + "(" + e.ToString() + ")");
255 }
256 }
257
258 return null;
259 }
260
261 /// <summary>
262 /// Creates a error response caused by invalid XML
263 /// </summary>
264 /// <returns>An XMLRPC response</returns>
265 private static XmlRpcResponse CreateErrorConnectingToGridResponse()
266 {
267 XmlRpcResponse response = new XmlRpcResponse();
268 Hashtable ErrorRespData = new Hashtable();
269 ErrorRespData["reason"] = "key";
270 ErrorRespData["message"] = "Error connecting to grid. Could not percieve credentials from login XML.";
271 ErrorRespData["login"] = "false";
272 response.Value = ErrorRespData;
273 return response;
274 }
275
276 /// <summary>
277 /// Creates an error response caused by bad login credentials
278 /// </summary>
279 /// <returns>An XMLRPC response</returns>
280 private static XmlRpcResponse CreateLoginErrorResponse()
281 {
282 XmlRpcResponse response = new XmlRpcResponse();
283 Hashtable ErrorRespData = new Hashtable();
284 ErrorRespData["reason"] = "key";
285 ErrorRespData["message"] = "Could not authenticate your avatar. Please check your username and password, and check the grid if problems persist.";
286 ErrorRespData["login"] = "false";
287 response.Value = ErrorRespData;
288 return response;
289 }
290
291 /// <summary>
292 /// Creates an error response caused by being logged in already
293 /// </summary>
294 /// <returns>An XMLRPC Response</returns>
295 private static XmlRpcResponse CreateAlreadyLoggedInResponse()
296 {
297 XmlRpcResponse response = new XmlRpcResponse();
298 Hashtable PresenceErrorRespData = new Hashtable();
299 PresenceErrorRespData["reason"] = "presence";
300 PresenceErrorRespData["message"] = "You appear to be already logged in, if this is not the case please wait for your session to timeout, if this takes longer than a few minutes please contact the grid owner";
301 PresenceErrorRespData["login"] = "false";
302 response.Value = PresenceErrorRespData;
303 return response;
304 }
305
306 /// <summary>
307 /// Creates an error response caused by target region being down
308 /// </summary>
309 /// <returns>An XMLRPC Response</returns>
310 private static XmlRpcResponse CreateDeadRegionResponse()
311 {
312 XmlRpcResponse response = new XmlRpcResponse();
313 Hashtable PresenceErrorRespData = new Hashtable();
314 PresenceErrorRespData["reason"] = "key";
315 PresenceErrorRespData["message"] = "The region you are attempting to log into is not responding. Please select another region and try again.";
316 PresenceErrorRespData["login"] = "false";
317 response.Value = PresenceErrorRespData;
318 return response;
319 }
320
321 /// <summary>
322 /// Customises the login response and fills in missing values.
323 /// </summary>
324 /// <param name="response">The existing response</param>
325 /// <param name="theUser">The user profile</param>
326 public virtual void CustomiseResponse(ref Hashtable response, ref UserProfileData theUser)
327 {
328
329 }
330
331 /// <summary>
332 /// Checks a user against it's password hash
333 /// </summary>
334 /// <param name="profile">The users profile</param>
335 /// <param name="password">The supplied password</param>
336 /// <returns>Authenticated?</returns>
337 public bool AuthenticateUser(ref UserProfileData profile, string password)
338 {
339 OpenSim.Framework.Console.MainConsole.Instance.Verbose(
340 "Authenticating " + profile.username + " " + profile.surname);
341
342 password = password.Remove(0, 3); //remove $1$
343
344 string s = Util.Md5Hash(password + ":" + profile.passwordSalt);
345
346 return profile.passwordHash.Equals(s.ToString(), StringComparison.InvariantCultureIgnoreCase);
347 }
348
349 /// <summary>
350 /// Creates and initialises a new user agent - make sure to use CommitAgent when done to submit to the DB
351 /// </summary>
352 /// <param name="profile">The users profile</param>
353 /// <param name="request">The users loginrequest</param>
354 public void CreateAgent(ref UserProfileData profile, XmlRpcRequest request)
355 {
356 Hashtable requestData = (Hashtable)request.Params[0];
357
358 UserAgentData agent = new UserAgentData();
359
360 // User connection
361 agent.agentIP = "";
362 agent.agentOnline = true;
363 agent.agentPort = 0;
364
365 // Generate sessions
366 RNGCryptoServiceProvider rand = new RNGCryptoServiceProvider();
367 byte[] randDataS = new byte[16];
368 byte[] randDataSS = new byte[16];
369 rand.GetBytes(randDataS);
370 rand.GetBytes(randDataSS);
371
372 agent.secureSessionID = new LLUUID(randDataSS, 0);
373 agent.sessionID = new LLUUID(randDataS, 0);
374
375 // Profile UUID
376 agent.UUID = profile.UUID;
377
378 // Current position (from Home)
379 agent.currentHandle = profile.homeRegion;
380 agent.currentPos = profile.homeLocation;
381
382 // If user specified additional start, use that
383 if (requestData.ContainsKey("start"))
384 {
385 string startLoc = ((string)requestData["start"]).Trim();
386 if (!(startLoc == "last" || startLoc == "home"))
387 {
388 // Format: uri:Ahern&162&213&34
389 try
390 {
391 string[] parts = startLoc.Remove(0, 4).Split('&');
392 string region = parts[0];
393
394 ////////////////////////////////////////////////////
395 //SimProfile SimInfo = new SimProfile();
396 //SimInfo = SimInfo.LoadFromGrid(theUser.currentAgent.currentHandle, _config.GridServerURL, _config.GridSendKey, _config.GridRecvKey);
397 }
398 catch (Exception e)
399 {
400
401 }
402 }
403 }
404
405 // What time did the user login?
406 agent.loginTime = Util.UnixTimeSinceEpoch();
407 agent.logoutTime = 0;
408
409 // Current location
410 agent.regionID = new LLUUID(); // Fill in later
411 agent.currentRegion = new LLUUID(); // Fill in later
412
413 profile.currentAgent = agent;
414 }
415
416 /// <summary>
417 /// Saves a target agent to the database
418 /// </summary>
419 /// <param name="profile">The users profile</param>
420 /// <returns>Successful?</returns>
421 public bool CommitAgent(ref UserProfileData profile)
422 {
423 // Saves the agent to database
424 return true;
425 }
426
427 /// <summary>
428 /// Main user login function
429 /// </summary>
430 /// <param name="request">The XMLRPC request</param>
431 /// <returns>The response to send</returns>
432 public XmlRpcResponse XmlRpcLoginMethod(XmlRpcRequest request)
433 {
434 XmlRpcResponse response = new XmlRpcResponse();
435 Hashtable requestData = (Hashtable)request.Params[0];
436
437 bool GoodXML = (requestData.Contains("first") && requestData.Contains("last") && requestData.Contains("passwd"));
438 bool GoodLogin = false;
439 string firstname = "";
440 string lastname = "";
441 string passwd = "";
442
443 UserProfileData TheUser;
444
445 if (GoodXML)
446 {
447 firstname = (string)requestData["first"];
448 lastname = (string)requestData["last"];
449 passwd = (string)requestData["passwd"];
450
451 TheUser = getUserProfile(firstname, lastname);
452 if (TheUser == null)
453 return CreateLoginErrorResponse();
454
455 GoodLogin = AuthenticateUser(ref TheUser, passwd);
456 }
457 else
458 {
459 return CreateErrorConnectingToGridResponse();
460 }
461
462 if (!GoodLogin)
463 {
464 return CreateLoginErrorResponse();
465 }
466 else
467 {
468 // If we already have a session...
469 if (TheUser.currentAgent != null && TheUser.currentAgent.agentOnline)
470 {
471 // Reject the login
472 return CreateAlreadyLoggedInResponse();
473 }
474 // Otherwise...
475 // Create a new agent session
476 CreateAgent(ref TheUser, request);
477
478 try
479 {
480 Hashtable responseData = new Hashtable();
481
482 LLUUID AgentID = TheUser.UUID;
483
484 // Global Texture Section
485 Hashtable GlobalT = new Hashtable();
486 GlobalT["sun_texture_id"] = "cce0f112-878f-4586-a2e2-a8f104bba271";
487 GlobalT["cloud_texture_id"] = "fc4b9f0b-d008-45c6-96a4-01dd947ac621";
488 GlobalT["moon_texture_id"] = "fc4b9f0b-d008-45c6-96a4-01dd947ac621";
489 ArrayList GlobalTextures = new ArrayList();
490 GlobalTextures.Add(GlobalT);
491
492 // Login Flags Section
493 Hashtable LoginFlagsHash = new Hashtable();
494 LoginFlagsHash["daylight_savings"] = "N";
495 LoginFlagsHash["stipend_since_login"] = "N";
496 LoginFlagsHash["gendered"] = "Y"; // Needs to be combined with below...
497 LoginFlagsHash["ever_logged_in"] = "Y"; // Should allow male/female av selection
498 ArrayList LoginFlags = new ArrayList();
499 LoginFlags.Add(LoginFlagsHash);
500
501 // UI Customisation Section
502 Hashtable uiconfig = new Hashtable();
503 uiconfig["allow_first_life"] = "Y";
504 ArrayList ui_config = new ArrayList();
505 ui_config.Add(uiconfig);
506
507 // Classified Categories Section
508 Hashtable ClassifiedCategoriesHash = new Hashtable();
509 ClassifiedCategoriesHash["category_name"] = "Generic";
510 ClassifiedCategoriesHash["category_id"] = (Int32)1;
511 ArrayList ClassifiedCategories = new ArrayList();
512 ClassifiedCategories.Add(ClassifiedCategoriesHash);
513
514 // Inventory Library Section
515 ArrayList AgentInventoryArray = new ArrayList();
516 Hashtable TempHash;
517
518 AgentInventory Library = new AgentInventory();
519 Library.CreateRootFolder(AgentID, true);
520
521 foreach (InventoryFolder InvFolder in Library.InventoryFolders.Values)
522 {
523 TempHash = new Hashtable();
524 TempHash["name"] = InvFolder.FolderName;
525 TempHash["parent_id"] = InvFolder.ParentID.ToStringHyphenated();
526 TempHash["version"] = (Int32)InvFolder.Version;
527 TempHash["type_default"] = (Int32)InvFolder.DefaultType;
528 TempHash["folder_id"] = InvFolder.FolderID.ToStringHyphenated();
529 AgentInventoryArray.Add(TempHash);
530 }
531
532 Hashtable InventoryRootHash = new Hashtable();
533 InventoryRootHash["folder_id"] = Library.InventoryRoot.FolderID.ToStringHyphenated();
534 ArrayList InventoryRoot = new ArrayList();
535 InventoryRoot.Add(InventoryRootHash);
536
537 Hashtable InitialOutfitHash = new Hashtable();
538 InitialOutfitHash["folder_name"] = "Nightclub Female";
539 InitialOutfitHash["gender"] = "female";
540 ArrayList InitialOutfit = new ArrayList();
541 InitialOutfit.Add(InitialOutfitHash);
542
543 // Circuit Code
544 uint circode = (uint)(Util.RandomClass.Next());
545
546 // Generics
547 responseData["last_name"] = TheUser.surname;
548 responseData["ui-config"] = ui_config;
549 responseData["sim_ip"] = "127.0.0.1"; //SimInfo.sim_ip.ToString();
550 responseData["login-flags"] = LoginFlags;
551 responseData["global-textures"] = GlobalTextures;
552 responseData["classified_categories"] = ClassifiedCategories;
553 responseData["event_categories"] = new ArrayList();
554 responseData["inventory-skeleton"] = AgentInventoryArray;
555 responseData["inventory-skel-lib"] = new ArrayList();
556 responseData["inventory-root"] = InventoryRoot;
557 responseData["event_notifications"] = new ArrayList();
558 responseData["gestures"] = new ArrayList();
559 responseData["inventory-lib-owner"] = new ArrayList();
560 responseData["initial-outfit"] = InitialOutfit;
561 responseData["seconds_since_epoch"] = (Int32)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;
562 responseData["start_location"] = "last";
563 responseData["home"] = "!!null temporary value {home}!!"; // Overwritten
564 responseData["message"] = _config.DefaultStartupMsg;
565 responseData["first_name"] = TheUser.username;
566 responseData["circuit_code"] = (Int32)circode;
567 responseData["sim_port"] = 0; //(Int32)SimInfo.sim_port;
568 responseData["secure_session_id"] = TheUser.currentAgent.secureSessionID.ToStringHyphenated();
569 responseData["look_at"] = "\n[r" + TheUser.homeLookAt.X.ToString() + ",r" + TheUser.homeLookAt.Y.ToString() + ",r" + TheUser.homeLookAt.Z.ToString() + "]\n";
570 responseData["agent_id"] = AgentID.ToStringHyphenated();
571 responseData["region_y"] = (Int32)0; // Overwritten
572 responseData["region_x"] = (Int32)0; // Overwritten
573 responseData["seed_capability"] = "";
574 responseData["agent_access"] = "M";
575 responseData["session_id"] = TheUser.currentAgent.sessionID.ToStringHyphenated();
576 responseData["login"] = "true";
577
578 try
579 {
580 this.CustomiseResponse(ref responseData, ref TheUser);
581 }
582 catch (Exception e)
583 {
584 Console.WriteLine(e.ToString());
585 return CreateDeadRegionResponse();
586 }
587
588 CommitAgent(ref TheUser);
589
590 response.Value = responseData;
591 // TheUser.SendDataToSim(SimInfo);
592 return response;
593
594 }
595 catch (Exception E)
596 {
597 Console.WriteLine(E.ToString());
598 }
599 //}
600 }
601 return response;
602
603 }
604
605 /// <summary>
606 /// Deletes an active agent session
607 /// </summary>
608 /// <param name="request">The request</param>
609 /// <param name="path">The path (eg /bork/narf/test)</param>
610 /// <param name="param">Parameters sent</param>
611 /// <returns>Success "OK" else error</returns>
612 public string RestDeleteUserSessionMethod(string request, string path, string param)
613 {
614 // TODO! Important!
615
616 return "OK";
617 }
618
619 /// <summary>
620 /// Returns an error message that the user could not be found in the database
621 /// </summary>
622 /// <returns>XML string consisting of a error element containing individual error(s)</returns>
623 public string CreateUnknownUserErrorResponse()
624 {
625 System.IO.StringWriter sw = new System.IO.StringWriter();
626 XmlTextWriter xw = new XmlTextWriter(sw);
627
628 // Header
629 xw.Formatting = Formatting.Indented;
630 xw.WriteStartDocument();
631 xw.WriteDocType("error", null, null, null);
632 xw.WriteComment("An error occured");
633 xw.WriteStartElement("error");
634
635 // User
636 xw.WriteElementString("unknownuser", "Unable to find a user with that name");
637
638 // Footer
639 xw.WriteEndElement();
640 xw.Flush();
641 xw.Close();
642
643 return sw.ToString();
644 }
645
646 /// <summary>
647 /// Converts a user profile to an XML element which can be returned
648 /// </summary>
649 /// <param name="profile">The user profile</param>
650 /// <returns>A string containing an XML Document of the user profile</returns>
651 public string ProfileToXml(UserProfileData profile)
652 {
653 System.IO.StringWriter sw = new System.IO.StringWriter();
654 XmlTextWriter xw = new XmlTextWriter(sw);
655
656 // Header
657 xw.Formatting = Formatting.Indented;
658 xw.WriteStartDocument();
659 xw.WriteDocType("userprofile", null, null, null);
660 xw.WriteComment("Found user profiles matching the request");
661 xw.WriteStartElement("users");
662
663 // User
664 xw.WriteStartElement("user");
665 // Account information
666 xw.WriteAttributeString("firstname", profile.username);
667 xw.WriteAttributeString("lastname", profile.surname);
668 xw.WriteAttributeString("uuid", profile.UUID.ToStringHyphenated());
669 // Server Information
670 xw.WriteAttributeString("server_inventory", profile.userInventoryURI);
671 xw.WriteAttributeString("server_asset", profile.userAssetURI);
672 // Profile Information
673 xw.WriteAttributeString("profile_about", profile.profileAboutText);
674 xw.WriteAttributeString("profile_firstlife_about", profile.profileFirstText);
675 xw.WriteAttributeString("profile_firstlife_image", profile.profileFirstImage.ToStringHyphenated());
676 xw.WriteAttributeString("profile_can_do", profile.profileCanDoMask.ToString());
677 xw.WriteAttributeString("profile_want_do", profile.profileWantDoMask.ToString());
678 xw.WriteAttributeString("profile_image", profile.profileImage.ToStringHyphenated());
679 xw.WriteAttributeString("profile_created",profile.created.ToString());
680 xw.WriteAttributeString("profile_lastlogin",profile.lastLogin.ToString());
681 // Home region information
682 xw.WriteAttributeString("home_coordinates", profile.homeLocation.ToString());
683 xw.WriteAttributeString("home_region", profile.homeRegion.ToString());
684 xw.WriteAttributeString("home_look", profile.homeLookAt.ToString());
685
686 xw.WriteEndElement();
687
688 // Footer
689 xw.WriteEndElement();
690 xw.Flush();
691 xw.Close();
692
693 return sw.ToString();
694 }
695
696 public string RestGetUserMethodName(string request, string path, string param)
697 {
698 UserProfileData userProfile = getUserProfile(param.Trim());
699
700 if (userProfile == null)
701 {
702 return CreateUnknownUserErrorResponse();
703 }
704
705 return ProfileToXml(userProfile);
706 }
707
708 public string RestGetUserMethodUUID(string request, string path, string param)
709 {
710 UserProfileData userProfile = getUserProfile(new LLUUID(param));
711
712 if (userProfile == null)
713 {
714 return CreateUnknownUserErrorResponse();
715 }
716
717 return ProfileToXml(userProfile);
718 }
719
720 }
721}