mirror of
https://github.com/opensim/opensim.git
synced 2026-08-06 09:16:28 +08:00
First step in separating out the Userserver console command handling to a "module".
Added OpenSim.Grid.UserServer.Modules project/dll which now contains the components of the userserver. With the OpenSim.Grid.UserServer being the setup and initiate exe.
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1,337 +1,337 @@
|
||||
/*
|
||||
* 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 OpenSim 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.Collections.Specialized;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Web;
|
||||
using DotNetOpenId;
|
||||
using DotNetOpenId.Provider;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Servers;
|
||||
|
||||
namespace OpenSim.Grid.UserServer
|
||||
{
|
||||
/// <summary>
|
||||
/// Temporary, in-memory store for OpenID associations
|
||||
/// </summary>
|
||||
public class ProviderMemoryStore : IAssociationStore<AssociationRelyingPartyType>
|
||||
{
|
||||
private class AssociationItem
|
||||
{
|
||||
public AssociationRelyingPartyType DistinguishingFactor;
|
||||
public string Handle;
|
||||
public DateTime Expires;
|
||||
public byte[] PrivateData;
|
||||
}
|
||||
|
||||
Dictionary<string, AssociationItem> m_store = new Dictionary<string, AssociationItem>();
|
||||
SortedList<DateTime, AssociationItem> m_sortedStore = new SortedList<DateTime, AssociationItem>();
|
||||
object m_syncRoot = new object();
|
||||
|
||||
#region IAssociationStore<AssociationRelyingPartyType> Members
|
||||
|
||||
public void StoreAssociation(AssociationRelyingPartyType distinguishingFactor, Association assoc)
|
||||
{
|
||||
AssociationItem item = new AssociationItem();
|
||||
item.DistinguishingFactor = distinguishingFactor;
|
||||
item.Handle = assoc.Handle;
|
||||
item.Expires = assoc.Expires.ToLocalTime();
|
||||
item.PrivateData = assoc.SerializePrivateData();
|
||||
|
||||
lock (m_syncRoot)
|
||||
{
|
||||
m_store[item.Handle] = item;
|
||||
m_sortedStore[item.Expires] = item;
|
||||
}
|
||||
}
|
||||
|
||||
public Association GetAssociation(AssociationRelyingPartyType distinguishingFactor)
|
||||
{
|
||||
lock (m_syncRoot)
|
||||
{
|
||||
if (m_sortedStore.Count > 0)
|
||||
{
|
||||
AssociationItem item = m_sortedStore.Values[m_sortedStore.Count - 1];
|
||||
return Association.Deserialize(item.Handle, item.Expires.ToUniversalTime(), item.PrivateData);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Association GetAssociation(AssociationRelyingPartyType distinguishingFactor, string handle)
|
||||
{
|
||||
AssociationItem item;
|
||||
bool success = false;
|
||||
lock (m_syncRoot)
|
||||
success = m_store.TryGetValue(handle, out item);
|
||||
|
||||
if (success)
|
||||
return Association.Deserialize(item.Handle, item.Expires.ToUniversalTime(), item.PrivateData);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool RemoveAssociation(AssociationRelyingPartyType distinguishingFactor, string handle)
|
||||
{
|
||||
lock (m_syncRoot)
|
||||
{
|
||||
for (int i = 0; i < m_sortedStore.Values.Count; i++)
|
||||
{
|
||||
AssociationItem item = m_sortedStore.Values[i];
|
||||
if (item.Handle == handle)
|
||||
{
|
||||
m_sortedStore.RemoveAt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return m_store.Remove(handle);
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearExpiredAssociations()
|
||||
{
|
||||
lock (m_syncRoot)
|
||||
{
|
||||
List<AssociationItem> itemsCopy = new List<AssociationItem>(m_sortedStore.Values);
|
||||
DateTime now = DateTime.Now;
|
||||
|
||||
for (int i = 0; i < itemsCopy.Count; i++)
|
||||
{
|
||||
AssociationItem item = itemsCopy[i];
|
||||
|
||||
if (item.Expires <= now)
|
||||
{
|
||||
m_sortedStore.RemoveAt(i);
|
||||
m_store.Remove(item.Handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class OpenIdStreamHandler : IStreamHandler
|
||||
{
|
||||
#region HTML
|
||||
|
||||
/// <summary>Login form used to authenticate OpenID requests</summary>
|
||||
const string LOGIN_PAGE =
|
||||
@"<html>
|
||||
<head><title>OpenSim OpenID Login</title></head>
|
||||
<body>
|
||||
<h3>OpenSim Login</h3>
|
||||
<form method=""post"">
|
||||
<label for=""first"">First Name:</label> <input readonly type=""text"" name=""first"" id=""first"" value=""{0}""/>
|
||||
<label for=""last"">Last Name:</label> <input readonly type=""text"" name=""last"" id=""last"" value=""{1}""/>
|
||||
<label for=""pass"">Password:</label> <input type=""password"" name=""pass"" id=""pass""/>
|
||||
<input type=""submit"" value=""Login"">
|
||||
</form>
|
||||
</body>
|
||||
</html>";
|
||||
|
||||
/// <summary>Page shown for a valid OpenID identity</summary>
|
||||
const string OPENID_PAGE =
|
||||
@"<html>
|
||||
<head>
|
||||
<title>{2} {3}</title>
|
||||
<link rel=""openid2.provider openid.server"" href=""{0}://{1}/openid/server/""/>
|
||||
</head>
|
||||
<body>OpenID identifier for {2} {3}</body>
|
||||
</html>
|
||||
";
|
||||
|
||||
/// <summary>Page shown for an invalid OpenID identity</summary>
|
||||
const string INVALID_OPENID_PAGE =
|
||||
@"<html><head><title>Identity not found</title></head>
|
||||
<body>Invalid OpenID identity</body></html>";
|
||||
|
||||
/// <summary>Page shown if the OpenID endpoint is requested directly</summary>
|
||||
const string ENDPOINT_PAGE =
|
||||
@"<html><head><title>OpenID Endpoint</title></head><body>
|
||||
This is an OpenID server endpoint, not a human-readable resource.
|
||||
For more information, see <a href='http://openid.net/'>http://openid.net/</a>.
|
||||
</body></html>";
|
||||
|
||||
#endregion HTML
|
||||
|
||||
public string ContentType { get { return m_contentType; } }
|
||||
public string HttpMethod { get { return m_httpMethod; } }
|
||||
public string Path { get { return m_path; } }
|
||||
|
||||
string m_contentType;
|
||||
string m_httpMethod;
|
||||
string m_path;
|
||||
UserLoginService m_loginService;
|
||||
ProviderMemoryStore m_openidStore = new ProviderMemoryStore();
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
public OpenIdStreamHandler(string httpMethod, string path, UserLoginService loginService)
|
||||
{
|
||||
m_loginService = loginService;
|
||||
m_httpMethod = httpMethod;
|
||||
m_path = path;
|
||||
|
||||
m_contentType = "text/html";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles all GET and POST requests for OpenID identifier pages and endpoint
|
||||
/// server communication
|
||||
/// </summary>
|
||||
public void Handle(string path, Stream request, Stream response, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
|
||||
{
|
||||
Uri providerEndpoint = new Uri(String.Format("{0}://{1}{2}", httpRequest.Url.Scheme, httpRequest.Url.Authority, httpRequest.Url.AbsolutePath));
|
||||
|
||||
// Defult to returning HTML content
|
||||
m_contentType = "text/html";
|
||||
|
||||
try
|
||||
{
|
||||
NameValueCollection postQuery = HttpUtility.ParseQueryString(new StreamReader(httpRequest.InputStream).ReadToEnd());
|
||||
NameValueCollection getQuery = HttpUtility.ParseQueryString(httpRequest.Url.Query);
|
||||
NameValueCollection openIdQuery = (postQuery.GetValues("openid.mode") != null ? postQuery : getQuery);
|
||||
|
||||
OpenIdProvider provider = new OpenIdProvider(m_openidStore, providerEndpoint, httpRequest.Url, openIdQuery);
|
||||
|
||||
if (provider.Request != null)
|
||||
{
|
||||
if (!provider.Request.IsResponseReady && provider.Request is IAuthenticationRequest)
|
||||
{
|
||||
IAuthenticationRequest authRequest = (IAuthenticationRequest)provider.Request;
|
||||
string[] passwordValues = postQuery.GetValues("pass");
|
||||
|
||||
UserProfileData profile;
|
||||
if (TryGetProfile(new Uri(authRequest.ClaimedIdentifier.ToString()), out profile))
|
||||
{
|
||||
// Check for form POST data
|
||||
if (passwordValues != null && passwordValues.Length == 1)
|
||||
{
|
||||
if (profile != null && m_loginService.AuthenticateUser(profile, passwordValues[0]))
|
||||
authRequest.IsAuthenticated = true;
|
||||
else
|
||||
authRequest.IsAuthenticated = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Authentication was requested, send the client a login form
|
||||
using (StreamWriter writer = new StreamWriter(response))
|
||||
writer.Write(String.Format(LOGIN_PAGE, profile.FirstName, profile.SurName));
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Cannot find an avatar matching the claimed identifier
|
||||
authRequest.IsAuthenticated = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Add OpenID headers to the response
|
||||
foreach (string key in provider.Request.Response.Headers.Keys)
|
||||
httpResponse.AddHeader(key, provider.Request.Response.Headers[key]);
|
||||
|
||||
string[] contentTypeValues = provider.Request.Response.Headers.GetValues("Content-Type");
|
||||
if (contentTypeValues != null && contentTypeValues.Length == 1)
|
||||
m_contentType = contentTypeValues[0];
|
||||
|
||||
// Set the response code and document body based on the OpenID result
|
||||
httpResponse.StatusCode = (int)provider.Request.Response.Code;
|
||||
response.Write(provider.Request.Response.Body, 0, provider.Request.Response.Body.Length);
|
||||
response.Close();
|
||||
}
|
||||
else if (httpRequest.Url.AbsolutePath.Contains("/openid/server"))
|
||||
{
|
||||
// Standard HTTP GET was made on the OpenID endpoint, send the client the default error page
|
||||
using (StreamWriter writer = new StreamWriter(response))
|
||||
writer.Write(ENDPOINT_PAGE);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Try and lookup this avatar
|
||||
UserProfileData profile;
|
||||
if (TryGetProfile(httpRequest.Url, out profile))
|
||||
{
|
||||
using (StreamWriter writer = new StreamWriter(response))
|
||||
{
|
||||
// TODO: Print out a full profile page for this avatar
|
||||
writer.Write(String.Format(OPENID_PAGE, httpRequest.Url.Scheme,
|
||||
httpRequest.Url.Authority, profile.FirstName, profile.SurName));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Couldn't parse an avatar name, or couldn't find the avatar in the user server
|
||||
using (StreamWriter writer = new StreamWriter(response))
|
||||
writer.Write(INVALID_OPENID_PAGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
httpResponse.StatusCode = (int)HttpStatusCode.InternalServerError;
|
||||
using (StreamWriter writer = new StreamWriter(response))
|
||||
writer.Write(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse a URL with a relative path of the form /users/First_Last and try to
|
||||
/// retrieve the profile matching that avatar name
|
||||
/// </summary>
|
||||
/// <param name="requestUrl">URL to parse for an avatar name</param>
|
||||
/// <param name="profile">Profile data for the avatar</param>
|
||||
/// <returns>True if the parse and lookup were successful, otherwise false</returns>
|
||||
bool TryGetProfile(Uri requestUrl, out UserProfileData profile)
|
||||
{
|
||||
if (requestUrl.Segments.Length == 3 && requestUrl.Segments[1] == "users/")
|
||||
{
|
||||
// Parse the avatar name from the path
|
||||
string username = requestUrl.Segments[requestUrl.Segments.Length - 1];
|
||||
string[] name = username.Split('_');
|
||||
|
||||
if (name.Length == 2)
|
||||
{
|
||||
profile = m_loginService.GetTheUser(name[0], name[1]);
|
||||
return (profile != null);
|
||||
}
|
||||
}
|
||||
|
||||
profile = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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 OpenSim 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.Collections.Specialized;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Web;
|
||||
using DotNetOpenId;
|
||||
using DotNetOpenId.Provider;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Servers;
|
||||
|
||||
namespace OpenSim.Grid.UserServer.Modules
|
||||
{
|
||||
/// <summary>
|
||||
/// Temporary, in-memory store for OpenID associations
|
||||
/// </summary>
|
||||
public class ProviderMemoryStore : IAssociationStore<AssociationRelyingPartyType>
|
||||
{
|
||||
private class AssociationItem
|
||||
{
|
||||
public AssociationRelyingPartyType DistinguishingFactor;
|
||||
public string Handle;
|
||||
public DateTime Expires;
|
||||
public byte[] PrivateData;
|
||||
}
|
||||
|
||||
Dictionary<string, AssociationItem> m_store = new Dictionary<string, AssociationItem>();
|
||||
SortedList<DateTime, AssociationItem> m_sortedStore = new SortedList<DateTime, AssociationItem>();
|
||||
object m_syncRoot = new object();
|
||||
|
||||
#region IAssociationStore<AssociationRelyingPartyType> Members
|
||||
|
||||
public void StoreAssociation(AssociationRelyingPartyType distinguishingFactor, Association assoc)
|
||||
{
|
||||
AssociationItem item = new AssociationItem();
|
||||
item.DistinguishingFactor = distinguishingFactor;
|
||||
item.Handle = assoc.Handle;
|
||||
item.Expires = assoc.Expires.ToLocalTime();
|
||||
item.PrivateData = assoc.SerializePrivateData();
|
||||
|
||||
lock (m_syncRoot)
|
||||
{
|
||||
m_store[item.Handle] = item;
|
||||
m_sortedStore[item.Expires] = item;
|
||||
}
|
||||
}
|
||||
|
||||
public Association GetAssociation(AssociationRelyingPartyType distinguishingFactor)
|
||||
{
|
||||
lock (m_syncRoot)
|
||||
{
|
||||
if (m_sortedStore.Count > 0)
|
||||
{
|
||||
AssociationItem item = m_sortedStore.Values[m_sortedStore.Count - 1];
|
||||
return Association.Deserialize(item.Handle, item.Expires.ToUniversalTime(), item.PrivateData);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Association GetAssociation(AssociationRelyingPartyType distinguishingFactor, string handle)
|
||||
{
|
||||
AssociationItem item;
|
||||
bool success = false;
|
||||
lock (m_syncRoot)
|
||||
success = m_store.TryGetValue(handle, out item);
|
||||
|
||||
if (success)
|
||||
return Association.Deserialize(item.Handle, item.Expires.ToUniversalTime(), item.PrivateData);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool RemoveAssociation(AssociationRelyingPartyType distinguishingFactor, string handle)
|
||||
{
|
||||
lock (m_syncRoot)
|
||||
{
|
||||
for (int i = 0; i < m_sortedStore.Values.Count; i++)
|
||||
{
|
||||
AssociationItem item = m_sortedStore.Values[i];
|
||||
if (item.Handle == handle)
|
||||
{
|
||||
m_sortedStore.RemoveAt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return m_store.Remove(handle);
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearExpiredAssociations()
|
||||
{
|
||||
lock (m_syncRoot)
|
||||
{
|
||||
List<AssociationItem> itemsCopy = new List<AssociationItem>(m_sortedStore.Values);
|
||||
DateTime now = DateTime.Now;
|
||||
|
||||
for (int i = 0; i < itemsCopy.Count; i++)
|
||||
{
|
||||
AssociationItem item = itemsCopy[i];
|
||||
|
||||
if (item.Expires <= now)
|
||||
{
|
||||
m_sortedStore.RemoveAt(i);
|
||||
m_store.Remove(item.Handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
public class OpenIdStreamHandler : IStreamHandler
|
||||
{
|
||||
#region HTML
|
||||
|
||||
/// <summary>Login form used to authenticate OpenID requests</summary>
|
||||
const string LOGIN_PAGE =
|
||||
@"<html>
|
||||
<head><title>OpenSim OpenID Login</title></head>
|
||||
<body>
|
||||
<h3>OpenSim Login</h3>
|
||||
<form method=""post"">
|
||||
<label for=""first"">First Name:</label> <input readonly type=""text"" name=""first"" id=""first"" value=""{0}""/>
|
||||
<label for=""last"">Last Name:</label> <input readonly type=""text"" name=""last"" id=""last"" value=""{1}""/>
|
||||
<label for=""pass"">Password:</label> <input type=""password"" name=""pass"" id=""pass""/>
|
||||
<input type=""submit"" value=""Login"">
|
||||
</form>
|
||||
</body>
|
||||
</html>";
|
||||
|
||||
/// <summary>Page shown for a valid OpenID identity</summary>
|
||||
const string OPENID_PAGE =
|
||||
@"<html>
|
||||
<head>
|
||||
<title>{2} {3}</title>
|
||||
<link rel=""openid2.provider openid.server"" href=""{0}://{1}/openid/server/""/>
|
||||
</head>
|
||||
<body>OpenID identifier for {2} {3}</body>
|
||||
</html>
|
||||
";
|
||||
|
||||
/// <summary>Page shown for an invalid OpenID identity</summary>
|
||||
const string INVALID_OPENID_PAGE =
|
||||
@"<html><head><title>Identity not found</title></head>
|
||||
<body>Invalid OpenID identity</body></html>";
|
||||
|
||||
/// <summary>Page shown if the OpenID endpoint is requested directly</summary>
|
||||
const string ENDPOINT_PAGE =
|
||||
@"<html><head><title>OpenID Endpoint</title></head><body>
|
||||
This is an OpenID server endpoint, not a human-readable resource.
|
||||
For more information, see <a href='http://openid.net/'>http://openid.net/</a>.
|
||||
</body></html>";
|
||||
|
||||
#endregion HTML
|
||||
|
||||
public string ContentType { get { return m_contentType; } }
|
||||
public string HttpMethod { get { return m_httpMethod; } }
|
||||
public string Path { get { return m_path; } }
|
||||
|
||||
string m_contentType;
|
||||
string m_httpMethod;
|
||||
string m_path;
|
||||
UserLoginService m_loginService;
|
||||
ProviderMemoryStore m_openidStore = new ProviderMemoryStore();
|
||||
|
||||
/// <summary>
|
||||
/// Constructor
|
||||
/// </summary>
|
||||
public OpenIdStreamHandler(string httpMethod, string path, UserLoginService loginService)
|
||||
{
|
||||
m_loginService = loginService;
|
||||
m_httpMethod = httpMethod;
|
||||
m_path = path;
|
||||
|
||||
m_contentType = "text/html";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Handles all GET and POST requests for OpenID identifier pages and endpoint
|
||||
/// server communication
|
||||
/// </summary>
|
||||
public void Handle(string path, Stream request, Stream response, OSHttpRequest httpRequest, OSHttpResponse httpResponse)
|
||||
{
|
||||
Uri providerEndpoint = new Uri(String.Format("{0}://{1}{2}", httpRequest.Url.Scheme, httpRequest.Url.Authority, httpRequest.Url.AbsolutePath));
|
||||
|
||||
// Defult to returning HTML content
|
||||
m_contentType = "text/html";
|
||||
|
||||
try
|
||||
{
|
||||
NameValueCollection postQuery = HttpUtility.ParseQueryString(new StreamReader(httpRequest.InputStream).ReadToEnd());
|
||||
NameValueCollection getQuery = HttpUtility.ParseQueryString(httpRequest.Url.Query);
|
||||
NameValueCollection openIdQuery = (postQuery.GetValues("openid.mode") != null ? postQuery : getQuery);
|
||||
|
||||
OpenIdProvider provider = new OpenIdProvider(m_openidStore, providerEndpoint, httpRequest.Url, openIdQuery);
|
||||
|
||||
if (provider.Request != null)
|
||||
{
|
||||
if (!provider.Request.IsResponseReady && provider.Request is IAuthenticationRequest)
|
||||
{
|
||||
IAuthenticationRequest authRequest = (IAuthenticationRequest)provider.Request;
|
||||
string[] passwordValues = postQuery.GetValues("pass");
|
||||
|
||||
UserProfileData profile;
|
||||
if (TryGetProfile(new Uri(authRequest.ClaimedIdentifier.ToString()), out profile))
|
||||
{
|
||||
// Check for form POST data
|
||||
if (passwordValues != null && passwordValues.Length == 1)
|
||||
{
|
||||
if (profile != null && m_loginService.AuthenticateUser(profile, passwordValues[0]))
|
||||
authRequest.IsAuthenticated = true;
|
||||
else
|
||||
authRequest.IsAuthenticated = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Authentication was requested, send the client a login form
|
||||
using (StreamWriter writer = new StreamWriter(response))
|
||||
writer.Write(String.Format(LOGIN_PAGE, profile.FirstName, profile.SurName));
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Cannot find an avatar matching the claimed identifier
|
||||
authRequest.IsAuthenticated = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Add OpenID headers to the response
|
||||
foreach (string key in provider.Request.Response.Headers.Keys)
|
||||
httpResponse.AddHeader(key, provider.Request.Response.Headers[key]);
|
||||
|
||||
string[] contentTypeValues = provider.Request.Response.Headers.GetValues("Content-Type");
|
||||
if (contentTypeValues != null && contentTypeValues.Length == 1)
|
||||
m_contentType = contentTypeValues[0];
|
||||
|
||||
// Set the response code and document body based on the OpenID result
|
||||
httpResponse.StatusCode = (int)provider.Request.Response.Code;
|
||||
response.Write(provider.Request.Response.Body, 0, provider.Request.Response.Body.Length);
|
||||
response.Close();
|
||||
}
|
||||
else if (httpRequest.Url.AbsolutePath.Contains("/openid/server"))
|
||||
{
|
||||
// Standard HTTP GET was made on the OpenID endpoint, send the client the default error page
|
||||
using (StreamWriter writer = new StreamWriter(response))
|
||||
writer.Write(ENDPOINT_PAGE);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Try and lookup this avatar
|
||||
UserProfileData profile;
|
||||
if (TryGetProfile(httpRequest.Url, out profile))
|
||||
{
|
||||
using (StreamWriter writer = new StreamWriter(response))
|
||||
{
|
||||
// TODO: Print out a full profile page for this avatar
|
||||
writer.Write(String.Format(OPENID_PAGE, httpRequest.Url.Scheme,
|
||||
httpRequest.Url.Authority, profile.FirstName, profile.SurName));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Couldn't parse an avatar name, or couldn't find the avatar in the user server
|
||||
using (StreamWriter writer = new StreamWriter(response))
|
||||
writer.Write(INVALID_OPENID_PAGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
httpResponse.StatusCode = (int)HttpStatusCode.InternalServerError;
|
||||
using (StreamWriter writer = new StreamWriter(response))
|
||||
writer.Write(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse a URL with a relative path of the form /users/First_Last and try to
|
||||
/// retrieve the profile matching that avatar name
|
||||
/// </summary>
|
||||
/// <param name="requestUrl">URL to parse for an avatar name</param>
|
||||
/// <param name="profile">Profile data for the avatar</param>
|
||||
/// <returns>True if the parse and lookup were successful, otherwise false</returns>
|
||||
bool TryGetProfile(Uri requestUrl, out UserProfileData profile)
|
||||
{
|
||||
if (requestUrl.Segments.Length == 3 && requestUrl.Segments[1] == "users/")
|
||||
{
|
||||
// Parse the avatar name from the path
|
||||
string username = requestUrl.Segments[requestUrl.Segments.Length - 1];
|
||||
string[] name = username.Split('_');
|
||||
|
||||
if (name.Length == 2)
|
||||
{
|
||||
profile = m_loginService.GetTheUser(name[0], name[1]);
|
||||
return (profile != null);
|
||||
}
|
||||
}
|
||||
|
||||
profile = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,68 +1,68 @@
|
||||
/*
|
||||
* 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 OpenSim 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;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using log4net;
|
||||
using Nwc.XmlRpc;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Communications;
|
||||
using OpenSim.Framework.Servers;
|
||||
|
||||
namespace OpenSim.Grid.UserServer
|
||||
{
|
||||
public class UserDataBaseService : UserManagerBase
|
||||
{
|
||||
public UserDataBaseService()
|
||||
: base(null)
|
||||
{
|
||||
}
|
||||
|
||||
public UserDataBaseService(IInterServiceInventoryServices interServiceInventoryService)
|
||||
: base(interServiceInventoryService)
|
||||
{
|
||||
}
|
||||
|
||||
public override UserProfileData SetupMasterUser(string firstName, string lastName)
|
||||
{
|
||||
throw new Exception("The method or operation is not implemented.");
|
||||
}
|
||||
|
||||
public override UserProfileData SetupMasterUser(string firstName, string lastName, string password)
|
||||
{
|
||||
throw new Exception("The method or operation is not implemented.");
|
||||
}
|
||||
|
||||
public override UserProfileData SetupMasterUser(UUID uuid)
|
||||
{
|
||||
throw new Exception("The method or operation is not implemented.");
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
* 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 OpenSim 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;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using log4net;
|
||||
using Nwc.XmlRpc;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Communications;
|
||||
using OpenSim.Framework.Servers;
|
||||
|
||||
namespace OpenSim.Grid.UserServer.Modules
|
||||
{
|
||||
public class UserDataBaseService : UserManagerBase
|
||||
{
|
||||
public UserDataBaseService()
|
||||
: base(null)
|
||||
{
|
||||
}
|
||||
|
||||
public UserDataBaseService(IInterServiceInventoryServices interServiceInventoryService)
|
||||
: base(interServiceInventoryService)
|
||||
{
|
||||
}
|
||||
|
||||
public override UserProfileData SetupMasterUser(string firstName, string lastName)
|
||||
{
|
||||
throw new Exception("The method or operation is not implemented.");
|
||||
}
|
||||
|
||||
public override UserProfileData SetupMasterUser(string firstName, string lastName, string password)
|
||||
{
|
||||
throw new Exception("The method or operation is not implemented.");
|
||||
}
|
||||
|
||||
public override UserProfileData SetupMasterUser(UUID uuid)
|
||||
{
|
||||
throw new Exception("The method or operation is not implemented.");
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -36,7 +36,7 @@ using OpenSim.Framework;
|
||||
using OpenSim.Framework.Communications;
|
||||
using OpenSim.Framework.Servers;
|
||||
|
||||
namespace OpenSim.Grid.UserServer
|
||||
namespace OpenSim.Grid.UserServer.Modules
|
||||
{
|
||||
public class UserServerAvatarAppearanceModule
|
||||
{
|
||||
@@ -36,7 +36,7 @@ using OpenSim.Framework;
|
||||
using OpenSim.Framework.Communications;
|
||||
using OpenSim.Framework.Servers;
|
||||
|
||||
namespace OpenSim.Grid.UserServer
|
||||
namespace OpenSim.Grid.UserServer.Modules
|
||||
{
|
||||
public class UserServerFriendsModule
|
||||
{
|
||||
@@ -1,43 +0,0 @@
|
||||
/*
|
||||
* 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.Text;
|
||||
using OpenSim.Framework.Servers;
|
||||
|
||||
namespace OpenSim.Grid.UserServer
|
||||
{
|
||||
public interface IUGAIMCore
|
||||
{
|
||||
T Get<T>();
|
||||
void RegisterInterface<T>(T iface);
|
||||
bool TryGet<T>(out T iface);
|
||||
BaseHttpServer GetHttpServer();
|
||||
|
||||
}
|
||||
}
|
||||
@@ -40,6 +40,8 @@ using OpenSim.Framework.Console;
|
||||
using OpenSim.Framework.Servers;
|
||||
using OpenSim.Framework.Statistics;
|
||||
using OpenSim.Grid.Communications.OGS1;
|
||||
using OpenSim.Grid.Framework;
|
||||
using OpenSim.Grid.UserServer.Modules;
|
||||
|
||||
namespace OpenSim.Grid.UserServer
|
||||
{
|
||||
@@ -63,6 +65,8 @@ namespace OpenSim.Grid.UserServer
|
||||
public GridInfoService m_gridInfoService;
|
||||
public MessageServersConnector m_messagesService;
|
||||
|
||||
protected UserServerCommandModule m_consoleCommandModule;
|
||||
|
||||
private UUID m_lastCreatedUser = UUID.Random();
|
||||
|
||||
public static void Main(string[] args)
|
||||
@@ -123,6 +127,8 @@ namespace OpenSim.Grid.UserServer
|
||||
|
||||
m_messagesService = new MessageServersConnector();
|
||||
|
||||
m_consoleCommandModule = new UserServerCommandModule(m_console, Cfg, m_userDataBaseService, m_loginService);
|
||||
|
||||
//register event handlers
|
||||
RegisterEventHandlers();
|
||||
|
||||
@@ -172,34 +178,7 @@ namespace OpenSim.Grid.UserServer
|
||||
|
||||
protected virtual void RegisterConsoleCommands()
|
||||
{
|
||||
m_console.Commands.AddCommand("userserver", false, "create user",
|
||||
"create user [<first> [<last> [<x> <y> [email]]]]",
|
||||
"Create a new user account", RunCommand);
|
||||
|
||||
m_console.Commands.AddCommand("userserver", false, "reset user password",
|
||||
"reset user password [<first> [<last> [<new password>]]]",
|
||||
"Reset a user's password", RunCommand);
|
||||
|
||||
m_console.Commands.AddCommand("userserver", false, "login level",
|
||||
"login level <level>",
|
||||
"Set the minimum user level to log in", HandleLoginCommand);
|
||||
|
||||
m_console.Commands.AddCommand("userserver", false, "login reset",
|
||||
"login reset",
|
||||
"Reset the login level to allow all users",
|
||||
HandleLoginCommand);
|
||||
|
||||
m_console.Commands.AddCommand("userserver", false, "login text",
|
||||
"login text <text>",
|
||||
"Set the text users will see on login", HandleLoginCommand);
|
||||
|
||||
m_console.Commands.AddCommand("userserver", false, "test-inventory",
|
||||
"test-inventory",
|
||||
"Perform a test inventory transaction", RunCommand);
|
||||
|
||||
m_console.Commands.AddCommand("userserver", false, "logoff-user",
|
||||
"logoff-user <first> <last> <message>",
|
||||
"Log off a named user", RunCommand);
|
||||
m_consoleCommandModule.RegisterConsoleCommands();
|
||||
}
|
||||
|
||||
protected virtual void RegisterHttpHandlers()
|
||||
@@ -261,247 +240,14 @@ namespace OpenSim.Grid.UserServer
|
||||
return m_httpServer;
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
#region Console Command Handlers
|
||||
public void do_create(string[] args)
|
||||
{
|
||||
switch (args[0])
|
||||
{
|
||||
case "user":
|
||||
CreateUser(args);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Execute switch for some of the reset commands
|
||||
/// </summary>
|
||||
/// <param name="args"></param>
|
||||
protected void Reset(string[] args)
|
||||
{
|
||||
if (args.Length == 0)
|
||||
return;
|
||||
|
||||
switch (args[0])
|
||||
{
|
||||
case "user":
|
||||
|
||||
switch (args[1])
|
||||
{
|
||||
case "password":
|
||||
ResetUserPassword(args);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new user
|
||||
/// </summary>
|
||||
/// <param name="cmdparams">string array with parameters: firstname, lastname, password, locationX, locationY, email</param>
|
||||
protected void CreateUser(string[] cmdparams)
|
||||
{
|
||||
string firstName;
|
||||
string lastName;
|
||||
string password;
|
||||
string email;
|
||||
uint regX = 1000;
|
||||
uint regY = 1000;
|
||||
|
||||
if (cmdparams.Length < 2)
|
||||
firstName = MainConsole.Instance.CmdPrompt("First name", "Default");
|
||||
else firstName = cmdparams[1];
|
||||
|
||||
if (cmdparams.Length < 3)
|
||||
lastName = MainConsole.Instance.CmdPrompt("Last name", "User");
|
||||
else lastName = cmdparams[2];
|
||||
|
||||
if (cmdparams.Length < 4)
|
||||
password = MainConsole.Instance.PasswdPrompt("Password");
|
||||
else password = cmdparams[3];
|
||||
|
||||
if (cmdparams.Length < 5)
|
||||
regX = Convert.ToUInt32(MainConsole.Instance.CmdPrompt("Start Region X", regX.ToString()));
|
||||
else regX = Convert.ToUInt32(cmdparams[4]);
|
||||
|
||||
if (cmdparams.Length < 6)
|
||||
regY = Convert.ToUInt32(MainConsole.Instance.CmdPrompt("Start Region Y", regY.ToString()));
|
||||
else regY = Convert.ToUInt32(cmdparams[5]);
|
||||
|
||||
if (cmdparams.Length < 7)
|
||||
email = MainConsole.Instance.CmdPrompt("Email", "");
|
||||
else email = cmdparams[6];
|
||||
|
||||
if (null == m_userDataBaseService.GetUserProfile(firstName, lastName))
|
||||
{
|
||||
m_lastCreatedUser = m_userDataBaseService.AddUser(firstName, lastName, password, email, regX, regY);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.ErrorFormat("[USERS]: A user with the name {0} {1} already exists!", firstName, lastName);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reset a user password.
|
||||
/// </summary>
|
||||
/// <param name="cmdparams"></param>
|
||||
private void ResetUserPassword(string[] cmdparams)
|
||||
{
|
||||
string firstName;
|
||||
string lastName;
|
||||
string newPassword;
|
||||
|
||||
if (cmdparams.Length < 3)
|
||||
firstName = MainConsole.Instance.CmdPrompt("First name");
|
||||
else firstName = cmdparams[2];
|
||||
|
||||
if ( cmdparams.Length < 4 )
|
||||
lastName = MainConsole.Instance.CmdPrompt("Last name");
|
||||
else lastName = cmdparams[3];
|
||||
|
||||
if ( cmdparams.Length < 5 )
|
||||
newPassword = MainConsole.Instance.PasswdPrompt("New password");
|
||||
else newPassword = cmdparams[4];
|
||||
|
||||
m_userDataBaseService.ResetUserPassword(firstName, lastName, newPassword);
|
||||
}
|
||||
|
||||
private void HandleLoginCommand(string module, string[] cmd)
|
||||
{
|
||||
string subcommand = cmd[1];
|
||||
|
||||
switch (subcommand)
|
||||
{
|
||||
case "level":
|
||||
// Set the minimal level to allow login
|
||||
// Useful to allow grid update without worrying about users.
|
||||
// or fixing critical issues
|
||||
//
|
||||
if (cmd.Length > 2)
|
||||
{
|
||||
int level = Convert.ToInt32(cmd[2]);
|
||||
m_loginService.setloginlevel(level);
|
||||
}
|
||||
break;
|
||||
case "reset":
|
||||
m_loginService.setloginlevel(0);
|
||||
break;
|
||||
case "text":
|
||||
if (cmd.Length > 2)
|
||||
{
|
||||
m_loginService.setwelcometext(cmd[2]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void RunCommand(string module, string[] cmd)
|
||||
{
|
||||
List<string> args = new List<string>(cmd);
|
||||
string command = cmd[0];
|
||||
|
||||
args.RemoveAt(0);
|
||||
|
||||
string[] cmdparams = args.ToArray();
|
||||
|
||||
switch (command)
|
||||
{
|
||||
case "create":
|
||||
do_create(cmdparams);
|
||||
break;
|
||||
|
||||
case "reset":
|
||||
Reset(cmdparams);
|
||||
break;
|
||||
|
||||
|
||||
case "test-inventory":
|
||||
// RestObjectPosterResponse<List<InventoryFolderBase>> requester = new RestObjectPosterResponse<List<InventoryFolderBase>>();
|
||||
// requester.ReturnResponseVal = TestResponse;
|
||||
// requester.BeginPostObject<UUID>(m_userManager._config.InventoryUrl + "RootFolders/", m_lastCreatedUser);
|
||||
SynchronousRestObjectPoster.BeginPostObject<UUID, List<InventoryFolderBase>>(
|
||||
"POST", Cfg.InventoryUrl + "RootFolders/", m_lastCreatedUser);
|
||||
break;
|
||||
|
||||
case "logoff-user":
|
||||
if (cmdparams.Length >= 3)
|
||||
{
|
||||
string firstname = cmdparams[0];
|
||||
string lastname = cmdparams[1];
|
||||
string message = "";
|
||||
|
||||
for (int i = 2; i < cmdparams.Length; i++)
|
||||
message += " " + cmdparams[i];
|
||||
|
||||
UserProfileData theUser = null;
|
||||
try
|
||||
{
|
||||
theUser = m_loginService.GetTheUser(firstname, lastname);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
m_log.Error("[LOGOFF]: Error getting user data from the database.");
|
||||
}
|
||||
|
||||
if (theUser != null)
|
||||
{
|
||||
if (theUser.CurrentAgent != null)
|
||||
{
|
||||
if (theUser.CurrentAgent.AgentOnline)
|
||||
{
|
||||
m_log.Info("[LOGOFF]: Logging off requested user!");
|
||||
m_loginService.LogOffUser(theUser, message);
|
||||
|
||||
theUser.CurrentAgent.AgentOnline = false;
|
||||
|
||||
m_loginService.CommitAgent(ref theUser);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.Info(
|
||||
"[LOGOFF]: User Doesn't appear to be online, sending the logoff message anyway.");
|
||||
m_loginService.LogOffUser(theUser, message);
|
||||
|
||||
theUser.CurrentAgent.AgentOnline = false;
|
||||
|
||||
m_loginService.CommitAgent(ref theUser);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.Error(
|
||||
"[LOGOFF]: Unable to logoff-user. User doesn't have an agent record so I can't find the simulator to notify");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.Info("[LOGOFF]: User doesn't exist in the database");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.Error(
|
||||
"[LOGOFF]: Invalid amount of parameters. logoff-user takes at least three. Firstname, Lastname, and message");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected override void ShowHelp(string[] helpArgs)
|
||||
{
|
||||
base.ShowHelp(helpArgs);
|
||||
|
||||
m_console.Notice("create user - create a new user");
|
||||
m_console.Notice("logoff-user <firstname> <lastname> <message> - logs off the specified user from the grid");
|
||||
m_console.Notice("reset user password - reset a user's password.");
|
||||
m_console.Notice("login-level <value> - Set the miminim userlevel allowed To login.");
|
||||
m_console.Notice("login-reset - reset the login level to its default value.");
|
||||
m_console.Notice("login-text <text to print during the login>");
|
||||
base.ShowHelp(helpArgs);
|
||||
|
||||
m_consoleCommandModule.ShowHelp(helpArgs);
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
349
OpenSim/Grid/UserServer/UserServerCommandModule.cs
Normal file
349
OpenSim/Grid/UserServer/UserServerCommandModule.cs
Normal file
@@ -0,0 +1,349 @@
|
||||
/*
|
||||
* 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 OpenSim 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.IO;
|
||||
using System.Reflection;
|
||||
using log4net;
|
||||
using log4net.Config;
|
||||
using OpenMetaverse;
|
||||
using OpenSim.Data;
|
||||
using OpenSim.Framework;
|
||||
using OpenSim.Framework.Communications;
|
||||
using OpenSim.Framework.Communications.Cache;
|
||||
using OpenSim.Framework.Console;
|
||||
using OpenSim.Framework.Servers;
|
||||
using OpenSim.Framework.Statistics;
|
||||
using OpenSim.Grid.Communications.OGS1;
|
||||
using OpenSim.Grid.Framework;
|
||||
using OpenSim.Grid.UserServer.Modules;
|
||||
|
||||
namespace OpenSim.Grid.UserServer
|
||||
{
|
||||
public class UserServerCommandModule
|
||||
{
|
||||
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
protected ConsoleBase m_console;
|
||||
protected UserConfig Cfg;
|
||||
|
||||
protected UserDataBaseService m_userDataBaseService;
|
||||
protected UserLoginService m_loginService;
|
||||
|
||||
private UUID m_lastCreatedUser = UUID.Random();
|
||||
|
||||
public UserServerCommandModule(ConsoleBase console, UserConfig cfg, UserDataBaseService userDBservice, UserLoginService loginService)
|
||||
{
|
||||
m_console = console;
|
||||
Cfg = cfg;
|
||||
m_userDataBaseService = userDBservice;
|
||||
m_loginService = loginService;
|
||||
}
|
||||
|
||||
public virtual void RegisterConsoleCommands()
|
||||
{
|
||||
m_console.Commands.AddCommand("userserver", false, "create user",
|
||||
"create user [<first> [<last> [<x> <y> [email]]]]",
|
||||
"Create a new user account", RunCommand);
|
||||
|
||||
m_console.Commands.AddCommand("userserver", false, "reset user password",
|
||||
"reset user password [<first> [<last> [<new password>]]]",
|
||||
"Reset a user's password", RunCommand);
|
||||
|
||||
m_console.Commands.AddCommand("userserver", false, "login level",
|
||||
"login level <level>",
|
||||
"Set the minimum user level to log in", HandleLoginCommand);
|
||||
|
||||
m_console.Commands.AddCommand("userserver", false, "login reset",
|
||||
"login reset",
|
||||
"Reset the login level to allow all users",
|
||||
HandleLoginCommand);
|
||||
|
||||
m_console.Commands.AddCommand("userserver", false, "login text",
|
||||
"login text <text>",
|
||||
"Set the text users will see on login", HandleLoginCommand);
|
||||
|
||||
m_console.Commands.AddCommand("userserver", false, "test-inventory",
|
||||
"test-inventory",
|
||||
"Perform a test inventory transaction", RunCommand);
|
||||
|
||||
m_console.Commands.AddCommand("userserver", false, "logoff-user",
|
||||
"logoff-user <first> <last> <message>",
|
||||
"Log off a named user", RunCommand);
|
||||
|
||||
m_console.Commands.AddCommand("userserver", false, "test-command",
|
||||
"test-command",
|
||||
"test command", HandleTestCommand);
|
||||
}
|
||||
|
||||
#region Console Command Handlers
|
||||
public void do_create(string[] args)
|
||||
{
|
||||
switch (args[0])
|
||||
{
|
||||
case "user":
|
||||
CreateUser(args);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Execute switch for some of the reset commands
|
||||
/// </summary>
|
||||
/// <param name="args"></param>
|
||||
protected void Reset(string[] args)
|
||||
{
|
||||
if (args.Length == 0)
|
||||
return;
|
||||
|
||||
switch (args[0])
|
||||
{
|
||||
case "user":
|
||||
|
||||
switch (args[1])
|
||||
{
|
||||
case "password":
|
||||
ResetUserPassword(args);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Create a new user
|
||||
/// </summary>
|
||||
/// <param name="cmdparams">string array with parameters: firstname, lastname, password, locationX, locationY, email</param>
|
||||
protected void CreateUser(string[] cmdparams)
|
||||
{
|
||||
string firstName;
|
||||
string lastName;
|
||||
string password;
|
||||
string email;
|
||||
uint regX = 1000;
|
||||
uint regY = 1000;
|
||||
|
||||
if (cmdparams.Length < 2)
|
||||
firstName = MainConsole.Instance.CmdPrompt("First name", "Default");
|
||||
else firstName = cmdparams[1];
|
||||
|
||||
if (cmdparams.Length < 3)
|
||||
lastName = MainConsole.Instance.CmdPrompt("Last name", "User");
|
||||
else lastName = cmdparams[2];
|
||||
|
||||
if (cmdparams.Length < 4)
|
||||
password = MainConsole.Instance.PasswdPrompt("Password");
|
||||
else password = cmdparams[3];
|
||||
|
||||
if (cmdparams.Length < 5)
|
||||
regX = Convert.ToUInt32(MainConsole.Instance.CmdPrompt("Start Region X", regX.ToString()));
|
||||
else regX = Convert.ToUInt32(cmdparams[4]);
|
||||
|
||||
if (cmdparams.Length < 6)
|
||||
regY = Convert.ToUInt32(MainConsole.Instance.CmdPrompt("Start Region Y", regY.ToString()));
|
||||
else regY = Convert.ToUInt32(cmdparams[5]);
|
||||
|
||||
if (cmdparams.Length < 7)
|
||||
email = MainConsole.Instance.CmdPrompt("Email", "");
|
||||
else email = cmdparams[6];
|
||||
|
||||
if (null == m_userDataBaseService.GetUserProfile(firstName, lastName))
|
||||
{
|
||||
m_lastCreatedUser = m_userDataBaseService.AddUser(firstName, lastName, password, email, regX, regY);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.ErrorFormat("[USERS]: A user with the name {0} {1} already exists!", firstName, lastName);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reset a user password.
|
||||
/// </summary>
|
||||
/// <param name="cmdparams"></param>
|
||||
private void ResetUserPassword(string[] cmdparams)
|
||||
{
|
||||
string firstName;
|
||||
string lastName;
|
||||
string newPassword;
|
||||
|
||||
if (cmdparams.Length < 3)
|
||||
firstName = MainConsole.Instance.CmdPrompt("First name");
|
||||
else firstName = cmdparams[2];
|
||||
|
||||
if (cmdparams.Length < 4)
|
||||
lastName = MainConsole.Instance.CmdPrompt("Last name");
|
||||
else lastName = cmdparams[3];
|
||||
|
||||
if (cmdparams.Length < 5)
|
||||
newPassword = MainConsole.Instance.PasswdPrompt("New password");
|
||||
else newPassword = cmdparams[4];
|
||||
|
||||
m_userDataBaseService.ResetUserPassword(firstName, lastName, newPassword);
|
||||
}
|
||||
|
||||
private void HandleTestCommand(string module, string[] cmd)
|
||||
{
|
||||
m_log.Info("test command received");
|
||||
}
|
||||
|
||||
private void HandleLoginCommand(string module, string[] cmd)
|
||||
{
|
||||
string subcommand = cmd[1];
|
||||
|
||||
switch (subcommand)
|
||||
{
|
||||
case "level":
|
||||
// Set the minimal level to allow login
|
||||
// Useful to allow grid update without worrying about users.
|
||||
// or fixing critical issues
|
||||
//
|
||||
if (cmd.Length > 2)
|
||||
{
|
||||
int level = Convert.ToInt32(cmd[2]);
|
||||
m_loginService.setloginlevel(level);
|
||||
}
|
||||
break;
|
||||
case "reset":
|
||||
m_loginService.setloginlevel(0);
|
||||
break;
|
||||
case "text":
|
||||
if (cmd.Length > 2)
|
||||
{
|
||||
m_loginService.setwelcometext(cmd[2]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void RunCommand(string module, string[] cmd)
|
||||
{
|
||||
List<string> args = new List<string>(cmd);
|
||||
string command = cmd[0];
|
||||
|
||||
args.RemoveAt(0);
|
||||
|
||||
string[] cmdparams = args.ToArray();
|
||||
|
||||
switch (command)
|
||||
{
|
||||
case "create":
|
||||
do_create(cmdparams);
|
||||
break;
|
||||
|
||||
case "reset":
|
||||
Reset(cmdparams);
|
||||
break;
|
||||
|
||||
|
||||
case "test-inventory":
|
||||
// RestObjectPosterResponse<List<InventoryFolderBase>> requester = new RestObjectPosterResponse<List<InventoryFolderBase>>();
|
||||
// requester.ReturnResponseVal = TestResponse;
|
||||
// requester.BeginPostObject<UUID>(m_userManager._config.InventoryUrl + "RootFolders/", m_lastCreatedUser);
|
||||
SynchronousRestObjectPoster.BeginPostObject<UUID, List<InventoryFolderBase>>(
|
||||
"POST", Cfg.InventoryUrl + "RootFolders/", m_lastCreatedUser);
|
||||
break;
|
||||
|
||||
case "logoff-user":
|
||||
if (cmdparams.Length >= 3)
|
||||
{
|
||||
string firstname = cmdparams[0];
|
||||
string lastname = cmdparams[1];
|
||||
string message = "";
|
||||
|
||||
for (int i = 2; i < cmdparams.Length; i++)
|
||||
message += " " + cmdparams[i];
|
||||
|
||||
UserProfileData theUser = null;
|
||||
try
|
||||
{
|
||||
theUser = m_loginService.GetTheUser(firstname, lastname);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
m_log.Error("[LOGOFF]: Error getting user data from the database.");
|
||||
}
|
||||
|
||||
if (theUser != null)
|
||||
{
|
||||
if (theUser.CurrentAgent != null)
|
||||
{
|
||||
if (theUser.CurrentAgent.AgentOnline)
|
||||
{
|
||||
m_log.Info("[LOGOFF]: Logging off requested user!");
|
||||
m_loginService.LogOffUser(theUser, message);
|
||||
|
||||
theUser.CurrentAgent.AgentOnline = false;
|
||||
|
||||
m_loginService.CommitAgent(ref theUser);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.Info(
|
||||
"[LOGOFF]: User Doesn't appear to be online, sending the logoff message anyway.");
|
||||
m_loginService.LogOffUser(theUser, message);
|
||||
|
||||
theUser.CurrentAgent.AgentOnline = false;
|
||||
|
||||
m_loginService.CommitAgent(ref theUser);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.Error(
|
||||
"[LOGOFF]: Unable to logoff-user. User doesn't have an agent record so I can't find the simulator to notify");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.Info("[LOGOFF]: User doesn't exist in the database");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_log.Error(
|
||||
"[LOGOFF]: Invalid amount of parameters. logoff-user takes at least three. Firstname, Lastname, and message");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void ShowHelp(string[] helpArgs)
|
||||
{
|
||||
m_console.Notice("create user - create a new user");
|
||||
m_console.Notice("logoff-user <firstname> <lastname> <message> - logs off the specified user from the grid");
|
||||
m_console.Notice("reset user password - reset a user's password.");
|
||||
m_console.Notice("login-level <value> - Set the miminim userlevel allowed To login.");
|
||||
m_console.Notice("login-reset - reset the login level to its default value.");
|
||||
m_console.Notice("login-text <text to print during the login>");
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
@@ -403,7 +403,9 @@ namespace OpenSim
|
||||
string regionFile = String.Format("{0}/{1}", regionsDir, cmd[3]);
|
||||
// Allow absolute and relative specifiers
|
||||
if (cmd[3].StartsWith("/") || cmd[3].StartsWith("\\") || cmd[3].StartsWith("..") || cmd[3].EndsWith(".xml"))
|
||||
{
|
||||
regionFile = cmd[3];
|
||||
}
|
||||
else
|
||||
{
|
||||
m_console.Error("Usage: create region <region name> <region_file.xml>");
|
||||
|
||||
39
prebuild.xml
39
prebuild.xml
@@ -895,6 +895,43 @@
|
||||
</Files>
|
||||
</Project>
|
||||
|
||||
<Project name="OpenSim.Grid.UserServer.Modules" path="OpenSim/Grid/UserServer.Modules" type="Library">
|
||||
<Configuration name="Debug">
|
||||
<Options>
|
||||
<OutputPath>../../../bin/</OutputPath>
|
||||
</Options>
|
||||
</Configuration>
|
||||
<Configuration name="Release">
|
||||
<Options>
|
||||
<OutputPath>../../../bin/</OutputPath>
|
||||
</Options>
|
||||
</Configuration>
|
||||
|
||||
<ReferencePath>../../../bin/</ReferencePath>
|
||||
<Reference name="System"/>
|
||||
<Reference name="System.Data"/>
|
||||
<Reference name="System.Xml"/>
|
||||
<Reference name="System.Web"/>
|
||||
<Reference name="OpenSim.Framework"/>
|
||||
<Reference name="OpenSim.Framework.Console"/>
|
||||
<Reference name="OpenSim.Framework.Communications"/>
|
||||
<Reference name="OpenSim.Data"/>
|
||||
<Reference name="OpenSim.Framework.Servers"/>
|
||||
<Reference name="OpenSim.Framework.Statistics"/>
|
||||
<Reference name="OpenSim.Grid.Framework"/>
|
||||
<Reference name="OpenSim.Grid.Communications.OGS1"/>
|
||||
<Reference name="OpenMetaverseTypes.dll"/>
|
||||
<Reference name="OpenMetaverse.StructuredData.dll"/>
|
||||
<Reference name="XMLRPC.dll"/>
|
||||
<Reference name="log4net.dll"/>
|
||||
<Reference name="DotNetOpenId.dll"/>
|
||||
|
||||
<Files>
|
||||
<Match pattern="*.cs" recurse="true"/>
|
||||
</Files>
|
||||
</Project>
|
||||
|
||||
|
||||
<Project name="OpenSim.Grid.UserServer" path="OpenSim/Grid/UserServer" type="Exe">
|
||||
<Configuration name="Debug">
|
||||
<Options>
|
||||
@@ -919,6 +956,8 @@
|
||||
<Reference name="OpenSim.Framework.Servers"/>
|
||||
<Reference name="OpenSim.Framework.Statistics"/>
|
||||
<Reference name="OpenSim.Grid.Communications.OGS1"/>
|
||||
<Reference name="OpenSim.Grid.Framework"/>
|
||||
<Reference name="OpenSim.Grid.UserServer.Modules"/>
|
||||
<Reference name="OpenMetaverseTypes.dll"/>
|
||||
<Reference name="OpenMetaverse.StructuredData.dll"/>
|
||||
<Reference name="XMLRPC.dll"/>
|
||||
|
||||
Reference in New Issue
Block a user