From 858b0a2efd4790042c3e248ce895a426462a2576 Mon Sep 17 00:00:00 2001 From: Melanie Thielker Date: Tue, 30 Jun 2009 21:48:03 +0000 Subject: 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. --- .../AuthenticationService/AuthenticationService.cs | 93 ++++++++++++++++++++-- .../Connectors/User/UserServiceConnector.cs | 60 +++++++++++++- .../Services/Interfaces/IAuthenticationService.cs | 42 ++++++++-- OpenSim/Services/Interfaces/IUserService.cs | 45 +++++++++-- OpenSim/Services/UserService/UserService.cs | 12 ++- 5 files changed, 228 insertions(+), 24 deletions(-) diff --git a/OpenSim/Services/AuthenticationService/AuthenticationService.cs b/OpenSim/Services/AuthenticationService/AuthenticationService.cs index 06f0e8f..3e6c3b2 100644 --- a/OpenSim/Services/AuthenticationService/AuthenticationService.cs +++ b/OpenSim/Services/AuthenticationService/AuthenticationService.cs @@ -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; + } + /// /// This implementation only authenticates users. /// /// /// /// - 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; } /// @@ -203,10 +263,17 @@ namespace OpenSim.Services.AuthenticationService } } - public UUID AllocateUserSession(UUID userID) + public UUID CreateUserSession(UUID userID, UUID oldSessionID) { - // Not implemented yet - return UUID.Zero; + 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; } } } diff --git a/OpenSim/Services/Connectors/User/UserServiceConnector.cs b/OpenSim/Services/Connectors/User/UserServiceConnector.cs index 8b136b5..12afb29 100644 --- a/OpenSim/Services/Connectors/User/UserServiceConnector.cs +++ b/OpenSim/Services/Connectors/User/UserServiceConnector.cs @@ -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("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("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("POST", uri, data); + MakeRequest("POST", uri, msg); } catch (Exception e) { diff --git a/OpenSim/Services/Interfaces/IAuthenticationService.cs b/OpenSim/Services/Interfaces/IAuthenticationService.cs index fa45cbc..2402414 100644 --- a/OpenSim/Services/Interfaces/IAuthenticationService.cs +++ b/OpenSim/Services/Interfaces/IAuthenticationService.cs @@ -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 - // - UUID AllocateUserSession(UUID userID); + ////////////////////////////////////////////////// + // Password auth portion + // + + // 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); } } diff --git a/OpenSim/Services/Interfaces/IUserService.cs b/OpenSim/Services/Interfaces/IUserService.cs index 2a4e79d..9bbe503 100644 --- a/OpenSim/Services/Interfaces/IUserService.cs +++ b/OpenSim/Services/Interfaces/IUserService.cs @@ -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 GetAvatarPickerData(UUID scopeID, string query); + + // Creates a user data record + bool CreateUserData(UserData data, UUID PrincipalID, UUID SessionID); } } diff --git a/OpenSim/Services/UserService/UserService.cs b/OpenSim/Services/UserService/UserService.cs index 5a6e5fb..cfbc2c1 100644 --- a/OpenSim/Services/UserService/UserService.cs +++ b/OpenSim/Services/UserService/UserService.cs @@ -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; } -- cgit v1.1