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.GenericGridServerConcept
parent
b587478fd4
commit
ea26bd4153
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
|
||||
|
||||
|
|
|
@ -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"/>
|
||||
|
|
Loading…
Reference in New Issue