Updated services to allow external applications like web interfaces to

authenticate against the services. This paves the way for such apps
to directly talk to services.
trunk
Melanie Thielker 2009-06-30 21:48:03 +00:00
parent fe21189aa4
commit 858b0a2efd
5 changed files with 228 additions and 24 deletions

View File

@ -98,16 +98,70 @@ namespace OpenSim.Services.AuthenticationService
m_Database.Initialise(connString);
}
public UUID AuthenticateKey(UUID principalID, string key)
{
bool writeAgentData = false;
UserAgentData agent = m_Database.GetAgentByUUID(principalID);
if (agent == null)
{
agent = new UserAgentData();
agent.ProfileID = principalID;
agent.SessionID = UUID.Random();
agent.SecureSessionID = UUID.Random();
agent.AgentIP = "127.0.0.1";
agent.AgentPort = 0;
agent.AgentOnline = false;
writeAgentData = true;
}
if (!m_PerformAuthentication)
{
if (writeAgentData)
m_Database.AddNewUserAgent(agent);
return agent.SessionID;
}
if (!VerifyKey(principalID, key))
return UUID.Zero;
if (writeAgentData)
m_Database.AddNewUserAgent(agent);
return agent.SessionID;
}
/// <summary>
/// This implementation only authenticates users.
/// </summary>
/// <param name="principalID"></param>
/// <param name="password"></param>
/// <returns></returns>
public bool Authenticate(UUID principalID, string password)
public UUID AuthenticatePassword(UUID principalID, string password)
{
bool writeAgentData = false;
UserAgentData agent = m_Database.GetAgentByUUID(principalID);
if (agent == null)
{
agent = new UserAgentData();
agent.ProfileID = principalID;
agent.SessionID = UUID.Random();
agent.SecureSessionID = UUID.Random();
agent.AgentIP = "127.0.0.1";
agent.AgentPort = 0;
agent.AgentOnline = false;
writeAgentData = true;
}
if (!m_PerformAuthentication)
return true;
{
if (writeAgentData)
m_Database.AddNewUserAgent(agent);
return agent.SessionID;
}
UserProfileData profile = m_Database.GetUserByUUID(principalID);
bool passwordSuccess = false;
@ -128,7 +182,13 @@ namespace OpenSim.Services.AuthenticationService
passwordSuccess = (profile.PasswordHash.Equals(s.ToString(), StringComparison.InvariantCultureIgnoreCase)
|| profile.PasswordHash.Equals(password, StringComparison.InvariantCulture));
return passwordSuccess;
if (!passwordSuccess)
return UUID.Zero;
if (writeAgentData)
m_Database.AddNewUserAgent(agent);
return agent.SessionID;
}
/// <summary>
@ -203,10 +263,17 @@ namespace OpenSim.Services.AuthenticationService
}
}
public UUID AllocateUserSession(UUID userID)
public UUID CreateUserSession(UUID userID, UUID oldSessionID)
{
// Not implemented yet
UserAgentData agent = m_Database.GetAgentByUUID(userID);
if (agent == null)
return UUID.Zero;
agent.SessionID = UUID.Random();
m_Database.AddNewUserAgent(agent);
return agent.SessionID;
}
public bool VerifyUserSession(UUID userID, UUID sessionID)
@ -225,9 +292,19 @@ namespace OpenSim.Services.AuthenticationService
return false;
}
public void DestroyUserSession(UUID userID)
public bool DestroyUserSession(UUID userID, UUID sessionID)
{
// Not implemented yet
if (!VerifyUserSession(userID, sessionID))
return false;
UserAgentData agent = m_Database.GetAgentByUUID(userID);
if (agent == null)
return false;
agent.SessionID = UUID.Zero;
m_Database.AddNewUserAgent(agent);
return true;
}
}
}

View File

@ -133,15 +133,71 @@ namespace OpenSim.Services.Connectors
return data;
}
public bool SetUserData(UserData data)
public bool SetHomePosition(UserData data, UUID regionID, UUID regionSecret)
{
string uri = m_ServerURI + "/user/";
bool result = false;
UserDataMessage msg = new UserDataMessage();
msg.Data = data;
msg.RegionID = regionID;
msg.RegionSecret = regionSecret;
try
{
result = SynchronousRestObjectRequester.
MakeRequest<UserData, bool>("POST", uri, data);
MakeRequest<UserDataMessage, bool>("POST", uri, msg);
}
catch (Exception e)
{
m_log.WarnFormat("[USER CONNECTOR]: Unable to send request to user server. Reason: {1}", e.Message);
return false;
}
return result;
}
public bool SetUserData(UserData data, UUID principalID, UUID sessionID)
{
string uri = m_ServerURI + "/user/";
bool result = false;
UserDataMessage msg = new UserDataMessage();
msg.Data = data;
msg.PrincipalID = principalID;
msg.SessionID = sessionID;
try
{
result = SynchronousRestObjectRequester.
MakeRequest<UserDataMessage, bool>("POST", uri, msg);
}
catch (Exception e)
{
m_log.WarnFormat("[USER CONNECTOR]: Unable to send request to user server. Reason: {1}", e.Message);
return false;
}
return result;
}
public bool CreateUserData(UserData data, UUID principalID, UUID sessionID)
{
string uri = m_ServerURI + "/newuser/";
bool result = false;
UserDataMessage msg = new UserDataMessage();
msg.Data = data;
msg.PrincipalID = principalID;
msg.SessionID = sessionID;
try
{
result = SynchronousRestObjectRequester.
MakeRequest<UserDataMessage, bool>("POST", uri, msg);
}
catch (Exception e)
{

View File

@ -38,9 +38,9 @@ namespace OpenSim.Services.Interfaces
//
public interface IAuthenticationService
{
// Check the pricipal's password
//////////////////////////////////////////////////
// Web login key portion
//
bool Authenticate(UUID principalID, string password);
// Get a service key given that principal's
// authentication token (master key).
@ -51,18 +51,44 @@ namespace OpenSim.Services.Interfaces
//
bool VerifyKey(UUID principalID, string key);
// Create a new user session. If one exists, it is cleared
//////////////////////////////////////////////////
// Password auth portion
//
UUID AllocateUserSession(UUID userID);
// Here's how thos works, and why.
//
// The authentication methods will return the existing session,
// or UUID.Zero if authentication failed. If there is no session,
// they will create one.
// The CreateUserSession method will unconditionally create a session
// and invalidate the prior session.
// Grid login uses this method to make sure that the session is
// fresh and new. Other software, like management applications,
// can obtain this existing session if they have a key or password
// for that account, this allows external apps to obtain credentials
// and use authenticating interface methods.
//
// Check the pricipal's password
//
UUID AuthenticatePassword(UUID principalID, string password);
// Check the principal's key
//
UUID AuthenticateKey(UUID principalID, string password);
// Create a new session, invalidating the old ones
//
UUID CreateUserSession(UUID principalID, UUID oldSessionID);
// Verify that a user session ID is valid. A session ID is
// considered valid when a user has successfully authenticated
// at least one time inside that session.
//
bool VerifyUserSession(UUID principalID, UUID session);
bool VerifyUserSession(UUID principalID, UUID sessionID);
// Remove a user session identifier and deauthenticate the user
// Deauthenticate user
//
void DestroyUserSession(UUID principalID);
bool DestroyUserSession(UUID principalID, UUID sessionID);
}
}

View File

@ -32,6 +32,24 @@ namespace OpenSim.Services.Interfaces
{
public class UserData
{
public UserData()
{
}
public UserData(UUID userID, UUID homeRegionID, float homePositionX,
float homePositionY, float homePositionZ, float homeLookAtX,
float homeLookAtY, float homeLookAtZ)
{
UserID = userID;
HomeRegionID = homeRegionID;
HomePositionX = homePositionX;
HomePositionY = homePositionY;
HomePositionZ = homePositionZ;
HomeLookAtX = homeLookAtX;
HomeLookAtY = homeLookAtY;
HomeLookAtZ = homeLookAtZ;
}
public string FirstName;
public string LastName;
public UUID UserID;
@ -49,7 +67,7 @@ namespace OpenSim.Services.Interfaces
public float HomeLookAtY;
public float HomeLookAtZ;
// There are here because they
// These are here because they
// concern the account rather than
// the profile. They just happen to
// be used in the Linden profile as well
@ -58,11 +76,21 @@ namespace OpenSim.Services.Interfaces
public int UserFlags;
public string AccountType;
// This is only used internally. It needs to be set
// to the secret of the sending region when updating
// user data.
};
public class UserDataMessage
{
public UserData Data;
// Set to the region's ID and secret when updating home location
//
public UUID RegionID;
public UUID RegionSecret;
// Set to the auth info of the user requesting creation/update
//
public UUID PrincipalID;
public UUID SessionID;
};
public interface IUserDataService
@ -73,11 +101,18 @@ namespace OpenSim.Services.Interfaces
// This will set only the home region portion of the data!
// Can't be used to set god level, flags, type or change the name!
//
bool SetUserData(UserData data);
bool SetHomePosition(UserData data, UUID RegionID, UUID RegionSecret);
// Update all updatable fields
//
bool SetUserData(UserData data, UUID PrincipalID, UUID SessionID);
// Returns the list of avatars that matches both the search
// criterion and the scope ID passed
//
List<UserData> GetAvatarPickerData(UUID scopeID, string query);
// Creates a user data record
bool CreateUserData(UserData data, UUID PrincipalID, UUID SessionID);
}
}

View File

@ -52,7 +52,17 @@ namespace OpenSim.Services.UserService
return null;
}
public bool SetUserData(UserData data)
public bool SetHomePosition(UserData data, UUID regionID, UUID regionSecret)
{
return false;
}
public bool SetUserData(UserData data, UUID principalID, UUID sessionID)
{
return false;
}
public bool CreateUserData(UserData data, UUID principalID, UUID sessionID)
{
return false;
}