UserAccountService.cs 48 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062
  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 (!string.IsNullOrEmpty(data.UserTitle))
  278. d.Data["UserTitle"] = data.UserTitle;
  279. if (!string.IsNullOrEmpty(data.UserCountry))
  280. d.Data["UserCountry"] = data.UserCountry;
  281. List<string> parts = new List<string>();
  282. foreach (KeyValuePair<string, object> kvp in data.ServiceURLs)
  283. {
  284. string key = System.Web.HttpUtility.UrlEncode(kvp.Key);
  285. string val = System.Web.HttpUtility.UrlEncode(kvp.Value.ToString());
  286. parts.Add(key + "=" + val);
  287. }
  288. d.Data["ServiceURLs"] = string.Join(" ", parts.ToArray());
  289. return m_Database.Store(d);
  290. }
  291. public List<UserAccount> GetUserAccounts(UUID scopeID, string query)
  292. {
  293. UserAccountData[] d = m_Database.GetUsers(scopeID, query.Trim());
  294. if (d == null)
  295. return new List<UserAccount>();
  296. List<UserAccount> ret = new List<UserAccount>();
  297. foreach (UserAccountData data in d)
  298. ret.Add(MakeUserAccount(data));
  299. return ret;
  300. }
  301. public List<UserAccount> GetUserAccountsWhere(UUID scopeID, string where)
  302. {
  303. UserAccountData[] d = m_Database.GetUsersWhere(scopeID, where);
  304. if (d == null)
  305. return new List<UserAccount>();
  306. List<UserAccount> ret = new List<UserAccount>();
  307. foreach (UserAccountData data in d)
  308. ret.Add(MakeUserAccount(data));
  309. return ret;
  310. }
  311. #endregion
  312. #region Console commands
  313. /// <summary>
  314. /// Handle the create user command from the console.
  315. /// </summary>
  316. /// <param name="cmdparams">string array with parameters: firstname, lastname, password, locationX, locationY, email, userID, model name </param>
  317. protected void HandleCreateUser(string module, string[] cmdparams)
  318. {
  319. string firstName;
  320. string lastName;
  321. string password = "";
  322. string email;
  323. string rawPrincipalId;
  324. string model;
  325. // List<char> excluded = new List<char>(new char[]{' '});
  326. List<char> excluded = new List<char>(new char[]{' ', '@', '.', ':' }); //Protect user names from using valid HG identifiers.
  327. if (cmdparams.Length < 3)
  328. firstName = MainConsole.Instance.Prompt("First name", "Default", excluded);
  329. else firstName = cmdparams[2];
  330. if (cmdparams.Length < 4)
  331. lastName = MainConsole.Instance.Prompt("Last name", "User", excluded);
  332. else lastName = cmdparams[3];
  333. if (cmdparams.Length < 5)
  334. {
  335. int retries = 3;
  336. while(--retries >= 0)
  337. {
  338. password = MainConsole.Instance.Prompt("Password", null, null, false);
  339. if(String.IsNullOrWhiteSpace(password))
  340. MainConsole.Instance.Output(" You must provide a Password");
  341. else
  342. break;
  343. }
  344. if (String.IsNullOrWhiteSpace(password))
  345. {
  346. MainConsole.Instance.Output("create user aborted");
  347. return;
  348. }
  349. }
  350. else password = cmdparams[4];
  351. if (cmdparams.Length < 6)
  352. email = MainConsole.Instance.Prompt("Email", "");
  353. else email = cmdparams[5];
  354. if (cmdparams.Length < 7)
  355. rawPrincipalId = MainConsole.Instance.Prompt("User ID (enter for random)", "");
  356. else
  357. rawPrincipalId = cmdparams[6];
  358. if (cmdparams.Length < 8)
  359. model = MainConsole.Instance.Prompt("Model name","");
  360. else
  361. model = cmdparams[7];
  362. UUID principalId = UUID.Zero;
  363. if(String.IsNullOrWhiteSpace(rawPrincipalId))
  364. principalId = UUID.Random();
  365. else if (!UUID.TryParse(rawPrincipalId, out principalId))
  366. throw new Exception(string.Format("ID {0} is not a valid UUID", rawPrincipalId));
  367. CreateUser(UUID.Zero, principalId, firstName, lastName, password, email, model);
  368. }
  369. protected void HandleShowAccount(string module, string[] cmdparams)
  370. {
  371. if (cmdparams.Length != 4)
  372. {
  373. MainConsole.Instance.Output("Usage: show account <first-name> <last-name>");
  374. return;
  375. }
  376. string firstName = cmdparams[2];
  377. string lastName = cmdparams[3];
  378. UserAccount ua = GetUserAccount(UUID.Zero, firstName, lastName);
  379. if (ua == null)
  380. {
  381. MainConsole.Instance.Output("No user named {0} {1}", firstName, lastName);
  382. return;
  383. }
  384. MainConsole.Instance.Output("Name: {0}", ua.Name);
  385. MainConsole.Instance.Output("ID: {0}", ua.PrincipalID);
  386. MainConsole.Instance.Output("Title: {0}", ua.UserTitle);
  387. MainConsole.Instance.Output("E-mail: {0}", ua.Email);
  388. MainConsole.Instance.Output("Created: {0}", Utils.UnixTimeToDateTime(ua.Created));
  389. MainConsole.Instance.Output("Level: {0}", ua.UserLevel);
  390. MainConsole.Instance.Output("Flags: {0}", ua.UserFlags);
  391. foreach (KeyValuePair<string, Object> kvp in ua.ServiceURLs)
  392. MainConsole.Instance.Output("{0}: {1}", kvp.Key, kvp.Value);
  393. }
  394. protected void HandleResetUserPassword(string module, string[] cmdparams)
  395. {
  396. string firstName;
  397. string lastName;
  398. string newPassword;
  399. if (cmdparams.Length < 4)
  400. firstName = MainConsole.Instance.Prompt("First name");
  401. else firstName = cmdparams[3];
  402. if (cmdparams.Length < 5)
  403. lastName = MainConsole.Instance.Prompt("Last name");
  404. else lastName = cmdparams[4];
  405. if (cmdparams.Length < 6)
  406. newPassword = MainConsole.Instance.Prompt("New password", null, null, false);
  407. else newPassword = cmdparams[5];
  408. UserAccount account = GetUserAccount(UUID.Zero, firstName, lastName);
  409. if (account == null)
  410. {
  411. MainConsole.Instance.Output("No such user as {0} {1}", firstName, lastName);
  412. return;
  413. }
  414. bool success = false;
  415. if (m_AuthenticationService != null)
  416. success = m_AuthenticationService.SetPassword(account.PrincipalID, newPassword);
  417. if (!success)
  418. MainConsole.Instance.Output("Unable to reset password for account {0} {1}.", firstName, lastName);
  419. else
  420. MainConsole.Instance.Output("Password reset for user {0} {1}", firstName, lastName);
  421. }
  422. protected void HandleResetUserEmail(string module, string[] cmdparams)
  423. {
  424. string firstName;
  425. string lastName;
  426. string newEmail;
  427. if (cmdparams.Length < 4)
  428. firstName = MainConsole.Instance.Prompt("First name");
  429. else firstName = cmdparams[3];
  430. if (cmdparams.Length < 5)
  431. lastName = MainConsole.Instance.Prompt("Last name");
  432. else lastName = cmdparams[4];
  433. if (cmdparams.Length < 6)
  434. newEmail = MainConsole.Instance.Prompt("New Email");
  435. else newEmail = cmdparams[5];
  436. UserAccount account = GetUserAccount(UUID.Zero, firstName, lastName);
  437. if (account == null)
  438. {
  439. MainConsole.Instance.Output("No such user as {0} {1}", firstName, lastName);
  440. return;
  441. }
  442. bool success = false;
  443. account.Email = newEmail;
  444. success = StoreUserAccount(account);
  445. if (!success)
  446. MainConsole.Instance.Output("Unable to set Email for account {0} {1}.", firstName, lastName);
  447. else
  448. MainConsole.Instance.Output("User Email set for user {0} {1} to {2}", firstName, lastName, account.Email);
  449. }
  450. protected void HandleSetUserLevel(string module, string[] cmdparams)
  451. {
  452. string firstName;
  453. string lastName;
  454. string rawLevel;
  455. int level;
  456. if (cmdparams.Length < 4)
  457. firstName = MainConsole.Instance.Prompt("First name");
  458. else firstName = cmdparams[3];
  459. if (cmdparams.Length < 5)
  460. lastName = MainConsole.Instance.Prompt("Last name");
  461. else lastName = cmdparams[4];
  462. UserAccount account = GetUserAccount(UUID.Zero, firstName, lastName);
  463. if (account == null) {
  464. MainConsole.Instance.Output("No such user");
  465. return;
  466. }
  467. if (cmdparams.Length < 6)
  468. rawLevel = MainConsole.Instance.Prompt("User level");
  469. else rawLevel = cmdparams[5];
  470. if(int.TryParse(rawLevel, out level) == false) {
  471. MainConsole.Instance.Output("Invalid user level");
  472. return;
  473. }
  474. account.UserLevel = level;
  475. bool success = StoreUserAccount(account);
  476. if (!success)
  477. MainConsole.Instance.Output("Unable to set user level for account {0} {1}.", firstName, lastName);
  478. else
  479. MainConsole.Instance.Output("User level set for user {0} {1} to {2}", firstName, lastName, level);
  480. }
  481. #endregion
  482. /// <summary>
  483. /// Create a user
  484. /// </summary>
  485. /// <param name="scopeID">Allows hosting of multiple grids in a single database. Normally left as UUID.Zero</param>
  486. /// <param name="principalID">ID of the user</param>
  487. /// <param name="firstName"></param>
  488. /// <param name="lastName"></param>
  489. /// <param name="password"></param>
  490. /// <param name="email"></param>
  491. /// <param name="model"></param>
  492. public UserAccount CreateUser(UUID scopeID, UUID principalID, string firstName, string lastName, string password, string email, string model = "")
  493. {
  494. UserAccount account = GetUserAccount(UUID.Zero, firstName, lastName);
  495. if (null == account)
  496. {
  497. account = new UserAccount(UUID.Zero, principalID, firstName, lastName, email);
  498. if (account.ServiceURLs == null || (account.ServiceURLs != null && account.ServiceURLs.Count == 0))
  499. {
  500. account.ServiceURLs = new Dictionary<string, object>();
  501. account.ServiceURLs["HomeURI"] = string.Empty;
  502. account.ServiceURLs["InventoryServerURI"] = string.Empty;
  503. account.ServiceURLs["AssetServerURI"] = string.Empty;
  504. }
  505. if (StoreUserAccount(account))
  506. {
  507. bool success;
  508. if (m_AuthenticationService != null)
  509. {
  510. success = m_AuthenticationService.SetPassword(account.PrincipalID, password);
  511. if (!success)
  512. m_log.WarnFormat("[USER ACCOUNT SERVICE]: Unable to set password for account {0} {1}.",
  513. firstName, lastName);
  514. }
  515. GridRegion home = null;
  516. if (m_GridService != null)
  517. {
  518. List<GridRegion> defaultRegions = m_GridService.GetDefaultRegions(UUID.Zero);
  519. if (defaultRegions != null && defaultRegions.Count >= 1)
  520. home = defaultRegions[0];
  521. if (m_GridUserService != null && home != null)
  522. m_GridUserService.SetHome(account.PrincipalID.ToString(), home.RegionID, new Vector3(128, 128, 0), new Vector3(0, 1, 0));
  523. else
  524. m_log.WarnFormat("[USER ACCOUNT SERVICE]: Unable to set home for account {0} {1}.",
  525. firstName, lastName);
  526. }
  527. else
  528. {
  529. m_log.WarnFormat("[USER ACCOUNT SERVICE]: Unable to retrieve home region for account {0} {1}.",
  530. firstName, lastName);
  531. }
  532. if (m_InventoryService != null)
  533. {
  534. success = m_InventoryService.CreateUserInventory(account.PrincipalID);
  535. if (!success)
  536. {
  537. m_log.WarnFormat("[USER ACCOUNT SERVICE]: Unable to create inventory for account {0} {1}.",
  538. firstName, lastName);
  539. }
  540. else
  541. {
  542. m_log.DebugFormat(
  543. "[USER ACCOUNT SERVICE]: Created user inventory for {0} {1}", firstName, lastName);
  544. }
  545. if (m_CreateDefaultAvatarEntries)
  546. {
  547. if (String.IsNullOrEmpty(model))
  548. CreateDefaultAppearanceEntries(account.PrincipalID);
  549. else
  550. EstablishAppearance(account.PrincipalID, model);
  551. }
  552. }
  553. m_log.InfoFormat(
  554. "[USER ACCOUNT SERVICE]: Account {0} {1} {2} created successfully",
  555. firstName, lastName, account.PrincipalID);
  556. }
  557. else
  558. {
  559. m_log.ErrorFormat("[USER ACCOUNT SERVICE]: Account creation failed for account {0} {1}", firstName, lastName);
  560. }
  561. }
  562. else
  563. {
  564. m_log.ErrorFormat("[USER ACCOUNT SERVICE]: A user with the name {0} {1} already exists!", firstName, lastName);
  565. }
  566. return account;
  567. }
  568. protected void CreateDefaultAppearanceEntries(UUID principalID)
  569. {
  570. m_log.DebugFormat("[USER ACCOUNT SERVICE]: Creating default appearance items for {0}", principalID);
  571. InventoryFolderBase bodyPartsFolder = m_InventoryService.GetFolderForType(principalID, FolderType.BodyPart);
  572. // Get Current Outfit folder
  573. InventoryFolderBase currentOutfitFolder = m_InventoryService.GetFolderForType(principalID, FolderType.CurrentOutfit);
  574. InventoryItemBase eyes = new InventoryItemBase(UUID.Random(), principalID);
  575. eyes.AssetID = AvatarWearable.DEFAULT_EYES_ASSET;
  576. eyes.Name = "Default Eyes";
  577. eyes.CreatorId = principalID.ToString();
  578. eyes.AssetType = (int)AssetType.Bodypart;
  579. eyes.InvType = (int)InventoryType.Wearable;
  580. eyes.Folder = bodyPartsFolder.ID;
  581. eyes.BasePermissions = (uint)PermissionMask.All;
  582. eyes.CurrentPermissions = (uint)PermissionMask.All;
  583. eyes.EveryOnePermissions = (uint)PermissionMask.All;
  584. eyes.GroupPermissions = (uint)PermissionMask.All;
  585. eyes.NextPermissions = (uint)PermissionMask.All;
  586. eyes.Flags = (uint)WearableType.Eyes;
  587. m_InventoryService.AddItem(eyes);
  588. CreateCurrentOutfitLink((int)InventoryType.Wearable, (uint)WearableType.Eyes, eyes.Name, eyes.ID, principalID, currentOutfitFolder.ID);
  589. InventoryItemBase shape = new InventoryItemBase(UUID.Random(), principalID);
  590. shape.AssetID = AvatarWearable.DEFAULT_BODY_ASSET;
  591. shape.Name = "Default Shape";
  592. shape.CreatorId = principalID.ToString();
  593. shape.AssetType = (int)AssetType.Bodypart;
  594. shape.InvType = (int)InventoryType.Wearable;
  595. shape.Folder = bodyPartsFolder.ID;
  596. shape.BasePermissions = (uint)PermissionMask.All;
  597. shape.CurrentPermissions = (uint)PermissionMask.All;
  598. shape.EveryOnePermissions = (uint)PermissionMask.All;
  599. shape.GroupPermissions = (uint)PermissionMask.All;
  600. shape.NextPermissions = (uint)PermissionMask.All;
  601. shape.Flags = (uint)WearableType.Shape;
  602. m_InventoryService.AddItem(shape);
  603. CreateCurrentOutfitLink((int)InventoryType.Wearable, (uint)WearableType.Shape, shape.Name, shape.ID, principalID, currentOutfitFolder.ID);
  604. InventoryItemBase skin = new InventoryItemBase(UUID.Random(), principalID);
  605. skin.AssetID = AvatarWearable.DEFAULT_SKIN_ASSET;
  606. skin.Name = "Default Skin";
  607. skin.CreatorId = principalID.ToString();
  608. skin.AssetType = (int)AssetType.Bodypart;
  609. skin.InvType = (int)InventoryType.Wearable;
  610. skin.Folder = bodyPartsFolder.ID;
  611. skin.BasePermissions = (uint)PermissionMask.All;
  612. skin.CurrentPermissions = (uint)PermissionMask.All;
  613. skin.EveryOnePermissions = (uint)PermissionMask.All;
  614. skin.GroupPermissions = (uint)PermissionMask.All;
  615. skin.NextPermissions = (uint)PermissionMask.All;
  616. skin.Flags = (uint)WearableType.Skin;
  617. m_InventoryService.AddItem(skin);
  618. CreateCurrentOutfitLink((int)InventoryType.Wearable, (uint)WearableType.Skin, skin.Name, skin.ID, principalID, currentOutfitFolder.ID);
  619. InventoryItemBase hair = new InventoryItemBase(UUID.Random(), principalID);
  620. hair.AssetID = AvatarWearable.DEFAULT_HAIR_ASSET;
  621. hair.Name = "Default Hair";
  622. hair.CreatorId = principalID.ToString();
  623. hair.AssetType = (int)AssetType.Bodypart;
  624. hair.InvType = (int)InventoryType.Wearable;
  625. hair.Folder = bodyPartsFolder.ID;
  626. hair.BasePermissions = (uint)PermissionMask.All;
  627. hair.CurrentPermissions = (uint)PermissionMask.All;
  628. hair.EveryOnePermissions = (uint)PermissionMask.All;
  629. hair.GroupPermissions = (uint)PermissionMask.All;
  630. hair.NextPermissions = (uint)PermissionMask.All;
  631. hair.Flags = (uint)WearableType.Hair;
  632. m_InventoryService.AddItem(hair);
  633. CreateCurrentOutfitLink((int)InventoryType.Wearable, (uint)WearableType.Hair, hair.Name, hair.ID, principalID, currentOutfitFolder.ID);
  634. InventoryFolderBase clothingFolder = m_InventoryService.GetFolderForType(principalID, FolderType.Clothing);
  635. InventoryItemBase shirt = new InventoryItemBase(UUID.Random(), principalID);
  636. shirt.AssetID = AvatarWearable.DEFAULT_SHIRT_ASSET;
  637. shirt.Name = "Default Shirt";
  638. shirt.CreatorId = principalID.ToString();
  639. shirt.AssetType = (int)AssetType.Clothing;
  640. shirt.InvType = (int)InventoryType.Wearable;
  641. shirt.Folder = clothingFolder.ID;
  642. shirt.BasePermissions = (uint)PermissionMask.All;
  643. shirt.CurrentPermissions = (uint)PermissionMask.All;
  644. shirt.EveryOnePermissions = (uint)PermissionMask.All;
  645. shirt.GroupPermissions = (uint)PermissionMask.All;
  646. shirt.NextPermissions = (uint)PermissionMask.All;
  647. shirt.Flags = (uint)WearableType.Shirt;
  648. m_InventoryService.AddItem(shirt);
  649. CreateCurrentOutfitLink((int)InventoryType.Wearable, (uint)WearableType.Shirt, shirt.Name, shirt.ID, principalID, currentOutfitFolder.ID);
  650. InventoryItemBase pants = new InventoryItemBase(UUID.Random(), principalID);
  651. pants.AssetID = AvatarWearable.DEFAULT_PANTS_ASSET;
  652. pants.Name = "Default Pants";
  653. pants.CreatorId = principalID.ToString();
  654. pants.AssetType = (int)AssetType.Clothing;
  655. pants.InvType = (int)InventoryType.Wearable;
  656. pants.Folder = clothingFolder.ID;
  657. pants.BasePermissions = (uint)PermissionMask.All;
  658. pants.CurrentPermissions = (uint)PermissionMask.All;
  659. pants.EveryOnePermissions = (uint)PermissionMask.All;
  660. pants.GroupPermissions = (uint)PermissionMask.All;
  661. pants.NextPermissions = (uint)PermissionMask.All;
  662. pants.Flags = (uint)WearableType.Pants;
  663. m_InventoryService.AddItem(pants);
  664. CreateCurrentOutfitLink((int)InventoryType.Wearable, (uint)WearableType.Pants, pants.Name, pants.ID, principalID, currentOutfitFolder.ID);
  665. if (m_AvatarService != null)
  666. {
  667. m_log.DebugFormat("[USER ACCOUNT SERVICE]: Creating default avatar entries for {0}", principalID);
  668. AvatarWearable[] wearables = new AvatarWearable[6];
  669. wearables[AvatarWearable.EYES] = new AvatarWearable(eyes.ID, eyes.AssetID);
  670. wearables[AvatarWearable.BODY] = new AvatarWearable(shape.ID, shape.AssetID);
  671. wearables[AvatarWearable.SKIN] = new AvatarWearable(skin.ID, skin.AssetID);
  672. wearables[AvatarWearable.HAIR] = new AvatarWearable(hair.ID, hair.AssetID);
  673. wearables[AvatarWearable.SHIRT] = new AvatarWearable(shirt.ID, shirt.AssetID);
  674. wearables[AvatarWearable.PANTS] = new AvatarWearable(pants.ID, pants.AssetID);
  675. AvatarAppearance ap = new AvatarAppearance();
  676. // this loop works, but is questionable
  677. for (int i = 0; i < 6; i++)
  678. {
  679. ap.SetWearable(i, wearables[i]);
  680. }
  681. m_AvatarService.SetAppearance(principalID, ap);
  682. }
  683. }
  684. protected void EstablishAppearance(UUID destinationAgent, string model)
  685. {
  686. m_log.DebugFormat("[USER ACCOUNT SERVICE]: Establishing new appearance for {0} - {1}",
  687. destinationAgent.ToString(), model);
  688. string[] modelSpecifiers = model.Split();
  689. if (modelSpecifiers.Length != 2)
  690. {
  691. m_log.WarnFormat("[USER ACCOUNT SERVICE]: Invalid model name \'{0}\'. Falling back to Ruth for {1}",
  692. model, destinationAgent);
  693. CreateDefaultAppearanceEntries(destinationAgent);
  694. return;
  695. }
  696. // Does the source model exist?
  697. UserAccount modelAccount = GetUserAccount(UUID.Zero, modelSpecifiers[0], modelSpecifiers[1]);
  698. if (modelAccount == null)
  699. {
  700. m_log.WarnFormat("[USER ACCOUNT SERVICE]: Requested model \'{0}\' not found. Falling back to Ruth for {1}",
  701. model, destinationAgent);
  702. CreateDefaultAppearanceEntries(destinationAgent);
  703. return;
  704. }
  705. // Does the source model have an established appearance herself?
  706. AvatarAppearance modelAppearance = m_AvatarService.GetAppearance(modelAccount.PrincipalID);
  707. if (modelAppearance == null)
  708. {
  709. m_log.WarnFormat("USER ACCOUNT SERVICE]: Requested model \'{0}\' does not have an established appearance. Falling back to Ruth for {1}",
  710. model, destinationAgent);
  711. CreateDefaultAppearanceEntries(destinationAgent);
  712. return;
  713. }
  714. try
  715. {
  716. CopyWearablesAndAttachments(destinationAgent, modelAccount.PrincipalID, modelAppearance);
  717. m_AvatarService.SetAppearance(destinationAgent, modelAppearance);
  718. }
  719. catch (Exception e)
  720. {
  721. m_log.WarnFormat("[USER ACCOUNT SERVICE]: Error transferring appearance for {0} : {1}",
  722. destinationAgent, e.Message);
  723. }
  724. m_log.DebugFormat("[USER ACCOUNT SERVICE]: Finished establishing appearance for {0}",
  725. destinationAgent.ToString());
  726. }
  727. /// <summary>
  728. /// This method is called by EstablishAppearance to do a copy all inventory items
  729. /// worn or attached to the Clothing inventory folder of the receiving avatar.
  730. /// In parallel the avatar wearables and attachments are updated.
  731. /// </summary>
  732. private void CopyWearablesAndAttachments(UUID destination, UUID source, AvatarAppearance avatarAppearance)
  733. {
  734. AvatarWearable[] wearables = avatarAppearance.Wearables;
  735. if(wearables.Length == 0)
  736. throw new Exception("Model does not have wearables");
  737. // Get Clothing folder of receiver
  738. InventoryFolderBase destinationFolder = m_InventoryService.GetFolderForType(destination, FolderType.Clothing);
  739. if (destinationFolder == null)
  740. throw new Exception("Cannot locate new clothing folder(s)");
  741. // Get Current Outfit folder
  742. InventoryFolderBase currentOutfitFolder = m_InventoryService.GetFolderForType(destination, FolderType.CurrentOutfit);
  743. // wrong destination folder type? create new
  744. if (destinationFolder.Type != (short)FolderType.Clothing)
  745. {
  746. destinationFolder = new InventoryFolderBase();
  747. destinationFolder.ID = UUID.Random();
  748. destinationFolder.Name = "Clothing";
  749. destinationFolder.Owner = destination;
  750. destinationFolder.Type = (short)AssetType.Clothing;
  751. destinationFolder.ParentID = m_InventoryService.GetRootFolder(destination).ID;
  752. destinationFolder.Version = 1;
  753. m_InventoryService.AddFolder(destinationFolder); // store base record
  754. m_log.ErrorFormat("[USER ACCOUNT SERVICE]: Created folder for destination {0} Clothing", source);
  755. }
  756. // Wearables
  757. AvatarWearable basewearable;
  758. WearableItem wearable;
  759. AvatarWearable newbasewearable = new AvatarWearable();
  760. // copy wearables creating new inventory entries
  761. for (int i = 0; i < wearables.Length; i++)
  762. {
  763. basewearable = wearables[i];
  764. if(basewearable == null || basewearable.Count == 0)
  765. continue;
  766. newbasewearable.Clear();
  767. for(int j = 0; j < basewearable.Count; j++)
  768. {
  769. wearable = basewearable[j];
  770. if (wearable.ItemID != UUID.Zero)
  771. {
  772. m_log.DebugFormat("[XXX]: Getting item {0} from avie {1} for {2} {3}",
  773. wearable.ItemID, source, i, j);
  774. // Get inventory item and copy it
  775. InventoryItemBase item = m_InventoryService.GetItem(source, wearable.ItemID);
  776. if(item != null && item.AssetType == (int)AssetType.Link)
  777. {
  778. if(item.AssetID == UUID.Zero )
  779. item = null;
  780. else
  781. item = m_InventoryService.GetItem(source, item.AssetID);
  782. }
  783. if (item != null)
  784. {
  785. InventoryItemBase destinationItem = new InventoryItemBase(UUID.Random(), destination);
  786. destinationItem.Name = item.Name;
  787. destinationItem.Owner = destination;
  788. destinationItem.Description = item.Description;
  789. destinationItem.InvType = item.InvType;
  790. destinationItem.CreatorId = item.CreatorId;
  791. destinationItem.CreatorData = item.CreatorData;
  792. destinationItem.NextPermissions = item.NextPermissions;
  793. destinationItem.CurrentPermissions = item.CurrentPermissions;
  794. destinationItem.BasePermissions = item.BasePermissions;
  795. destinationItem.EveryOnePermissions = item.EveryOnePermissions;
  796. destinationItem.GroupPermissions = item.GroupPermissions;
  797. destinationItem.AssetType = item.AssetType;
  798. destinationItem.AssetID = item.AssetID;
  799. destinationItem.GroupID = item.GroupID;
  800. destinationItem.GroupOwned = item.GroupOwned;
  801. destinationItem.SalePrice = item.SalePrice;
  802. destinationItem.SaleType = item.SaleType;
  803. destinationItem.Flags = item.Flags;
  804. destinationItem.CreationDate = item.CreationDate;
  805. destinationItem.Folder = destinationFolder.ID;
  806. ApplyNextOwnerPermissions(destinationItem);
  807. m_InventoryService.AddItem(destinationItem);
  808. m_log.DebugFormat("[USER ACCOUNT SERVICE]: Added item {0} to folder {1}", destinationItem.ID, destinationFolder.ID);
  809. // Wear item
  810. newbasewearable.Add(destinationItem.ID,wearable.AssetID);
  811. // Add to Current Outfit
  812. CreateCurrentOutfitLink((int)InventoryType.Wearable, item.Flags, item.Name, destinationItem.ID, destination, currentOutfitFolder.ID);
  813. }
  814. else
  815. {
  816. m_log.WarnFormat("[USER ACCOUNT SERVICE]: Error transferring {0} to folder {1}", wearable.ItemID, destinationFolder.ID);
  817. }
  818. }
  819. }
  820. avatarAppearance.SetWearable(i, newbasewearable);
  821. }
  822. // Attachments
  823. List<AvatarAttachment> attachments = avatarAppearance.GetAttachments();
  824. avatarAppearance.ClearAttachments();
  825. foreach (AvatarAttachment attachment in attachments)
  826. {
  827. int attachpoint = attachment.AttachPoint;
  828. UUID itemID = attachment.ItemID;
  829. if (itemID != UUID.Zero)
  830. {
  831. // Get inventory item and copy it
  832. InventoryItemBase item = m_InventoryService.GetItem(source, itemID);
  833. if (item != null)
  834. {
  835. InventoryItemBase destinationItem = new InventoryItemBase(UUID.Random(), destination);
  836. destinationItem.Name = item.Name;
  837. destinationItem.Owner = destination;
  838. destinationItem.Description = item.Description;
  839. destinationItem.InvType = item.InvType;
  840. destinationItem.CreatorId = item.CreatorId;
  841. destinationItem.CreatorData = item.CreatorData;
  842. destinationItem.NextPermissions = item.NextPermissions;
  843. destinationItem.CurrentPermissions = item.CurrentPermissions;
  844. destinationItem.BasePermissions = item.BasePermissions;
  845. destinationItem.EveryOnePermissions = item.EveryOnePermissions;
  846. destinationItem.GroupPermissions = item.GroupPermissions;
  847. destinationItem.AssetType = item.AssetType;
  848. destinationItem.AssetID = item.AssetID;
  849. destinationItem.GroupID = item.GroupID;
  850. destinationItem.GroupOwned = item.GroupOwned;
  851. destinationItem.SalePrice = item.SalePrice;
  852. destinationItem.SaleType = item.SaleType;
  853. destinationItem.Flags = item.Flags;
  854. destinationItem.CreationDate = item.CreationDate;
  855. destinationItem.Folder = destinationFolder.ID;
  856. ApplyNextOwnerPermissions(destinationItem);
  857. m_InventoryService.AddItem(destinationItem);
  858. m_log.DebugFormat("[USER ACCOUNT SERVICE]: Added item {0} to folder {1}", destinationItem.ID, destinationFolder.ID);
  859. // Attach item
  860. avatarAppearance.SetAttachment(attachpoint, destinationItem.ID, destinationItem.AssetID);
  861. m_log.DebugFormat("[USER ACCOUNT SERVICE]: Attached {0}", destinationItem.ID);
  862. // Add to Current Outfit
  863. CreateCurrentOutfitLink(destinationItem.InvType, item.Flags, item.Name, destinationItem.ID, destination, currentOutfitFolder.ID);
  864. }
  865. else
  866. {
  867. m_log.WarnFormat("[USER ACCOUNT SERVICE]: Error transferring {0} to folder {1}", itemID, destinationFolder.ID);
  868. }
  869. }
  870. }
  871. }
  872. protected void CreateCurrentOutfitLink(int invType, uint itemType, string name, UUID itemID, UUID userID, UUID currentOutfitFolderUUID)
  873. {
  874. UUID LinkInvItem = UUID.Random();
  875. InventoryItemBase itembase = new InventoryItemBase(LinkInvItem, userID)
  876. {
  877. AssetID = itemID,
  878. AssetType = (int)AssetType.Link,
  879. CreatorId = userID.ToString(),
  880. InvType = invType,
  881. Description = "",
  882. //Folder = m_InventoryService.GetFolderForType(userID, FolderType.CurrentOutfit).ID,
  883. Folder = currentOutfitFolderUUID,
  884. Flags = itemType,
  885. Name = name,
  886. BasePermissions = (uint)PermissionMask.Copy,
  887. CurrentPermissions = (uint)PermissionMask.Copy,
  888. EveryOnePermissions = (uint)PermissionMask.Copy,
  889. GroupPermissions = (uint)PermissionMask.Copy,
  890. NextPermissions = (uint)PermissionMask.Copy
  891. };
  892. m_InventoryService.AddItem(itembase);
  893. }
  894. /// <summary>
  895. /// Apply next owner permissions.
  896. /// </summary>
  897. private void ApplyNextOwnerPermissions(InventoryItemBase item)
  898. {
  899. if (item.InvType == (int)InventoryType.Object)
  900. {
  901. uint perms = item.CurrentPermissions;
  902. item.CurrentPermissions = perms;
  903. }
  904. item.CurrentPermissions &= item.NextPermissions;
  905. item.BasePermissions &= item.NextPermissions;
  906. item.EveryOnePermissions &= item.NextPermissions;
  907. }
  908. }
  909. }