UserAccountService.cs 47 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061
  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. using System;
  28. using System.Linq;
  29. using System.Collections.Generic;
  30. using System.Reflection;
  31. using log4net;
  32. using Nini.Config;
  33. using OpenMetaverse;
  34. using OpenSim.Data;
  35. using OpenSim.Framework;
  36. using OpenSim.Services.Interfaces;
  37. using OpenSim.Framework.Console;
  38. using GridRegion = OpenSim.Services.Interfaces.GridRegion;
  39. using PermissionMask = OpenSim.Framework.PermissionMask;
  40. namespace OpenSim.Services.UserAccountService
  41. {
  42. public class UserAccountService : UserAccountServiceBase, IUserAccountService
  43. {
  44. private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
  45. private static readonly UUID UUID_GRID_GOD = new UUID("6571e388-6218-4574-87db-f9379718315e");
  46. private static UserAccountService m_RootInstance;
  47. /// <summary>
  48. /// Should we create default entries (minimum body parts/clothing, avatar wearable entries) for a new avatar?
  49. /// </summary>
  50. private bool m_CreateDefaultAvatarEntries;
  51. protected IGridService m_GridService;
  52. protected IAuthenticationService m_AuthenticationService;
  53. protected IGridUserService m_GridUserService;
  54. protected IInventoryService m_InventoryService;
  55. protected IAvatarService m_AvatarService;
  56. public UserAccountService(IConfigSource config)
  57. : base(config)
  58. {
  59. IConfig userConfig = config.Configs["UserAccountService"];
  60. if (userConfig == null)
  61. throw new Exception("No UserAccountService configuration");
  62. string gridServiceDll = userConfig.GetString("GridService", string.Empty);
  63. if (gridServiceDll != string.Empty)
  64. m_GridService = LoadPlugin<IGridService>(gridServiceDll, new Object[] { config });
  65. string authServiceDll = userConfig.GetString("AuthenticationService", string.Empty);
  66. if (authServiceDll != string.Empty)
  67. m_AuthenticationService = LoadPlugin<IAuthenticationService>(authServiceDll, new Object[] { config });
  68. string presenceServiceDll = userConfig.GetString("GridUserService", string.Empty);
  69. if (presenceServiceDll != string.Empty)
  70. m_GridUserService = LoadPlugin<IGridUserService>(presenceServiceDll, new Object[] { config });
  71. string invServiceDll = userConfig.GetString("InventoryService", string.Empty);
  72. if (invServiceDll != string.Empty)
  73. m_InventoryService = LoadPlugin<IInventoryService>(invServiceDll, new Object[] { config });
  74. string avatarServiceDll = userConfig.GetString("AvatarService", string.Empty);
  75. if (avatarServiceDll != string.Empty)
  76. m_AvatarService = LoadPlugin<IAvatarService>(avatarServiceDll, new Object[] { config });
  77. m_CreateDefaultAvatarEntries = userConfig.GetBoolean("CreateDefaultAvatarEntries", false);
  78. if (m_RootInstance == null)
  79. {
  80. m_RootInstance = this;
  81. // create a system grid god account
  82. UserAccount ggod = GetUserAccount(UUID.Zero, UUID_GRID_GOD);
  83. if(ggod == null)
  84. {
  85. UserAccountData d = new UserAccountData();
  86. d.FirstName = "GRID";
  87. d.LastName = "SERVICES";
  88. d.PrincipalID = UUID_GRID_GOD;
  89. d.ScopeID = UUID.Zero;
  90. d.Data = new Dictionary<string, string>();
  91. d.Data["Email"] = string.Empty;
  92. d.Data["Created"] = Util.UnixTimeSinceEpoch().ToString();
  93. d.Data["UserLevel"] = "240";
  94. d.Data["UserFlags"] = "0";
  95. d.Data["ServiceURLs"] = string.Empty;
  96. m_Database.Store(d);
  97. }
  98. // In case there are several instances of this class in the same process,
  99. // the console commands are only registered for the root instance
  100. if (MainConsole.Instance != null)
  101. {
  102. MainConsole.Instance.Commands.AddCommand("Users", false,
  103. "create user",
  104. "create user [<first> [<last> [<pass> [<email> [<user id> [<model>]]]]]]",
  105. "Create a new user", HandleCreateUser);
  106. MainConsole.Instance.Commands.AddCommand("Users", false,
  107. "reset user password",
  108. "reset user password [<first> [<last> [<password>]]]",
  109. "Reset a user password", HandleResetUserPassword);
  110. MainConsole.Instance.Commands.AddCommand("Users", false,
  111. "reset user email",
  112. "reset user email [<first> [<last> [<email>]]]",
  113. "Reset a user email address", HandleResetUserEmail);
  114. MainConsole.Instance.Commands.AddCommand("Users", false,
  115. "set user level",
  116. "set user level [<first> [<last> [<level>]]]",
  117. "Set user level. If >= 200 and 'allow_grid_gods = true' in OpenSim.ini, "
  118. + "this account will be treated as god-moded. "
  119. + "It will also affect the 'login level' command. ",
  120. HandleSetUserLevel);
  121. MainConsole.Instance.Commands.AddCommand("Users", false,
  122. "show account",
  123. "show account <first> <last>",
  124. "Show account details for the given user", HandleShowAccount);
  125. }
  126. }
  127. }
  128. #region IUserAccountService
  129. public UserAccount GetUserAccount(UUID scopeID, string firstName,
  130. string lastName)
  131. {
  132. // m_log.DebugFormat(
  133. // "[USER ACCOUNT SERVICE]: Retrieving account by username for {0} {1}, scope {2}",
  134. // firstName, lastName, scopeID);
  135. UserAccountData[] d;
  136. if (scopeID != UUID.Zero)
  137. {
  138. d = m_Database.Get(
  139. new string[] { "ScopeID", "FirstName", "LastName" },
  140. new string[] { scopeID.ToString(), firstName, lastName });
  141. if (d.Length < 1)
  142. {
  143. d = m_Database.Get(
  144. new string[] { "ScopeID", "FirstName", "LastName" },
  145. new string[] { UUID.Zero.ToString(), firstName, lastName });
  146. }
  147. }
  148. else
  149. {
  150. d = m_Database.Get(
  151. new string[] { "FirstName", "LastName" },
  152. new string[] { firstName, lastName });
  153. }
  154. if (d.Length < 1)
  155. return null;
  156. return MakeUserAccount(d[0]);
  157. }
  158. private UserAccount MakeUserAccount(UserAccountData d)
  159. {
  160. UserAccount u = new UserAccount();
  161. u.FirstName = d.FirstName;
  162. u.LastName = d.LastName;
  163. u.PrincipalID = d.PrincipalID;
  164. u.ScopeID = d.ScopeID;
  165. if (d.Data.ContainsKey("Email") && d.Data["Email"] != null)
  166. u.Email = d.Data["Email"].ToString();
  167. else
  168. u.Email = string.Empty;
  169. u.Created = Convert.ToInt32(d.Data["Created"].ToString());
  170. if (d.Data.ContainsKey("UserTitle") && d.Data["UserTitle"] != null)
  171. u.UserTitle = d.Data["UserTitle"].ToString();
  172. else
  173. u.UserTitle = string.Empty;
  174. if (d.Data.ContainsKey("UserLevel") && d.Data["UserLevel"] != null)
  175. Int32.TryParse(d.Data["UserLevel"], out u.UserLevel);
  176. if (d.Data.ContainsKey("UserFlags") && d.Data["UserFlags"] != null)
  177. Int32.TryParse(d.Data["UserFlags"], out u.UserFlags);
  178. if (d.Data.ContainsKey("UserCountry") && d.Data["UserCountry"] != null)
  179. u.UserCountry = d.Data["UserCountry"].ToString();
  180. else
  181. u.UserCountry = string.Empty;
  182. if (d.Data.ContainsKey("ServiceURLs") && d.Data["ServiceURLs"] != null)
  183. {
  184. string[] URLs = d.Data["ServiceURLs"].ToString().Split(new char[] { ' ' });
  185. u.ServiceURLs = new Dictionary<string, object>();
  186. foreach (string url in URLs)
  187. {
  188. string[] parts = url.Split(new char[] { '=' });
  189. if (parts.Length != 2)
  190. continue;
  191. string name = System.Web.HttpUtility.UrlDecode(parts[0]);
  192. string val = System.Web.HttpUtility.UrlDecode(parts[1]);
  193. u.ServiceURLs[name] = val;
  194. }
  195. }
  196. else
  197. u.ServiceURLs = new Dictionary<string, object>();
  198. return u;
  199. }
  200. public UserAccount GetUserAccount(UUID scopeID, string email)
  201. {
  202. UserAccountData[] d;
  203. if (scopeID != UUID.Zero)
  204. {
  205. d = m_Database.Get(
  206. new string[] { "ScopeID", "Email" },
  207. new string[] { scopeID.ToString(), email });
  208. if (d.Length < 1)
  209. {
  210. d = m_Database.Get(
  211. new string[] { "ScopeID", "Email" },
  212. new string[] { UUID.Zero.ToString(), email });
  213. }
  214. }
  215. else
  216. {
  217. d = m_Database.Get(
  218. new string[] { "Email" },
  219. new string[] { email });
  220. }
  221. if (d.Length < 1)
  222. return null;
  223. return MakeUserAccount(d[0]);
  224. }
  225. public UserAccount GetUserAccount(UUID scopeID, UUID principalID)
  226. {
  227. UserAccountData[] d;
  228. if (scopeID != UUID.Zero)
  229. {
  230. d = m_Database.Get(
  231. new string[] { "ScopeID", "PrincipalID" },
  232. new string[] { scopeID.ToString(), principalID.ToString() });
  233. if (d.Length < 1)
  234. {
  235. d = m_Database.Get(
  236. new string[] { "ScopeID", "PrincipalID" },
  237. new string[] { UUID.Zero.ToString(), principalID.ToString() });
  238. }
  239. }
  240. else
  241. {
  242. d = m_Database.Get(
  243. new string[] { "PrincipalID" },
  244. new string[] { principalID.ToString() });
  245. }
  246. if (d.Length < 1)
  247. {
  248. return null;
  249. }
  250. return MakeUserAccount(d[0]);
  251. }
  252. public List<UserAccount> GetUserAccounts(UUID scopeID, List<string> IDs)
  253. {
  254. UserAccountData[] ret = m_Database.GetUsersWhere(scopeID, "PrincipalID in ('" + String.Join("', '", IDs) + "')");
  255. if(ret == null || ret.Length == 0)
  256. return new List<UserAccount>();
  257. return new List<UserAccount>(ret.Select((x) => MakeUserAccount(x)));
  258. }
  259. public void InvalidateCache(UUID userID)
  260. {
  261. }
  262. public bool StoreUserAccount(UserAccount data)
  263. {
  264. // m_log.DebugFormat(
  265. // "[USER ACCOUNT SERVICE]: Storing user account for {0} {1} {2}, scope {3}",
  266. // data.FirstName, data.LastName, data.PrincipalID, data.ScopeID);
  267. UserAccountData d = new UserAccountData();
  268. d.FirstName = data.FirstName;
  269. d.LastName = data.LastName;
  270. d.PrincipalID = data.PrincipalID;
  271. d.ScopeID = data.ScopeID;
  272. d.Data = new Dictionary<string, string>();
  273. d.Data["Email"] = data.Email;
  274. d.Data["Created"] = data.Created.ToString();
  275. d.Data["UserLevel"] = data.UserLevel.ToString();
  276. d.Data["UserFlags"] = data.UserFlags.ToString();
  277. if (data.UserTitle != null)
  278. d.Data["UserTitle"] = data.UserTitle.ToString();
  279. List<string> parts = new List<string>();
  280. foreach (KeyValuePair<string, object> kvp in data.ServiceURLs)
  281. {
  282. string key = System.Web.HttpUtility.UrlEncode(kvp.Key);
  283. string val = System.Web.HttpUtility.UrlEncode(kvp.Value.ToString());
  284. parts.Add(key + "=" + val);
  285. }
  286. d.Data["ServiceURLs"] = string.Join(" ", parts.ToArray());
  287. return m_Database.Store(d);
  288. }
  289. public List<UserAccount> GetUserAccounts(UUID scopeID, string query)
  290. {
  291. UserAccountData[] d = m_Database.GetUsers(scopeID, query.Trim());
  292. if (d == null)
  293. return new List<UserAccount>();
  294. List<UserAccount> ret = new List<UserAccount>();
  295. foreach (UserAccountData data in d)
  296. ret.Add(MakeUserAccount(data));
  297. return ret;
  298. }
  299. public List<UserAccount> GetUserAccountsWhere(UUID scopeID, string where)
  300. {
  301. UserAccountData[] d = m_Database.GetUsersWhere(scopeID, where);
  302. if (d == null)
  303. return new List<UserAccount>();
  304. List<UserAccount> ret = new List<UserAccount>();
  305. foreach (UserAccountData data in d)
  306. ret.Add(MakeUserAccount(data));
  307. return ret;
  308. }
  309. #endregion
  310. #region Console commands
  311. /// <summary>
  312. /// Handle the create user command from the console.
  313. /// </summary>
  314. /// <param name="cmdparams">string array with parameters: firstname, lastname, password, locationX, locationY, email, userID, model name </param>
  315. protected void HandleCreateUser(string module, string[] cmdparams)
  316. {
  317. string firstName;
  318. string lastName;
  319. string password = "";
  320. string email;
  321. string rawPrincipalId;
  322. string model;
  323. // List<char> excluded = new List<char>(new char[]{' '});
  324. List<char> excluded = new List<char>(new char[]{' ', '@', '.', ':' }); //Protect user names from using valid HG identifiers.
  325. if (cmdparams.Length < 3)
  326. firstName = MainConsole.Instance.Prompt("First name", "Default", excluded);
  327. else firstName = cmdparams[2];
  328. if (cmdparams.Length < 4)
  329. lastName = MainConsole.Instance.Prompt("Last name", "User", excluded);
  330. else lastName = cmdparams[3];
  331. if (cmdparams.Length < 5)
  332. {
  333. int retries = 3;
  334. while(--retries >= 0)
  335. {
  336. password = MainConsole.Instance.Prompt("Password", null, null, false);
  337. if(String.IsNullOrWhiteSpace(password))
  338. MainConsole.Instance.Output(" You must provide a Password");
  339. else
  340. break;
  341. }
  342. if (String.IsNullOrWhiteSpace(password))
  343. {
  344. MainConsole.Instance.Output("create user aborted");
  345. return;
  346. }
  347. }
  348. else password = cmdparams[4];
  349. if (cmdparams.Length < 6)
  350. email = MainConsole.Instance.Prompt("Email", "");
  351. else email = cmdparams[5];
  352. if (cmdparams.Length < 7)
  353. rawPrincipalId = MainConsole.Instance.Prompt("User ID (enter for random)", "");
  354. else
  355. rawPrincipalId = cmdparams[6];
  356. if (cmdparams.Length < 8)
  357. model = MainConsole.Instance.Prompt("Model name","");
  358. else
  359. model = cmdparams[7];
  360. UUID principalId = UUID.Zero;
  361. if(String.IsNullOrWhiteSpace(rawPrincipalId))
  362. principalId = UUID.Random();
  363. else if (!UUID.TryParse(rawPrincipalId, out principalId))
  364. throw new Exception(string.Format("ID {0} is not a valid UUID", rawPrincipalId));
  365. CreateUser(UUID.Zero, principalId, firstName, lastName, password, email, model);
  366. }
  367. protected void HandleShowAccount(string module, string[] cmdparams)
  368. {
  369. if (cmdparams.Length != 4)
  370. {
  371. MainConsole.Instance.Output("Usage: show account <first-name> <last-name>");
  372. return;
  373. }
  374. string firstName = cmdparams[2];
  375. string lastName = cmdparams[3];
  376. UserAccount ua = GetUserAccount(UUID.Zero, firstName, lastName);
  377. if (ua == null)
  378. {
  379. MainConsole.Instance.Output("No user named {0} {1}", firstName, lastName);
  380. return;
  381. }
  382. MainConsole.Instance.Output("Name: {0}", ua.Name);
  383. MainConsole.Instance.Output("ID: {0}", ua.PrincipalID);
  384. MainConsole.Instance.Output("Title: {0}", ua.UserTitle);
  385. MainConsole.Instance.Output("E-mail: {0}", ua.Email);
  386. MainConsole.Instance.Output("Created: {0}", Utils.UnixTimeToDateTime(ua.Created));
  387. MainConsole.Instance.Output("Level: {0}", ua.UserLevel);
  388. MainConsole.Instance.Output("Flags: {0}", ua.UserFlags);
  389. foreach (KeyValuePair<string, Object> kvp in ua.ServiceURLs)
  390. MainConsole.Instance.Output("{0}: {1}", kvp.Key, kvp.Value);
  391. }
  392. protected void HandleResetUserPassword(string module, string[] cmdparams)
  393. {
  394. string firstName;
  395. string lastName;
  396. string newPassword;
  397. if (cmdparams.Length < 4)
  398. firstName = MainConsole.Instance.Prompt("First name");
  399. else firstName = cmdparams[3];
  400. if (cmdparams.Length < 5)
  401. lastName = MainConsole.Instance.Prompt("Last name");
  402. else lastName = cmdparams[4];
  403. if (cmdparams.Length < 6)
  404. newPassword = MainConsole.Instance.Prompt("New password", null, null, false);
  405. else newPassword = cmdparams[5];
  406. UserAccount account = GetUserAccount(UUID.Zero, firstName, lastName);
  407. if (account == null)
  408. {
  409. MainConsole.Instance.Output("No such user as {0} {1}", firstName, lastName);
  410. return;
  411. }
  412. bool success = false;
  413. if (m_AuthenticationService != null)
  414. success = m_AuthenticationService.SetPassword(account.PrincipalID, newPassword);
  415. if (!success)
  416. MainConsole.Instance.Output("Unable to reset password for account {0} {1}.", firstName, lastName);
  417. else
  418. MainConsole.Instance.Output("Password reset for user {0} {1}", firstName, lastName);
  419. }
  420. protected void HandleResetUserEmail(string module, string[] cmdparams)
  421. {
  422. string firstName;
  423. string lastName;
  424. string newEmail;
  425. if (cmdparams.Length < 4)
  426. firstName = MainConsole.Instance.Prompt("First name");
  427. else firstName = cmdparams[3];
  428. if (cmdparams.Length < 5)
  429. lastName = MainConsole.Instance.Prompt("Last name");
  430. else lastName = cmdparams[4];
  431. if (cmdparams.Length < 6)
  432. newEmail = MainConsole.Instance.Prompt("New Email");
  433. else newEmail = cmdparams[5];
  434. UserAccount account = GetUserAccount(UUID.Zero, firstName, lastName);
  435. if (account == null)
  436. {
  437. MainConsole.Instance.Output("No such user as {0} {1}", firstName, lastName);
  438. return;
  439. }
  440. bool success = false;
  441. account.Email = newEmail;
  442. success = StoreUserAccount(account);
  443. if (!success)
  444. MainConsole.Instance.Output("Unable to set Email for account {0} {1}.", firstName, lastName);
  445. else
  446. MainConsole.Instance.Output("User Email set for user {0} {1} to {2}", firstName, lastName, account.Email);
  447. }
  448. protected void HandleSetUserLevel(string module, string[] cmdparams)
  449. {
  450. string firstName;
  451. string lastName;
  452. string rawLevel;
  453. int level;
  454. if (cmdparams.Length < 4)
  455. firstName = MainConsole.Instance.Prompt("First name");
  456. else firstName = cmdparams[3];
  457. if (cmdparams.Length < 5)
  458. lastName = MainConsole.Instance.Prompt("Last name");
  459. else lastName = cmdparams[4];
  460. UserAccount account = GetUserAccount(UUID.Zero, firstName, lastName);
  461. if (account == null) {
  462. MainConsole.Instance.Output("No such user");
  463. return;
  464. }
  465. if (cmdparams.Length < 6)
  466. rawLevel = MainConsole.Instance.Prompt("User level");
  467. else rawLevel = cmdparams[5];
  468. if(int.TryParse(rawLevel, out level) == false) {
  469. MainConsole.Instance.Output("Invalid user level");
  470. return;
  471. }
  472. account.UserLevel = level;
  473. bool success = StoreUserAccount(account);
  474. if (!success)
  475. MainConsole.Instance.Output("Unable to set user level for account {0} {1}.", firstName, lastName);
  476. else
  477. MainConsole.Instance.Output("User level set for user {0} {1} to {2}", firstName, lastName, level);
  478. }
  479. #endregion
  480. /// <summary>
  481. /// Create a user
  482. /// </summary>
  483. /// <param name="scopeID">Allows hosting of multiple grids in a single database. Normally left as UUID.Zero</param>
  484. /// <param name="principalID">ID of the user</param>
  485. /// <param name="firstName"></param>
  486. /// <param name="lastName"></param>
  487. /// <param name="password"></param>
  488. /// <param name="email"></param>
  489. /// <param name="model"></param>
  490. public UserAccount CreateUser(UUID scopeID, UUID principalID, string firstName, string lastName, string password, string email, string model = "")
  491. {
  492. UserAccount account = GetUserAccount(UUID.Zero, firstName, lastName);
  493. if (null == account)
  494. {
  495. account = new UserAccount(UUID.Zero, principalID, firstName, lastName, email);
  496. if (account.ServiceURLs == null || (account.ServiceURLs != null && account.ServiceURLs.Count == 0))
  497. {
  498. account.ServiceURLs = new Dictionary<string, object>();
  499. account.ServiceURLs["HomeURI"] = string.Empty;
  500. account.ServiceURLs["InventoryServerURI"] = string.Empty;
  501. account.ServiceURLs["AssetServerURI"] = string.Empty;
  502. }
  503. if (StoreUserAccount(account))
  504. {
  505. bool success;
  506. if (m_AuthenticationService != null)
  507. {
  508. success = m_AuthenticationService.SetPassword(account.PrincipalID, password);
  509. if (!success)
  510. m_log.WarnFormat("[USER ACCOUNT SERVICE]: Unable to set password for account {0} {1}.",
  511. firstName, lastName);
  512. }
  513. GridRegion home = null;
  514. if (m_GridService != null)
  515. {
  516. List<GridRegion> defaultRegions = m_GridService.GetDefaultRegions(UUID.Zero);
  517. if (defaultRegions != null && defaultRegions.Count >= 1)
  518. home = defaultRegions[0];
  519. if (m_GridUserService != null && home != null)
  520. m_GridUserService.SetHome(account.PrincipalID.ToString(), home.RegionID, new Vector3(128, 128, 0), new Vector3(0, 1, 0));
  521. else
  522. m_log.WarnFormat("[USER ACCOUNT SERVICE]: Unable to set home for account {0} {1}.",
  523. firstName, lastName);
  524. }
  525. else
  526. {
  527. m_log.WarnFormat("[USER ACCOUNT SERVICE]: Unable to retrieve home region for account {0} {1}.",
  528. firstName, lastName);
  529. }
  530. if (m_InventoryService != null)
  531. {
  532. success = m_InventoryService.CreateUserInventory(account.PrincipalID);
  533. if (!success)
  534. {
  535. m_log.WarnFormat("[USER ACCOUNT SERVICE]: Unable to create inventory for account {0} {1}.",
  536. firstName, lastName);
  537. }
  538. else
  539. {
  540. m_log.DebugFormat(
  541. "[USER ACCOUNT SERVICE]: Created user inventory for {0} {1}", firstName, lastName);
  542. }
  543. if (m_CreateDefaultAvatarEntries)
  544. {
  545. if (String.IsNullOrEmpty(model))
  546. CreateDefaultAppearanceEntries(account.PrincipalID);
  547. else
  548. EstablishAppearance(account.PrincipalID, model);
  549. }
  550. }
  551. m_log.InfoFormat(
  552. "[USER ACCOUNT SERVICE]: Account {0} {1} {2} created successfully",
  553. firstName, lastName, account.PrincipalID);
  554. }
  555. else
  556. {
  557. m_log.ErrorFormat("[USER ACCOUNT SERVICE]: Account creation failed for account {0} {1}", firstName, lastName);
  558. }
  559. }
  560. else
  561. {
  562. m_log.ErrorFormat("[USER ACCOUNT SERVICE]: A user with the name {0} {1} already exists!", firstName, lastName);
  563. }
  564. return account;
  565. }
  566. protected void CreateDefaultAppearanceEntries(UUID principalID)
  567. {
  568. m_log.DebugFormat("[USER ACCOUNT SERVICE]: Creating default appearance items for {0}", principalID);
  569. InventoryFolderBase bodyPartsFolder = m_InventoryService.GetFolderForType(principalID, FolderType.BodyPart);
  570. // Get Current Outfit folder
  571. InventoryFolderBase currentOutfitFolder = m_InventoryService.GetFolderForType(principalID, FolderType.CurrentOutfit);
  572. InventoryItemBase eyes = new InventoryItemBase(UUID.Random(), principalID);
  573. eyes.AssetID = AvatarWearable.DEFAULT_EYES_ASSET;
  574. eyes.Name = "Default Eyes";
  575. eyes.CreatorId = principalID.ToString();
  576. eyes.AssetType = (int)AssetType.Bodypart;
  577. eyes.InvType = (int)InventoryType.Wearable;
  578. eyes.Folder = bodyPartsFolder.ID;
  579. eyes.BasePermissions = (uint)PermissionMask.All;
  580. eyes.CurrentPermissions = (uint)PermissionMask.All;
  581. eyes.EveryOnePermissions = (uint)PermissionMask.All;
  582. eyes.GroupPermissions = (uint)PermissionMask.All;
  583. eyes.NextPermissions = (uint)PermissionMask.All;
  584. eyes.Flags = (uint)WearableType.Eyes;
  585. m_InventoryService.AddItem(eyes);
  586. CreateCurrentOutfitLink((int)InventoryType.Wearable, (uint)WearableType.Eyes, eyes.Name, eyes.ID, principalID, currentOutfitFolder.ID);
  587. InventoryItemBase shape = new InventoryItemBase(UUID.Random(), principalID);
  588. shape.AssetID = AvatarWearable.DEFAULT_BODY_ASSET;
  589. shape.Name = "Default Shape";
  590. shape.CreatorId = principalID.ToString();
  591. shape.AssetType = (int)AssetType.Bodypart;
  592. shape.InvType = (int)InventoryType.Wearable;
  593. shape.Folder = bodyPartsFolder.ID;
  594. shape.BasePermissions = (uint)PermissionMask.All;
  595. shape.CurrentPermissions = (uint)PermissionMask.All;
  596. shape.EveryOnePermissions = (uint)PermissionMask.All;
  597. shape.GroupPermissions = (uint)PermissionMask.All;
  598. shape.NextPermissions = (uint)PermissionMask.All;
  599. shape.Flags = (uint)WearableType.Shape;
  600. m_InventoryService.AddItem(shape);
  601. CreateCurrentOutfitLink((int)InventoryType.Wearable, (uint)WearableType.Shape, shape.Name, shape.ID, principalID, currentOutfitFolder.ID);
  602. InventoryItemBase skin = new InventoryItemBase(UUID.Random(), principalID);
  603. skin.AssetID = AvatarWearable.DEFAULT_SKIN_ASSET;
  604. skin.Name = "Default Skin";
  605. skin.CreatorId = principalID.ToString();
  606. skin.AssetType = (int)AssetType.Bodypart;
  607. skin.InvType = (int)InventoryType.Wearable;
  608. skin.Folder = bodyPartsFolder.ID;
  609. skin.BasePermissions = (uint)PermissionMask.All;
  610. skin.CurrentPermissions = (uint)PermissionMask.All;
  611. skin.EveryOnePermissions = (uint)PermissionMask.All;
  612. skin.GroupPermissions = (uint)PermissionMask.All;
  613. skin.NextPermissions = (uint)PermissionMask.All;
  614. skin.Flags = (uint)WearableType.Skin;
  615. m_InventoryService.AddItem(skin);
  616. CreateCurrentOutfitLink((int)InventoryType.Wearable, (uint)WearableType.Skin, skin.Name, skin.ID, principalID, currentOutfitFolder.ID);
  617. InventoryItemBase hair = new InventoryItemBase(UUID.Random(), principalID);
  618. hair.AssetID = AvatarWearable.DEFAULT_HAIR_ASSET;
  619. hair.Name = "Default Hair";
  620. hair.CreatorId = principalID.ToString();
  621. hair.AssetType = (int)AssetType.Bodypart;
  622. hair.InvType = (int)InventoryType.Wearable;
  623. hair.Folder = bodyPartsFolder.ID;
  624. hair.BasePermissions = (uint)PermissionMask.All;
  625. hair.CurrentPermissions = (uint)PermissionMask.All;
  626. hair.EveryOnePermissions = (uint)PermissionMask.All;
  627. hair.GroupPermissions = (uint)PermissionMask.All;
  628. hair.NextPermissions = (uint)PermissionMask.All;
  629. hair.Flags = (uint)WearableType.Hair;
  630. m_InventoryService.AddItem(hair);
  631. CreateCurrentOutfitLink((int)InventoryType.Wearable, (uint)WearableType.Hair, hair.Name, hair.ID, principalID, currentOutfitFolder.ID);
  632. InventoryFolderBase clothingFolder = m_InventoryService.GetFolderForType(principalID, FolderType.Clothing);
  633. InventoryItemBase shirt = new InventoryItemBase(UUID.Random(), principalID);
  634. shirt.AssetID = AvatarWearable.DEFAULT_SHIRT_ASSET;
  635. shirt.Name = "Default Shirt";
  636. shirt.CreatorId = principalID.ToString();
  637. shirt.AssetType = (int)AssetType.Clothing;
  638. shirt.InvType = (int)InventoryType.Wearable;
  639. shirt.Folder = clothingFolder.ID;
  640. shirt.BasePermissions = (uint)PermissionMask.All;
  641. shirt.CurrentPermissions = (uint)PermissionMask.All;
  642. shirt.EveryOnePermissions = (uint)PermissionMask.All;
  643. shirt.GroupPermissions = (uint)PermissionMask.All;
  644. shirt.NextPermissions = (uint)PermissionMask.All;
  645. shirt.Flags = (uint)WearableType.Shirt;
  646. m_InventoryService.AddItem(shirt);
  647. CreateCurrentOutfitLink((int)InventoryType.Wearable, (uint)WearableType.Shirt, shirt.Name, shirt.ID, principalID, currentOutfitFolder.ID);
  648. InventoryItemBase pants = new InventoryItemBase(UUID.Random(), principalID);
  649. pants.AssetID = AvatarWearable.DEFAULT_PANTS_ASSET;
  650. pants.Name = "Default Pants";
  651. pants.CreatorId = principalID.ToString();
  652. pants.AssetType = (int)AssetType.Clothing;
  653. pants.InvType = (int)InventoryType.Wearable;
  654. pants.Folder = clothingFolder.ID;
  655. pants.BasePermissions = (uint)PermissionMask.All;
  656. pants.CurrentPermissions = (uint)PermissionMask.All;
  657. pants.EveryOnePermissions = (uint)PermissionMask.All;
  658. pants.GroupPermissions = (uint)PermissionMask.All;
  659. pants.NextPermissions = (uint)PermissionMask.All;
  660. pants.Flags = (uint)WearableType.Pants;
  661. m_InventoryService.AddItem(pants);
  662. CreateCurrentOutfitLink((int)InventoryType.Wearable, (uint)WearableType.Pants, pants.Name, pants.ID, principalID, currentOutfitFolder.ID);
  663. if (m_AvatarService != null)
  664. {
  665. m_log.DebugFormat("[USER ACCOUNT SERVICE]: Creating default avatar entries for {0}", principalID);
  666. AvatarWearable[] wearables = new AvatarWearable[6];
  667. wearables[AvatarWearable.EYES] = new AvatarWearable(eyes.ID, eyes.AssetID);
  668. wearables[AvatarWearable.BODY] = new AvatarWearable(shape.ID, shape.AssetID);
  669. wearables[AvatarWearable.SKIN] = new AvatarWearable(skin.ID, skin.AssetID);
  670. wearables[AvatarWearable.HAIR] = new AvatarWearable(hair.ID, hair.AssetID);
  671. wearables[AvatarWearable.SHIRT] = new AvatarWearable(shirt.ID, shirt.AssetID);
  672. wearables[AvatarWearable.PANTS] = new AvatarWearable(pants.ID, pants.AssetID);
  673. AvatarAppearance ap = new AvatarAppearance();
  674. // this loop works, but is questionable
  675. for (int i = 0; i < 6; i++)
  676. {
  677. ap.SetWearable(i, wearables[i]);
  678. }
  679. m_AvatarService.SetAppearance(principalID, ap);
  680. }
  681. }
  682. protected void EstablishAppearance(UUID destinationAgent, string model)
  683. {
  684. m_log.DebugFormat("[USER ACCOUNT SERVICE]: Establishing new appearance for {0} - {1}",
  685. destinationAgent.ToString(), model);
  686. string[] modelSpecifiers = model.Split();
  687. if (modelSpecifiers.Length != 2)
  688. {
  689. m_log.WarnFormat("[USER ACCOUNT SERVICE]: Invalid model name \'{0}\'. Falling back to Ruth for {1}",
  690. model, destinationAgent);
  691. CreateDefaultAppearanceEntries(destinationAgent);
  692. return;
  693. }
  694. // Does the source model exist?
  695. UserAccount modelAccount = GetUserAccount(UUID.Zero, modelSpecifiers[0], modelSpecifiers[1]);
  696. if (modelAccount == null)
  697. {
  698. m_log.WarnFormat("[USER ACCOUNT SERVICE]: Requested model \'{0}\' not found. Falling back to Ruth for {1}",
  699. model, destinationAgent);
  700. CreateDefaultAppearanceEntries(destinationAgent);
  701. return;
  702. }
  703. // Does the source model have an established appearance herself?
  704. AvatarAppearance modelAppearance = m_AvatarService.GetAppearance(modelAccount.PrincipalID);
  705. if (modelAppearance == null)
  706. {
  707. m_log.WarnFormat("USER ACCOUNT SERVICE]: Requested model \'{0}\' does not have an established appearance. Falling back to Ruth for {1}",
  708. model, destinationAgent);
  709. CreateDefaultAppearanceEntries(destinationAgent);
  710. return;
  711. }
  712. try
  713. {
  714. CopyWearablesAndAttachments(destinationAgent, modelAccount.PrincipalID, modelAppearance);
  715. m_AvatarService.SetAppearance(destinationAgent, modelAppearance);
  716. }
  717. catch (Exception e)
  718. {
  719. m_log.WarnFormat("[USER ACCOUNT SERVICE]: Error transferring appearance for {0} : {1}",
  720. destinationAgent, e.Message);
  721. }
  722. m_log.DebugFormat("[USER ACCOUNT SERVICE]: Finished establishing appearance for {0}",
  723. destinationAgent.ToString());
  724. }
  725. /// <summary>
  726. /// This method is called by EstablishAppearance to do a copy all inventory items
  727. /// worn or attached to the Clothing inventory folder of the receiving avatar.
  728. /// In parallel the avatar wearables and attachments are updated.
  729. /// </summary>
  730. private void CopyWearablesAndAttachments(UUID destination, UUID source, AvatarAppearance avatarAppearance)
  731. {
  732. AvatarWearable[] wearables = avatarAppearance.Wearables;
  733. if(wearables.Length == 0)
  734. throw new Exception("Model does not have wearables");
  735. // Get Clothing folder of receiver
  736. InventoryFolderBase destinationFolder = m_InventoryService.GetFolderForType(destination, FolderType.Clothing);
  737. if (destinationFolder == null)
  738. throw new Exception("Cannot locate new clothing folder(s)");
  739. // Get Current Outfit folder
  740. InventoryFolderBase currentOutfitFolder = m_InventoryService.GetFolderForType(destination, FolderType.CurrentOutfit);
  741. // wrong destination folder type? create new
  742. if (destinationFolder.Type != (short)FolderType.Clothing)
  743. {
  744. destinationFolder = new InventoryFolderBase();
  745. destinationFolder.ID = UUID.Random();
  746. destinationFolder.Name = "Clothing";
  747. destinationFolder.Owner = destination;
  748. destinationFolder.Type = (short)AssetType.Clothing;
  749. destinationFolder.ParentID = m_InventoryService.GetRootFolder(destination).ID;
  750. destinationFolder.Version = 1;
  751. m_InventoryService.AddFolder(destinationFolder); // store base record
  752. m_log.ErrorFormat("[USER ACCOUNT SERVICE]: Created folder for destination {0} Clothing", source);
  753. }
  754. // Wearables
  755. AvatarWearable basewearable;
  756. WearableItem wearable;
  757. AvatarWearable newbasewearable = new AvatarWearable();
  758. // copy wearables creating new inventory entries
  759. for (int i = 0; i < wearables.Length; i++)
  760. {
  761. basewearable = wearables[i];
  762. if(basewearable == null || basewearable.Count == 0)
  763. continue;
  764. newbasewearable.Clear();
  765. for(int j = 0; j < basewearable.Count; j++)
  766. {
  767. wearable = basewearable[j];
  768. if (wearable.ItemID != UUID.Zero)
  769. {
  770. m_log.DebugFormat("[XXX]: Getting item {0} from avie {1} for {2} {3}",
  771. wearable.ItemID, source, i, j);
  772. // Get inventory item and copy it
  773. InventoryItemBase item = m_InventoryService.GetItem(source, wearable.ItemID);
  774. if(item != null && item.AssetType == (int)AssetType.Link)
  775. {
  776. if(item.AssetID == UUID.Zero )
  777. item = null;
  778. else
  779. item = m_InventoryService.GetItem(source, item.AssetID);
  780. }
  781. if (item != null)
  782. {
  783. InventoryItemBase destinationItem = new InventoryItemBase(UUID.Random(), destination);
  784. destinationItem.Name = item.Name;
  785. destinationItem.Owner = destination;
  786. destinationItem.Description = item.Description;
  787. destinationItem.InvType = item.InvType;
  788. destinationItem.CreatorId = item.CreatorId;
  789. destinationItem.CreatorData = item.CreatorData;
  790. destinationItem.NextPermissions = item.NextPermissions;
  791. destinationItem.CurrentPermissions = item.CurrentPermissions;
  792. destinationItem.BasePermissions = item.BasePermissions;
  793. destinationItem.EveryOnePermissions = item.EveryOnePermissions;
  794. destinationItem.GroupPermissions = item.GroupPermissions;
  795. destinationItem.AssetType = item.AssetType;
  796. destinationItem.AssetID = item.AssetID;
  797. destinationItem.GroupID = item.GroupID;
  798. destinationItem.GroupOwned = item.GroupOwned;
  799. destinationItem.SalePrice = item.SalePrice;
  800. destinationItem.SaleType = item.SaleType;
  801. destinationItem.Flags = item.Flags;
  802. destinationItem.CreationDate = item.CreationDate;
  803. destinationItem.Folder = destinationFolder.ID;
  804. ApplyNextOwnerPermissions(destinationItem);
  805. m_InventoryService.AddItem(destinationItem);
  806. m_log.DebugFormat("[USER ACCOUNT SERVICE]: Added item {0} to folder {1}", destinationItem.ID, destinationFolder.ID);
  807. // Wear item
  808. newbasewearable.Add(destinationItem.ID,wearable.AssetID);
  809. // Add to Current Outfit
  810. CreateCurrentOutfitLink((int)InventoryType.Wearable, item.Flags, item.Name, destinationItem.ID, destination, currentOutfitFolder.ID);
  811. }
  812. else
  813. {
  814. m_log.WarnFormat("[USER ACCOUNT SERVICE]: Error transferring {0} to folder {1}", wearable.ItemID, destinationFolder.ID);
  815. }
  816. }
  817. }
  818. avatarAppearance.SetWearable(i, newbasewearable);
  819. }
  820. // Attachments
  821. List<AvatarAttachment> attachments = avatarAppearance.GetAttachments();
  822. avatarAppearance.ClearAttachments();
  823. foreach (AvatarAttachment attachment in attachments)
  824. {
  825. int attachpoint = attachment.AttachPoint;
  826. UUID itemID = attachment.ItemID;
  827. if (itemID != UUID.Zero)
  828. {
  829. // Get inventory item and copy it
  830. InventoryItemBase item = m_InventoryService.GetItem(source, itemID);
  831. if (item != null)
  832. {
  833. InventoryItemBase destinationItem = new InventoryItemBase(UUID.Random(), destination);
  834. destinationItem.Name = item.Name;
  835. destinationItem.Owner = destination;
  836. destinationItem.Description = item.Description;
  837. destinationItem.InvType = item.InvType;
  838. destinationItem.CreatorId = item.CreatorId;
  839. destinationItem.CreatorData = item.CreatorData;
  840. destinationItem.NextPermissions = item.NextPermissions;
  841. destinationItem.CurrentPermissions = item.CurrentPermissions;
  842. destinationItem.BasePermissions = item.BasePermissions;
  843. destinationItem.EveryOnePermissions = item.EveryOnePermissions;
  844. destinationItem.GroupPermissions = item.GroupPermissions;
  845. destinationItem.AssetType = item.AssetType;
  846. destinationItem.AssetID = item.AssetID;
  847. destinationItem.GroupID = item.GroupID;
  848. destinationItem.GroupOwned = item.GroupOwned;
  849. destinationItem.SalePrice = item.SalePrice;
  850. destinationItem.SaleType = item.SaleType;
  851. destinationItem.Flags = item.Flags;
  852. destinationItem.CreationDate = item.CreationDate;
  853. destinationItem.Folder = destinationFolder.ID;
  854. ApplyNextOwnerPermissions(destinationItem);
  855. m_InventoryService.AddItem(destinationItem);
  856. m_log.DebugFormat("[USER ACCOUNT SERVICE]: Added item {0} to folder {1}", destinationItem.ID, destinationFolder.ID);
  857. // Attach item
  858. avatarAppearance.SetAttachment(attachpoint, destinationItem.ID, destinationItem.AssetID);
  859. m_log.DebugFormat("[USER ACCOUNT SERVICE]: Attached {0}", destinationItem.ID);
  860. // Add to Current Outfit
  861. CreateCurrentOutfitLink(destinationItem.InvType, item.Flags, item.Name, destinationItem.ID, destination, currentOutfitFolder.ID);
  862. }
  863. else
  864. {
  865. m_log.WarnFormat("[USER ACCOUNT SERVICE]: Error transferring {0} to folder {1}", itemID, destinationFolder.ID);
  866. }
  867. }
  868. }
  869. }
  870. protected void CreateCurrentOutfitLink(int invType, uint itemType, string name, UUID itemID, UUID userID, UUID currentOutfitFolderUUID)
  871. {
  872. UUID LinkInvItem = UUID.Random();
  873. InventoryItemBase itembase = new InventoryItemBase(LinkInvItem, userID)
  874. {
  875. AssetID = itemID,
  876. AssetType = (int)AssetType.Link,
  877. CreatorId = userID.ToString(),
  878. InvType = invType,
  879. Description = "",
  880. //Folder = m_InventoryService.GetFolderForType(userID, FolderType.CurrentOutfit).ID,
  881. Folder = currentOutfitFolderUUID,
  882. Flags = itemType,
  883. Name = name,
  884. BasePermissions = (uint)PermissionMask.Copy,
  885. CurrentPermissions = (uint)PermissionMask.Copy,
  886. EveryOnePermissions = (uint)PermissionMask.Copy,
  887. GroupPermissions = (uint)PermissionMask.Copy,
  888. NextPermissions = (uint)PermissionMask.Copy
  889. };
  890. m_InventoryService.AddItem(itembase);
  891. }
  892. /// <summary>
  893. /// Apply next owner permissions.
  894. /// </summary>
  895. private void ApplyNextOwnerPermissions(InventoryItemBase item)
  896. {
  897. if (item.InvType == (int)InventoryType.Object)
  898. {
  899. uint perms = item.CurrentPermissions;
  900. item.CurrentPermissions = perms;
  901. }
  902. item.CurrentPermissions &= item.NextPermissions;
  903. item.BasePermissions &= item.NextPermissions;
  904. item.EveryOnePermissions &= item.NextPermissions;
  905. }
  906. }
  907. }