/* * Copyright (c) Contributors, http://opensimulator.org/ * See CONTRIBUTORS.TXT for a full list of copyright holders. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of the OpenSimulator Project nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ using System; using System.Collections.Generic; using System.Reflection; using Nini.Config; using OpenSim.Data; using OpenSim.Services.Interfaces; using OpenSim.Framework.Console; using GridRegion = OpenSim.Services.Interfaces.GridRegion; using OpenMetaverse; using log4net; namespace OpenSim.Services.UserAccountService { public class UserAccountService : UserAccountServiceBase, IUserAccountService { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static UserAccountService m_RootInstance; protected IGridService m_GridService; protected IAuthenticationService m_AuthenticationService; protected IGridUserService m_GridUserService; protected IInventoryService m_InventoryService; public UserAccountService(IConfigSource config) : base(config) { IConfig userConfig = config.Configs["UserAccountService"]; if (userConfig == null) throw new Exception("No UserAccountService configuration"); // In case there are several instances of this class in the same process, // the console commands are only registered for the root instance if (m_RootInstance == null) { m_RootInstance = this; string gridServiceDll = userConfig.GetString("GridService", string.Empty); if (gridServiceDll != string.Empty) m_GridService = LoadPlugin(gridServiceDll, new Object[] { config }); string authServiceDll = userConfig.GetString("AuthenticationService", string.Empty); if (authServiceDll != string.Empty) m_AuthenticationService = LoadPlugin(authServiceDll, new Object[] { config }); string presenceServiceDll = userConfig.GetString("GridUserService", string.Empty); if (presenceServiceDll != string.Empty) m_GridUserService = LoadPlugin(presenceServiceDll, new Object[] { config }); string invServiceDll = userConfig.GetString("InventoryService", string.Empty); if (invServiceDll != string.Empty) m_InventoryService = LoadPlugin(invServiceDll, new Object[] { config }); if (MainConsole.Instance != null) { MainConsole.Instance.Commands.AddCommand("UserService", false, "create user", "create user [ [ [ []]]]", "Create a new user", HandleCreateUser); MainConsole.Instance.Commands.AddCommand("UserService", false, "reset user password", "reset user password [ [ []]]", "Reset a user password", HandleResetUserPassword); MainConsole.Instance.Commands.AddCommand("UserService", false, "set user level", "set user level [ [ []]]", "Set user level. If >= 200 and 'allow_grid_gods = true' in OpenSim.ini, " + "this account will be treated as god-moded. " + "It will also affect the 'login level' command. ", HandleSetUserLevel); MainConsole.Instance.Commands.AddCommand("UserService", false, "show account", "show account ", "Show account details for the given user", HandleShowAccount); } } } #region IUserAccountService public UserAccount GetUserAccount(UUID scopeID, string firstName, string lastName) { // m_log.DebugFormat( // "[USER ACCOUNT SERVICE]: Retrieving account by username for {0} {1}, scope {2}", // firstName, lastName, scopeID); UserAccountData[] d; if (scopeID != UUID.Zero) { d = m_Database.Get( new string[] { "ScopeID", "FirstName", "LastName" }, new string[] { scopeID.ToString(), firstName, lastName }); if (d.Length < 1) { d = m_Database.Get( new string[] { "ScopeID", "FirstName", "LastName" }, new string[] { UUID.Zero.ToString(), firstName, lastName }); } } else { d = m_Database.Get( new string[] { "FirstName", "LastName" }, new string[] { firstName, lastName }); } if (d.Length < 1) return null; return MakeUserAccount(d[0]); } private UserAccount MakeUserAccount(UserAccountData d) { UserAccount u = new UserAccount(); u.FirstName = d.FirstName; u.LastName = d.LastName; u.PrincipalID = d.PrincipalID; u.ScopeID = d.ScopeID; if (d.Data.ContainsKey("Email") && d.Data["Email"] != null) u.Email = d.Data["Email"].ToString(); else u.Email = string.Empty; u.Created = Convert.ToInt32(d.Data["Created"].ToString()); if (d.Data.ContainsKey("UserTitle") && d.Data["UserTitle"] != null) u.UserTitle = d.Data["UserTitle"].ToString(); else u.UserTitle = string.Empty; if (d.Data.ContainsKey("UserLevel") && d.Data["UserLevel"] != null) Int32.TryParse(d.Data["UserLevel"], out u.UserLevel); if (d.Data.ContainsKey("UserFlags") && d.Data["UserFlags"] != null) Int32.TryParse(d.Data["UserFlags"], out u.UserFlags); if (d.Data.ContainsKey("UserCountry") && d.Data["UserCountry"] != null) u.UserCountry = d.Data["UserCountry"].ToString(); else u.UserTitle = string.Empty; if (d.Data.ContainsKey("ServiceURLs") && d.Data["ServiceURLs"] != null) { string[] URLs = d.Data["ServiceURLs"].ToString().Split(new char[] { ' ' }); u.ServiceURLs = new Dictionary(); foreach (string url in URLs) { string[] parts = url.Split(new char[] { '=' }); if (parts.Length != 2) continue; string name = System.Web.HttpUtility.UrlDecode(parts[0]); string val = System.Web.HttpUtility.UrlDecode(parts[1]); u.ServiceURLs[name] = val; } } else u.ServiceURLs = new Dictionary(); return u; } public UserAccount GetUserAccount(UUID scopeID, string email) { UserAccountData[] d; if (scopeID != UUID.Zero) { d = m_Database.Get( new string[] { "ScopeID", "Email" }, new string[] { scopeID.ToString(), email }); if (d.Length < 1) { d = m_Database.Get( new string[] { "ScopeID", "Email" }, new string[] { UUID.Zero.ToString(), email }); } } else { d = m_Database.Get( new string[] { "Email" }, new string[] { email }); } if (d.Length < 1) return null; return MakeUserAccount(d[0]); } public UserAccount GetUserAccount(UUID scopeID, UUID principalID) { UserAccountData[] d; if (scopeID != UUID.Zero) { d = m_Database.Get( new string[] { "ScopeID", "PrincipalID" }, new string[] { scopeID.ToString(), principalID.ToString() }); if (d.Length < 1) { d = m_Database.Get( new string[] { "ScopeID", "PrincipalID" }, new string[] { UUID.Zero.ToString(), principalID.ToString() }); } } else { d = m_Database.Get( new string[] { "PrincipalID" }, new string[] { principalID.ToString() }); } if (d.Length < 1) { return null; } return MakeUserAccount(d[0]); } public bool StoreUserAccount(UserAccount data) { // m_log.DebugFormat( // "[USER ACCOUNT SERVICE]: Storing user account for {0} {1} {2}, scope {3}", // data.FirstName, data.LastName, data.PrincipalID, data.ScopeID); UserAccountData d = new UserAccountData(); d.FirstName = data.FirstName; d.LastName = data.LastName; d.PrincipalID = data.PrincipalID; d.ScopeID = data.ScopeID; d.Data = new Dictionary(); d.Data["Email"] = data.Email; d.Data["Created"] = data.Created.ToString(); d.Data["UserLevel"] = data.UserLevel.ToString(); d.Data["UserFlags"] = data.UserFlags.ToString(); if (data.UserTitle != null) d.Data["UserTitle"] = data.UserTitle.ToString(); List parts = new List(); foreach (KeyValuePair kvp in data.ServiceURLs) { string key = System.Web.HttpUtility.UrlEncode(kvp.Key); string val = System.Web.HttpUtility.UrlEncode(kvp.Value.ToString()); parts.Add(key + "=" + val); } d.Data["ServiceURLs"] = string.Join(" ", parts.ToArray()); return m_Database.Store(d); } public List GetUserAccounts(UUID scopeID, string query) { UserAccountData[] d = m_Database.GetUsers(scopeID, query.Trim()); if (d == null) return new List(); List ret = new List(); foreach (UserAccountData data in d) ret.Add(MakeUserAccount(data)); return ret; } public List GetUserAccountsWhere(UUID scopeID, string where) { UserAccountData[] d = m_Database.GetUsersWhere(scopeID, where); if (d == null) return new List(); List ret = new List(); foreach (UserAccountData data in d) ret.Add(MakeUserAccount(data)); return ret; } #endregion #region Console commands /// /// Handle the create user command from the console. /// /// string array with parameters: firstname, lastname, password, locationX, locationY, email protected void HandleCreateUser(string module, string[] cmdparams) { string firstName; string lastName; string password; string email; List excluded = new List(new char[]{' '}); if (cmdparams.Length < 3) firstName = MainConsole.Instance.CmdPrompt("First name", "Default", excluded); else firstName = cmdparams[2]; if (cmdparams.Length < 4) lastName = MainConsole.Instance.CmdPrompt("Last name", "User", excluded); else lastName = cmdparams[3]; if (cmdparams.Length < 5) password = MainConsole.Instance.PasswdPrompt("Password"); else password = cmdparams[4]; if (cmdparams.Length < 6) email = MainConsole.Instance.CmdPrompt("Email", ""); else email = cmdparams[5]; CreateUser(firstName, lastName, password, email); } protected void HandleShowAccount(string module, string[] cmdparams) { if (cmdparams.Length != 4) { MainConsole.Instance.Output("Usage: show account "); return; } string firstName = cmdparams[2]; string lastName = cmdparams[3]; UserAccount ua = GetUserAccount(UUID.Zero, firstName, lastName); if (ua == null) { MainConsole.Instance.OutputFormat("No user named {0} {1}", firstName, lastName); return; } MainConsole.Instance.OutputFormat("Name: {0}", ua.Name); MainConsole.Instance.OutputFormat("ID: {0}", ua.PrincipalID); MainConsole.Instance.OutputFormat("Title: {0}", ua.UserTitle); MainConsole.Instance.OutputFormat("E-mail: {0}", ua.Email); MainConsole.Instance.OutputFormat("Created: {0}", Utils.UnixTimeToDateTime(ua.Created)); MainConsole.Instance.OutputFormat("Level: {0}", ua.UserLevel); MainConsole.Instance.OutputFormat("Flags: {0}", ua.UserFlags); foreach (KeyValuePair kvp in ua.ServiceURLs) MainConsole.Instance.OutputFormat("{0}: {1}", kvp.Key, kvp.Value); } protected void HandleResetUserPassword(string module, string[] cmdparams) { string firstName; string lastName; string newPassword; if (cmdparams.Length < 4) firstName = MainConsole.Instance.CmdPrompt("First name"); else firstName = cmdparams[3]; if (cmdparams.Length < 5) lastName = MainConsole.Instance.CmdPrompt("Last name"); else lastName = cmdparams[4]; if (cmdparams.Length < 6) newPassword = MainConsole.Instance.PasswdPrompt("New password"); else newPassword = cmdparams[5]; UserAccount account = GetUserAccount(UUID.Zero, firstName, lastName); if (account == null) { MainConsole.Instance.OutputFormat("No such user as {0} {1}", firstName, lastName); return; } bool success = false; if (m_AuthenticationService != null) success = m_AuthenticationService.SetPassword(account.PrincipalID, newPassword); if (!success) MainConsole.Instance.OutputFormat("Unable to reset password for account {0} {1}.", firstName, lastName); else MainConsole.Instance.OutputFormat("Password reset for user {0} {1}", firstName, lastName); } protected void HandleSetUserLevel(string module, string[] cmdparams) { string firstName; string lastName; string rawLevel; int level; if (cmdparams.Length < 4) firstName = MainConsole.Instance.CmdPrompt("First name"); else firstName = cmdparams[3]; if (cmdparams.Length < 5) lastName = MainConsole.Instance.CmdPrompt("Last name"); else lastName = cmdparams[4]; UserAccount account = GetUserAccount(UUID.Zero, firstName, lastName); if (account == null) { MainConsole.Instance.OutputFormat("No such user"); return; } if (cmdparams.Length < 6) rawLevel = MainConsole.Instance.CmdPrompt("User level"); else rawLevel = cmdparams[5]; if(int.TryParse(rawLevel, out level) == false) { MainConsole.Instance.OutputFormat("Invalid user level"); return; } account.UserLevel = level; bool success = StoreUserAccount(account); if (!success) MainConsole.Instance.OutputFormat("Unable to set user level for account {0} {1}.", firstName, lastName); else MainConsole.Instance.OutputFormat("User level set for user {0} {1} to {2}", firstName, lastName, level); } #endregion /// /// Create a user /// /// /// /// /// private void CreateUser(string firstName, string lastName, string password, string email) { UserAccount account = GetUserAccount(UUID.Zero, firstName, lastName); if (null == account) { account = new UserAccount(UUID.Zero, firstName, lastName, email); if (account.ServiceURLs == null || (account.ServiceURLs != null && account.ServiceURLs.Count == 0)) { account.ServiceURLs = new Dictionary(); account.ServiceURLs["HomeURI"] = string.Empty; account.ServiceURLs["GatekeeperURI"] = string.Empty; account.ServiceURLs["InventoryServerURI"] = string.Empty; account.ServiceURLs["AssetServerURI"] = string.Empty; } if (StoreUserAccount(account)) { bool success; if (m_AuthenticationService != null) { success = m_AuthenticationService.SetPassword(account.PrincipalID, password); if (!success) m_log.WarnFormat("[USER ACCOUNT SERVICE]: Unable to set password for account {0} {1}.", firstName, lastName); } GridRegion home = null; if (m_GridService != null) { List defaultRegions = m_GridService.GetDefaultRegions(UUID.Zero); if (defaultRegions != null && defaultRegions.Count >= 1) home = defaultRegions[0]; if (m_GridUserService != null && home != null) m_GridUserService.SetHome(account.PrincipalID.ToString(), home.RegionID, new Vector3(128, 128, 0), new Vector3(0, 1, 0)); else m_log.WarnFormat("[USER ACCOUNT SERVICE]: Unable to set home for account {0} {1}.", firstName, lastName); } else m_log.WarnFormat("[USER ACCOUNT SERVICE]: Unable to retrieve home region for account {0} {1}.", firstName, lastName); if (m_InventoryService != null) { success = m_InventoryService.CreateUserInventory(account.PrincipalID); if (!success) m_log.WarnFormat("[USER ACCOUNT SERVICE]: Unable to create inventory for account {0} {1}.", firstName, lastName); } m_log.InfoFormat("[USER ACCOUNT SERVICE]: Account {0} {1} created successfully", firstName, lastName); } else { m_log.ErrorFormat("[USER ACCOUNT SERVICE]: Account creation failed for account {0} {1}", firstName, lastName); } } else { m_log.ErrorFormat("[USER ACCOUNT SERVICE]: A user with the name {0} {1} already exists!", firstName, lastName); } } } }