mirror of
https://github.com/opensim/opensim.git
synced 2026-05-27 20:35:59 +08:00
set in the target's UserFlags and the impersonator must have UserLevel 200 or above. The user can then log in using the target's name and their own password.
440 lines
18 KiB
C#
440 lines
18 KiB
C#
/*
|
|
* 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<IGridService>(gridServiceDll, new Object[] { config });
|
|
|
|
string authServiceDll = userConfig.GetString("AuthenticationService", string.Empty);
|
|
if (authServiceDll != string.Empty)
|
|
m_AuthenticationService = LoadPlugin<IAuthenticationService>(authServiceDll, new Object[] { config });
|
|
|
|
string presenceServiceDll = userConfig.GetString("GridUserService", string.Empty);
|
|
if (presenceServiceDll != string.Empty)
|
|
m_GridUserService = LoadPlugin<IGridUserService>(presenceServiceDll, new Object[] { config });
|
|
|
|
string invServiceDll = userConfig.GetString("InventoryService", string.Empty);
|
|
if (invServiceDll != string.Empty)
|
|
m_InventoryService = LoadPlugin<IInventoryService>(invServiceDll, new Object[] { config });
|
|
|
|
if (MainConsole.Instance != null)
|
|
{
|
|
MainConsole.Instance.Commands.AddCommand("UserService", false,
|
|
"create user",
|
|
"create user [<first> [<last> [<pass> [<email>]]]]",
|
|
"Create a new user", HandleCreateUser);
|
|
MainConsole.Instance.Commands.AddCommand("UserService", false, "reset user password",
|
|
"reset user password [<first> [<last> [<password>]]]",
|
|
"Reset a user password", HandleResetUserPassword);
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#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("ServiceURLs") && d.Data["ServiceURLs"] != null)
|
|
{
|
|
string[] URLs = d.Data["ServiceURLs"].ToString().Split(new char[] { ' ' });
|
|
u.ServiceURLs = new Dictionary<string, object>();
|
|
|
|
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<string, object>();
|
|
|
|
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<string, string>();
|
|
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<string> parts = new List<string>();
|
|
|
|
foreach (KeyValuePair<string, object> 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<UserAccount> GetUserAccounts(UUID scopeID, string query)
|
|
{
|
|
UserAccountData[] d = m_Database.GetUsers(scopeID, query);
|
|
|
|
if (d == null)
|
|
return new List<UserAccount>();
|
|
|
|
List<UserAccount> ret = new List<UserAccount>();
|
|
|
|
foreach (UserAccountData data in d)
|
|
ret.Add(MakeUserAccount(data));
|
|
|
|
return ret;
|
|
}
|
|
|
|
public List<UserAccount> GetUserAccountsWhere(UUID scopeID, string where)
|
|
{
|
|
UserAccountData[] d = m_Database.GetUsersWhere(scopeID, where);
|
|
|
|
if (d == null)
|
|
return new List<UserAccount>();
|
|
|
|
List<UserAccount> ret = new List<UserAccount>();
|
|
|
|
foreach (UserAccountData data in d)
|
|
ret.Add(MakeUserAccount(data));
|
|
|
|
return ret;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Console commands
|
|
|
|
/// <summary>
|
|
/// Handle the create user command from the console.
|
|
/// </summary>
|
|
/// <param name="cmdparams">string array with parameters: firstname, lastname, password, locationX, locationY, email</param>
|
|
protected void HandleCreateUser(string module, string[] cmdparams)
|
|
{
|
|
string firstName;
|
|
string lastName;
|
|
string password;
|
|
string email;
|
|
|
|
List<char> excluded = new List<char>(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 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)
|
|
m_log.ErrorFormat("[USER ACCOUNT SERVICE]: No such user");
|
|
|
|
bool success = false;
|
|
if (m_AuthenticationService != null)
|
|
success = m_AuthenticationService.SetPassword(account.PrincipalID, newPassword);
|
|
if (!success)
|
|
m_log.ErrorFormat("[USER ACCOUNT SERVICE]: Unable to reset password for account {0} {1}.",
|
|
firstName, lastName);
|
|
else
|
|
m_log.InfoFormat("[USER ACCOUNT SERVICE]: Password reset for user {0} {1}", firstName, lastName);
|
|
}
|
|
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// Create a user
|
|
/// </summary>
|
|
/// <param name="firstName"></param>
|
|
/// <param name="lastName"></param>
|
|
/// <param name="password"></param>
|
|
/// <param name="email"></param>
|
|
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<string, object>();
|
|
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<GridRegion> 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);
|
|
}
|
|
}
|
|
}
|
|
}
|