Fixed permissions bug related to friends in PermissionsModule. Added FriendsData[] GetFriends(string principalID) to IFriendsData and FriendInfo[] GetFriends(string PrincipalID) to IFriendsService. Refactored some more in the FriendsModule. Made client get notification of local friends permissions upon HGLogin. HG Friends object permissions work.

bulletsim
Diva Canto 2011-05-21 16:48:00 -07:00
parent 80457111e0
commit 58c53c41de
17 changed files with 376 additions and 301 deletions

View File

@ -47,5 +47,6 @@ namespace OpenSim.Data
bool Store(FriendsData data); bool Store(FriendsData data);
bool Delete(UUID ownerID, string friend); bool Delete(UUID ownerID, string friend);
FriendsData[] GetFriends(UUID principalID); FriendsData[] GetFriends(UUID principalID);
FriendsData[] GetFriends(string principalID);
} }
} }

View File

@ -67,6 +67,11 @@ namespace OpenSim.Data.MSSQL
} }
public FriendsData[] GetFriends(UUID principalID) public FriendsData[] GetFriends(UUID principalID)
{
return GetFriends(principalID.ToString());
}
public FriendsData[] GetFriends(string principalID)
{ {
using (SqlConnection conn = new SqlConnection(m_ConnectionString)) using (SqlConnection conn = new SqlConnection(m_ConnectionString))
using (SqlCommand cmd = new SqlCommand()) using (SqlCommand cmd = new SqlCommand())
@ -79,5 +84,6 @@ namespace OpenSim.Data.MSSQL
return DoQuery(cmd); return DoQuery(cmd);
} }
} }
} }
} }

View File

@ -56,6 +56,11 @@ namespace OpenSim.Data.MySQL
} }
public FriendsData[] GetFriends(UUID principalID) public FriendsData[] GetFriends(UUID principalID)
{
return GetFriends(principalID.ToString());
}
public FriendsData[] GetFriends(string principalID)
{ {
MySqlCommand cmd = new MySqlCommand(); MySqlCommand cmd = new MySqlCommand();

View File

@ -42,6 +42,11 @@ namespace OpenSim.Data.Null
{ {
} }
public FriendsData[] GetFriends(UUID principalID)
{
return GetFriends(principalID.ToString());
}
/// <summary> /// <summary>
/// Tries to implement the Get [] semantics, but it cuts corners. /// Tries to implement the Get [] semantics, but it cuts corners.
/// Specifically, it gets all friendships even if they weren't accepted yet. /// Specifically, it gets all friendships even if they weren't accepted yet.
@ -49,7 +54,7 @@ namespace OpenSim.Data.Null
/// <param name="fields"></param> /// <param name="fields"></param>
/// <param name="values"></param> /// <param name="values"></param>
/// <returns></returns> /// <returns></returns>
public FriendsData[] GetFriends(UUID userID) public FriendsData[] GetFriends(string userID)
{ {
List<FriendsData> lst = m_Data.FindAll(delegate (FriendsData fdata) List<FriendsData> lst = m_Data.FindAll(delegate (FriendsData fdata)
{ {

View File

@ -46,7 +46,12 @@ namespace OpenSim.Data.SQLite
{ {
} }
public FriendsData[] GetFriends(UUID userID) public FriendsData[] GetFriends(UUID principalID)
{
return GetFriends(principalID.ToString());
}
public FriendsData[] GetFriends(string userID)
{ {
SqliteCommand cmd = new SqliteCommand(); SqliteCommand cmd = new SqliteCommand();

View File

@ -69,7 +69,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
} }
} }
private static readonly FriendInfo[] EMPTY_FRIENDS = new FriendInfo[0]; protected static readonly FriendInfo[] EMPTY_FRIENDS = new FriendInfo[0];
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
protected List<Scene> m_Scenes = new List<Scene>(); protected List<Scene> m_Scenes = new List<Scene>();
@ -187,6 +187,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
{ {
if (!m_Enabled) if (!m_Enabled)
return; return;
m_log.DebugFormat("[FRIENDS MODULE]: AddRegion on {0}", Name);
m_Scenes.Add(scene); m_Scenes.Add(scene);
scene.RegisterModuleInterface<IFriendsModule>(this); scene.RegisterModuleInterface<IFriendsModule>(this);
@ -221,13 +222,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
#endregion #endregion
public uint GetFriendPerms(UUID principalID, UUID friendID) public virtual uint GetFriendPerms(UUID principalID, UUID friendID)
{ {
FriendInfo[] friends = GetFriends(principalID); FriendInfo[] friends = GetFriends(principalID);
foreach (FriendInfo fi in friends) FriendInfo finfo = GetFriend(friends, friendID);
if (finfo != null)
{ {
if (fi.Friend == friendID.ToString()) return (uint)finfo.TheirFlags;
return (uint)fi.TheirFlags;
} }
return 0; return 0;
@ -241,14 +242,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
client.OnTerminateFriendship += OnTerminateFriendship; client.OnTerminateFriendship += OnTerminateFriendship;
client.OnGrantUserRights += OnGrantUserRights; client.OnGrantUserRights += OnGrantUserRights;
Util.FireAndForget(delegate { FetchFriendslist(client.AgentId); }); Util.FireAndForget(delegate { FetchFriendslist(client); });
} }
/// Fetch the friends list or increment the refcount for the existing /// Fetch the friends list or increment the refcount for the existing
/// friends list /// friends list
/// Returns true if the list was fetched, false if it wasn't /// Returns true if the list was fetched, false if it wasn't
protected virtual bool FetchFriendslist(UUID agentID) protected virtual bool FetchFriendslist(IClientAPI client)
{ {
UUID agentID = client.AgentId;
lock (m_Friends) lock (m_Friends)
{ {
UserFriendData friendsData; UserFriendData friendsData;
@ -261,7 +263,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
{ {
friendsData = new UserFriendData(); friendsData = new UserFriendData();
friendsData.PrincipalID = agentID; friendsData.PrincipalID = agentID;
friendsData.Friends = FriendsService.GetFriends(agentID); friendsData.Friends = GetFriendsFromService(client);
friendsData.Refcount = 1; friendsData.Refcount = 1;
m_Friends[agentID] = friendsData; m_Friends[agentID] = friendsData;
@ -270,6 +272,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
} }
} }
protected virtual FriendInfo[] GetFriendsFromService(IClientAPI client)
{
return FriendsService.GetFriends(client.AgentId);
}
private void OnClientClosed(UUID agentID, Scene scene) private void OnClientClosed(UUID agentID, Scene scene)
{ {
ScenePresence sp = scene.GetScenePresence(agentID); ScenePresence sp = scene.GetScenePresence(agentID);
@ -293,8 +300,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
private void OnMakeRootAgent(ScenePresence sp) private void OnMakeRootAgent(ScenePresence sp)
{ {
UUID agentID = sp.ControllingClient.AgentId; UpdateFriendsCache(sp.ControllingClient);
UpdateFriendsCache(agentID);
} }
private void OnClientLogin(IClientAPI client) private void OnClientLogin(IClientAPI client)
@ -309,7 +315,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
m_NeedsListOfFriends.Add(agentID); m_NeedsListOfFriends.Add(agentID);
} }
public void SendFriendsOnlineIfNeeded(IClientAPI client) public virtual bool SendFriendsOnlineIfNeeded(IClientAPI client)
{ {
UUID agentID = client.AgentId; UUID agentID = client.AgentId;
@ -317,7 +323,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
lock (m_NeedsListOfFriends) lock (m_NeedsListOfFriends)
{ {
if (!m_NeedsListOfFriends.Remove(agentID)) if (!m_NeedsListOfFriends.Remove(agentID))
return; return false;
} }
// Send the friends online // Send the friends online
@ -366,6 +372,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
// Finally // Finally
LocalFriendshipOffered(agentID, im); LocalFriendshipOffered(agentID, im);
} }
return true;
} }
protected virtual string FriendshipMessage(string friendID) protected virtual string FriendshipMessage(string friendID)
@ -579,7 +587,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
StoreFriendships(agentID, friendID); StoreFriendships(agentID, friendID);
// Update the local cache // Update the local cache
UpdateFriendsCache(agentID); UpdateFriendsCache(client);
// //
// Notify the friend // Notify the friend
@ -647,7 +655,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
DeleteFriendship(agentID, exfriendID); DeleteFriendship(agentID, exfriendID);
// Update local cache // Update local cache
UpdateFriendsCache(agentID); UpdateFriendsCache(client);
client.SendTerminateFriend(exfriendID); client.SendTerminateFriend(exfriendID);
@ -679,23 +687,26 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
private void OnGrantUserRights(IClientAPI remoteClient, UUID requester, UUID target, int rights) private void OnGrantUserRights(IClientAPI remoteClient, UUID requester, UUID target, int rights)
{ {
m_log.DebugFormat("[FRIENDS MODULE]: User {0} changing rights to {1} for friend {2}", requester, rights, target);
FriendInfo[] friends = GetFriends(remoteClient.AgentId); FriendInfo[] friends = GetFriends(remoteClient.AgentId);
if (friends.Length == 0) if (friends.Length == 0)
return;
m_log.DebugFormat("[FRIENDS MODULE]: User {0} changing rights to {1} for friend {2}", requester, rights, target);
// Let's find the friend in this user's friend list
FriendInfo friend = null;
foreach (FriendInfo fi in friends)
{ {
if (fi.Friend == target.ToString()) m_log.DebugFormat("[XXX]: agent {0} has no friends", requester);
friend = fi; return;
} }
// Let's find the friend in this user's friend list
FriendInfo friend = GetFriend(friends, target);
if (friend != null) // Found it if (friend != null) // Found it
{ {
// Store it on the DB // Store it on the DB
FriendsService.StoreFriend(requester.ToString(), target.ToString(), rights); if (!SimpleStore(requester, target, rights))
{
remoteClient.SendAlertMessage("Unable to grant rights.");
return;
}
// Store it in the local cache // Store it in the local cache
int myFlags = friend.MyFlags; int myFlags = friend.MyFlags;
@ -725,6 +736,24 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
} }
} }
} }
else
m_log.DebugFormat("[FRIENDS MODULE]: friend {0} not found for {1}", target, requester);
}
protected virtual bool SimpleStore(UUID agentID, UUID friendID, int rights)
{
FriendsService.StoreFriend(agentID.ToString(), friendID.ToString(), rights);
return true;
}
protected virtual FriendInfo GetFriend(FriendInfo[] friends, UUID friendID)
{
foreach (FriendInfo fi in friends)
{
if (fi.Friend == friendID.ToString())
return fi;
}
return null;
} }
#region Local #region Local
@ -753,7 +782,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
friendClient.SendInstantMessage(im); friendClient.SendInstantMessage(im);
// Update the local cache // Update the local cache
UpdateFriendsCache(friendID); UpdateFriendsCache(friendClient);
// we're done // we're done
return true; return true;
@ -786,7 +815,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
// the friend in this sim as root agent // the friend in this sim as root agent
friendClient.SendTerminateFriend(exfriendID); friendClient.SendTerminateFriend(exfriendID);
// update local cache // update local cache
UpdateFriendsCache(exfriendID); UpdateFriendsCache(friendClient);
// we're done // we're done
return true; return true;
} }
@ -816,15 +845,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
} }
// Update local cache // Update local cache
lock (m_Friends) UpdateLocalCache(userID, friendID, rights);
{
FriendInfo[] friends = GetFriends(friendID);
foreach (FriendInfo finfo in friends)
{
if (finfo.Friend == userID.ToString())
finfo.TheirFlags = rights;
}
}
return true; return true;
} }
@ -866,13 +887,25 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
return EMPTY_FRIENDS; return EMPTY_FRIENDS;
} }
private void UpdateFriendsCache(UUID agentID) private void UpdateFriendsCache(IClientAPI client)
{ {
UUID agentID = client.AgentId;
lock (m_Friends) lock (m_Friends)
{ {
UserFriendData friendsData; UserFriendData friendsData;
if (m_Friends.TryGetValue(agentID, out friendsData)) if (m_Friends.TryGetValue(agentID, out friendsData))
friendsData.Friends = FriendsService.GetFriends(agentID); friendsData.Friends = GetFriendsFromService(client);
}
}
protected void UpdateLocalCache(UUID userID, UUID friendID, int rights)
{
// Update local cache
lock (m_Friends)
{
FriendInfo[] friends = GetFriends(friendID);
FriendInfo finfo = GetFriend(friends, userID);
finfo.TheirFlags = rights;
} }
} }
} }

View File

@ -58,129 +58,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
#endregion #endregion
//public void SendFriendsOnlineIfNeeded(IClientAPI client) protected override bool FetchFriendslist(IClientAPI client)
//{
// UUID agentID = client.AgentId;
// // Check if the online friends list is needed
// lock (m_NeedsListOfFriends)
// {
// if (!m_NeedsListOfFriends.Remove(agentID))
// return;
// }
// // Send the friends online
// List<UUID> online = GetOnlineFriends(agentID);
// if (online.Count > 0)
// {
// m_log.DebugFormat("[FRIENDS MODULE]: User {0} in region {1} has {2} friends online", client.AgentId, client.Scene.RegionInfo.RegionName, online.Count);
// client.SendAgentOnline(online.ToArray());
// }
// // Send outstanding friendship offers
// List<string> outstanding = new List<string>();
// FriendInfo[] friends = GetFriends(agentID);
// foreach (FriendInfo fi in friends)
// {
// if (fi.TheirFlags == -1)
// outstanding.Add(fi.Friend);
// }
// GridInstantMessage im = new GridInstantMessage(client.Scene, UUID.Zero, String.Empty, agentID, (byte)InstantMessageDialog.FriendshipOffered,
// "Will you be my friend?", true, Vector3.Zero);
// foreach (string fid in outstanding)
// {
// UUID fromAgentID;
// if (!UUID.TryParse(fid, out fromAgentID))
// continue;
// UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(client.Scene.RegionInfo.ScopeID, fromAgentID);
// PresenceInfo presence = null;
// PresenceInfo[] presences = PresenceService.GetAgents(new string[] { fid });
// if (presences != null && presences.Length > 0)
// presence = presences[0];
// if (presence != null)
// im.offline = 0;
// im.fromAgentID = fromAgentID.Guid;
// im.fromAgentName = account.FirstName + " " + account.LastName;
// im.offline = (byte)((presence == null) ? 1 : 0);
// im.imSessionID = im.fromAgentID;
// // Finally
// LocalFriendshipOffered(agentID, im);
// }
//}
//List<UUID> GetOnlineFriends(UUID userID)
//{
// List<string> friendList = new List<string>();
// List<UUID> online = new List<UUID>();
// FriendInfo[] friends = GetFriends(userID);
// foreach (FriendInfo fi in friends)
// {
// if (((fi.TheirFlags & 1) != 0) && (fi.TheirFlags != -1))
// friendList.Add(fi.Friend);
// }
// if (friendList.Count > 0)
// {
// PresenceInfo[] presence = PresenceService.GetAgents(friendList.ToArray());
// foreach (PresenceInfo pi in presence)
// {
// UUID presenceID;
// if (UUID.TryParse(pi.UserID, out presenceID))
// online.Add(presenceID);
// }
// }
// return online;
//}
//private void StatusNotify(FriendInfo friend, UUID userID, bool online)
//{
// UUID friendID;
// if (UUID.TryParse(friend.Friend, out friendID))
// {
// // Try local
// if (LocalStatusNotification(userID, friendID, online))
// return;
// // The friend is not here [as root]. Let's forward.
// PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { friendID.ToString() });
// if (friendSessions != null && friendSessions.Length > 0)
// {
// PresenceInfo friendSession = null;
// foreach (PresenceInfo pinfo in friendSessions)
// if (pinfo.RegionID != UUID.Zero) // let's guard against sessions-gone-bad
// {
// friendSession = pinfo;
// break;
// }
// if (friendSession != null)
// {
// GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
// //m_log.DebugFormat("[FRIENDS]: Remote Notify to region {0}", region.RegionName);
// m_FriendsSimConnector.StatusNotify(region, userID, friendID, online);
// }
// }
// // Friend is not online. Ignore.
// }
// else
// {
// m_log.WarnFormat("[FRIENDS]: Error parsing friend ID {0}", friend.Friend);
// }
//}
protected override bool FetchFriendslist(UUID agentID)
{ {
if (base.FetchFriendslist(agentID)) if (base.FetchFriendslist(client))
{ {
UUID agentID = client.AgentId;
// We need to preload the user management cache with the names // We need to preload the user management cache with the names
// of foreign friends, just like we do with SOPs' creators // of foreign friends, just like we do with SOPs' creators
foreach (FriendInfo finfo in m_Friends[agentID].Friends) foreach (FriendInfo finfo in m_Friends[agentID].Friends)
@ -204,6 +86,39 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
return false; return false;
} }
public override bool SendFriendsOnlineIfNeeded(IClientAPI client)
{
if (base.SendFriendsOnlineIfNeeded(client))
{
UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(client.Scene.RegionInfo.ScopeID, client.AgentId);
if (account == null) // foreign
{
FriendInfo[] friends = GetFriends(client.AgentId);
foreach (FriendInfo f in friends)
{
client.SendChangeUserRights(new UUID(f.Friend), client.AgentId, f.TheirFlags);
}
}
}
return false;
}
protected override FriendInfo[] GetFriendsFromService(IClientAPI client)
{
UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, client.AgentId);
if (account1 != null)
return base.GetFriendsFromService(client);
// Foreigner
AgentCircuitData agentClientCircuit = ((Scene)(client.Scene)).AuthenticateHandler.GetAgentCircuitData(client.CircuitCode);
string agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit);
FriendInfo[] finfos = FriendsService.GetFriends(agentUUI);
m_log.DebugFormat("[HGFRIENDS MODULE]: Fetched {0} local friends for visitor {1}", finfos.Length, agentUUI);
return finfos;
}
protected override bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last) protected override bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last)
{ {
first = "Unknown"; last = "User"; first = "Unknown"; last = "User";
@ -249,6 +164,45 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
return "Please confirm this friendship you made while you were away."; return "Please confirm this friendship you made while you were away.";
} }
protected override bool SimpleStore(UUID agentID, UUID friendID, int rights)
{
UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID);
UserAccount account2 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friendID);
// Are they both local users?
if (account1 != null && account2 != null)
{
// local grid users
return base.SimpleStore(agentID, friendID, rights);
}
if (account1 != null)
{
FriendInfo[] finfos = GetFriends(agentID);
if (finfos.Length > 0)
{
FriendInfo finfo = GetFriend(finfos, friendID);
FriendsService.StoreFriend(agentID.ToString(), finfo.Friend, rights);
return true;
}
}
if (account2 != null)
{
IClientAPI client = LocateClientObject(agentID);
if (client != null)
{
AgentCircuitData acircuit = m_Scenes[0].AuthenticateHandler.GetAgentCircuitData(client.CircuitCode);
if (acircuit != null)
{
FriendsService.StoreFriend(Util.ProduceUserUniversalIdentifier(acircuit), friendID.ToString(), rights);
return true;
}
}
}
return false;
}
protected override void StoreBackwards(UUID friendID, UUID agentID) protected override void StoreBackwards(UUID friendID, UUID agentID)
{ {
UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID); UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID);
@ -366,6 +320,16 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
// my brain hurts now // my brain hurts now
} }
protected override FriendInfo GetFriend(FriendInfo[] friends, UUID friendID)
{
foreach (FriendInfo fi in friends)
{
if (fi.Friend.StartsWith(friendID.ToString()))
return fi;
}
return null;
}
protected override void DeleteFriendship(UUID agentID, UUID exfriendID) protected override void DeleteFriendship(UUID agentID, UUID exfriendID)
{ {
base.DeleteFriendship(agentID, exfriendID); base.DeleteFriendship(agentID, exfriendID);
@ -374,7 +338,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
FriendInfo[] friends = GetFriends(agentID); FriendInfo[] friends = GetFriends(agentID);
foreach (FriendInfo finfo in friends) foreach (FriendInfo finfo in friends)
{ {
if (finfo.Friend != exfriendID.ToString() && finfo.Friend.EndsWith(exfriendID.ToString())) if (finfo.Friend != exfriendID.ToString() && finfo.Friend.StartsWith(exfriendID.ToString()))
{ {
FriendsService.Delete(agentID, exfriendID.ToString()); FriendsService.Delete(agentID, exfriendID.ToString());
// TODO: delete the friendship on the other side // TODO: delete the friendship on the other side
@ -383,56 +347,5 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends
} }
} }
//private void OnGrantUserRights(IClientAPI remoteClient, UUID requester, UUID target, int rights)
//{
// FriendInfo[] friends = GetFriends(remoteClient.AgentId);
// if (friends.Length == 0)
// return;
// m_log.DebugFormat("[FRIENDS MODULE]: User {0} changing rights to {1} for friend {2}", requester, rights, target);
// // Let's find the friend in this user's friend list
// FriendInfo friend = null;
// foreach (FriendInfo fi in friends)
// {
// if (fi.Friend == target.ToString())
// friend = fi;
// }
// if (friend != null) // Found it
// {
// // Store it on the DB
// FriendsService.StoreFriend(requester, target.ToString(), rights);
// // Store it in the local cache
// int myFlags = friend.MyFlags;
// friend.MyFlags = rights;
// // Always send this back to the original client
// remoteClient.SendChangeUserRights(requester, target, rights);
// //
// // Notify the friend
// //
// // Try local
// if (LocalGrantRights(requester, target, myFlags, rights))
// return;
// PresenceInfo[] friendSessions = PresenceService.GetAgents(new string[] { target.ToString() });
// if (friendSessions != null && friendSessions.Length > 0)
// {
// PresenceInfo friendSession = friendSessions[0];
// if (friendSession != null)
// {
// GridRegion region = GridService.GetRegionByUUID(m_Scenes[0].RegionInfo.ScopeID, friendSession.RegionID);
// // TODO: You might want to send the delta to save the lookup
// // on the other end!!
// m_FriendsSimConnector.GrantRights(region, requester, target, myFlags, rights);
// }
// }
// }
//}
} }
} }

View File

@ -582,15 +582,20 @@ namespace OpenSim.Region.CoreModules.World.Permissions
return objectOwnerMask; return objectOwnerMask;
if (IsFriendWithPerms(user, objectOwner)) if (IsFriendWithPerms(user, objectOwner))
{
return objectOwnerMask; return objectOwnerMask;
}
// Estate users should be able to edit anything in the sim if RegionOwnerIsGod is set // Estate users should be able to edit anything in the sim if RegionOwnerIsGod is set
if (m_RegionOwnerIsGod && IsEstateManager(user) && !IsAdministrator(objectOwner)) if (m_RegionOwnerIsGod && IsEstateManager(user) && !IsAdministrator(objectOwner))
{
return objectOwnerMask; return objectOwnerMask;
}
// Admin should be able to edit anything in the sim (including admin objects) // Admin should be able to edit anything in the sim (including admin objects)
if (IsAdministrator(user)) if (IsAdministrator(user))
{
return objectOwnerMask; return objectOwnerMask;
}
// Users should be able to edit what is over their land. // Users should be able to edit what is over their land.
Vector3 taskPos = task.AbsolutePosition; Vector3 taskPos = task.AbsolutePosition;
@ -599,8 +604,10 @@ namespace OpenSim.Region.CoreModules.World.Permissions
{ {
// Admin objects should not be editable by the above // Admin objects should not be editable by the above
if (!IsAdministrator(objectOwner)) if (!IsAdministrator(objectOwner))
{
return objectOwnerMask; return objectOwnerMask;
} }
}
// Group permissions // Group permissions
if ((task.GroupID != UUID.Zero) && IsGroupMember(task.GroupID, user, 0)) if ((task.GroupID != UUID.Zero) && IsGroupMember(task.GroupID, user, 0))
@ -673,7 +680,6 @@ namespace OpenSim.Region.CoreModules.World.Permissions
// //
// Nobody but the object owner can set permissions on an object // Nobody but the object owner can set permissions on an object
// //
if (locked && (!IsAdministrator(currentUser)) && denyOnLocked) if (locked && (!IsAdministrator(currentUser)) && denyOnLocked)
{ {
return false; return false;
@ -705,6 +711,11 @@ namespace OpenSim.Region.CoreModules.World.Permissions
return true; return true;
} }
// Friends with benefits should be able to edit the objects too
if (IsFriendWithPerms(currentUser, objectOwner))
// Return immediately, so that the administrator can share objects with friends
return true;
// Users should be able to edit what is over their land. // Users should be able to edit what is over their land.
ILandObject parcel = m_scene.LandChannel.GetLandObject(group.AbsolutePosition.X, group.AbsolutePosition.Y); ILandObject parcel = m_scene.LandChannel.GetLandObject(group.AbsolutePosition.X, group.AbsolutePosition.Y);
if ((parcel != null) && (parcel.LandData.OwnerID == currentUser)) if ((parcel != null) && (parcel.LandData.OwnerID == currentUser))

View File

@ -34,6 +34,6 @@ namespace OpenSim.Region.Framework.Interfaces
public interface IFriendsModule public interface IFriendsModule
{ {
uint GetFriendPerms(UUID PrincipalID, UUID FriendID); uint GetFriendPerms(UUID PrincipalID, UUID FriendID);
void SendFriendsOnlineIfNeeded(IClientAPI client); bool SendFriendsOnlineIfNeeded(IClientAPI client);
} }
} }

View File

@ -82,6 +82,9 @@ namespace OpenSim.Server.Handlers.Friends
case "getfriends": case "getfriends":
return GetFriends(request); return GetFriends(request);
case "getfriends_string":
return GetFriendsString(request);
case "storefriend": case "storefriend":
return StoreFriend(request); return StoreFriend(request);
@ -111,7 +114,25 @@ namespace OpenSim.Server.Handlers.Friends
m_log.WarnFormat("[FRIENDS HANDLER]: no principalID in request to get friends"); m_log.WarnFormat("[FRIENDS HANDLER]: no principalID in request to get friends");
FriendInfo[] finfos = m_FriendsService.GetFriends(principalID); FriendInfo[] finfos = m_FriendsService.GetFriends(principalID);
//m_log.DebugFormat("[FRIENDS HANDLER]: neighbours for region {0}: {1}", regionID, rinfos.Count);
return PackageFriends(finfos);
}
byte[] GetFriendsString(Dictionary<string, object> request)
{
string principalID = string.Empty;
if (request.ContainsKey("PRINCIPALID"))
principalID = request["PRINCIPALID"].ToString();
else
m_log.WarnFormat("[FRIENDS HANDLER]: no principalID in request to get friends");
FriendInfo[] finfos = m_FriendsService.GetFriends(principalID);
return PackageFriends(finfos);
}
private byte[] PackageFriends(FriendInfo[] finfos)
{
Dictionary<string, object> result = new Dictionary<string, object>(); Dictionary<string, object> result = new Dictionary<string, object>();
if ((finfos == null) || ((finfos != null) && (finfos.Length == 0))) if ((finfos == null) || ((finfos != null) && (finfos.Length == 0)))

View File

@ -82,8 +82,8 @@ namespace OpenSim.Server.Handlers.Hypergrid
switch (method) switch (method)
{ {
case "getfriends": case "getfriendperms":
return GetFriends(request); return GetFriendPerms(request);
case "newfriendship": case "newfriendship":
return NewFriendship(request); return NewFriendship(request);
@ -102,58 +102,45 @@ namespace OpenSim.Server.Handlers.Hypergrid
#region Method-specific handlers #region Method-specific handlers
byte[] GetFriends(Dictionary<string, object> request) byte[] GetFriendPerms(Dictionary<string, object> request)
{ {
if (!VerifyServiceKey(request))
return FailureResult();
UUID principalID = UUID.Zero; UUID principalID = UUID.Zero;
if (request.ContainsKey("PRINCIPALID")) if (request.ContainsKey("PRINCIPALID"))
UUID.TryParse(request["PRINCIPALID"].ToString(), out principalID); UUID.TryParse(request["PRINCIPALID"].ToString(), out principalID);
else else
m_log.WarnFormat("[HGFRIENDS HANDLER]: no principalID in request to get friends"); {
m_log.WarnFormat("[HGFRIENDS HANDLER]: no principalID in request to get friend perms");
return FailureResult();
}
FriendInfo[] finfos = m_FriendsService.GetFriends(principalID); UUID friendID = UUID.Zero;
//m_log.DebugFormat("[FRIENDS HANDLER]: neighbours for region {0}: {1}", regionID, rinfos.Count); if (request.ContainsKey("FRIENDID"))
UUID.TryParse(request["FRIENDID"].ToString(), out friendID);
Dictionary<string, object> result = new Dictionary<string, object>();
if ((finfos == null) || ((finfos != null) && (finfos.Length == 0)))
result["result"] = "null";
else else
{ {
int i = 0; m_log.WarnFormat("[HGFRIENDS HANDLER]: no friendID in request to get friend perms");
foreach (FriendInfo finfo in finfos) return FailureResult();
}
string perms = "0";
FriendInfo[] friendsInfo = m_FriendsService.GetFriends(principalID);
foreach (FriendInfo finfo in friendsInfo)
{ {
Dictionary<string, object> rinfoDict = finfo.ToKeyValuePairs(); if (finfo.Friend.StartsWith(friendID.ToString()))
result["friend" + i] = rinfoDict; return SuccessResult(finfo.TheirFlags.ToString());
i++;
}
} }
string xmlString = ServerUtils.BuildXmlResponse(result); return FailureResult("Friend not found");
//m_log.DebugFormat("[FRIENDS HANDLER]: resp string: {0}", xmlString);
UTF8Encoding encoding = new UTF8Encoding();
return encoding.GetBytes(xmlString);
} }
byte[] NewFriendship(Dictionary<string, object> request) byte[] NewFriendship(Dictionary<string, object> request)
{ {
if (!request.ContainsKey("KEY") || !request.ContainsKey("SESSIONID")) if (!VerifyServiceKey(request))
{
m_log.WarnFormat("[HGFRIENDS HANDLER]: ignoring request without Key or SessionID");
return FailureResult(); return FailureResult();
}
string serviceKey = request["KEY"].ToString();
string sessionStr = request["SESSIONID"].ToString();
UUID sessionID;
UUID.TryParse(sessionStr, out sessionID);
if (!m_UserAgentService.VerifyAgent(sessionID, serviceKey))
{
m_log.WarnFormat("[HGFRIENDS HANDLER]: Key {0} for session {1} did not match existing key. Ignoring request", serviceKey, sessionID);
return FailureResult();
}
m_log.DebugFormat("[XXX] Verification ok");
// OK, can proceed // OK, can proceed
FriendInfo friend = new FriendInfo(request); FriendInfo friend = new FriendInfo(request);
@ -172,6 +159,29 @@ namespace OpenSim.Server.Handlers.Hypergrid
#region Misc #region Misc
private bool VerifyServiceKey(Dictionary<string, object> request)
{
if (!request.ContainsKey("KEY") || !request.ContainsKey("SESSIONID"))
{
m_log.WarnFormat("[HGFRIENDS HANDLER]: ignoring request without Key or SessionID");
return false;
}
string serviceKey = request["KEY"].ToString();
string sessionStr = request["SESSIONID"].ToString();
UUID sessionID;
UUID.TryParse(sessionStr, out sessionID);
if (!m_UserAgentService.VerifyAgent(sessionID, serviceKey))
{
m_log.WarnFormat("[HGFRIENDS HANDLER]: Key {0} for session {1} did not match existing key. Ignoring request", serviceKey, sessionID);
return false;
}
m_log.DebugFormat("[XXX] Verification ok");
return true;
}
private byte[] SuccessResult() private byte[] SuccessResult()
{ {
XmlDocument doc = new XmlDocument(); XmlDocument doc = new XmlDocument();
@ -194,6 +204,34 @@ namespace OpenSim.Server.Handlers.Hypergrid
return DocToBytes(doc); return DocToBytes(doc);
} }
private byte[] SuccessResult(string value)
{
XmlDocument doc = new XmlDocument();
XmlNode xmlnode = doc.CreateNode(XmlNodeType.XmlDeclaration,
"", "");
doc.AppendChild(xmlnode);
XmlElement rootElement = doc.CreateElement("", "ServerResponse",
"");
doc.AppendChild(rootElement);
XmlElement result = doc.CreateElement("", "Result", "");
result.AppendChild(doc.CreateTextNode("Success"));
rootElement.AppendChild(result);
XmlElement message = doc.CreateElement("", "Value", "");
message.AppendChild(doc.CreateTextNode(value));
rootElement.AppendChild(message);
return DocToBytes(doc);
}
private byte[] FailureResult() private byte[] FailureResult()
{ {
return FailureResult(String.Empty); return FailureResult(String.Empty);

View File

@ -92,6 +92,21 @@ namespace OpenSim.Services.Connectors.Friends
sendData["PRINCIPALID"] = PrincipalID.ToString(); sendData["PRINCIPALID"] = PrincipalID.ToString();
sendData["METHOD"] = "getfriends"; sendData["METHOD"] = "getfriends";
return GetFriends(sendData, PrincipalID.ToString());
}
public FriendInfo[] GetFriends(string PrincipalID)
{
Dictionary<string, object> sendData = new Dictionary<string, object>();
sendData["PRINCIPALID"] = PrincipalID;
sendData["METHOD"] = "getfriends_string";
return GetFriends(sendData, PrincipalID);
}
protected FriendInfo[] GetFriends(Dictionary<string, object> sendData, string PrincipalID)
{
string reqString = ServerUtils.BuildQueryString(sendData); string reqString = ServerUtils.BuildQueryString(sendData);
try try

View File

@ -63,12 +63,13 @@ namespace OpenSim.Services.Connectors.Hypergrid
#region IFriendsService #region IFriendsService
public FriendInfo[] GetFriends(UUID PrincipalID) public uint GetFriendPerms(UUID PrincipalID, UUID friendID)
{ {
Dictionary<string, object> sendData = new Dictionary<string, object>(); Dictionary<string, object> sendData = new Dictionary<string, object>();
sendData["PRINCIPALID"] = PrincipalID.ToString(); sendData["PRINCIPALID"] = PrincipalID.ToString();
sendData["METHOD"] = "getfriends"; sendData["FRIENDID"] = friendID.ToString();
sendData["METHOD"] = "getfriendperms";
sendData["KEY"] = m_ServiceKey; sendData["KEY"] = m_ServiceKey;
sendData["SESSIONID"] = m_SessionID.ToString(); sendData["SESSIONID"] = m_SessionID.ToString();
@ -83,34 +84,14 @@ namespace OpenSim.Services.Connectors.Hypergrid
{ {
Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply); Dictionary<string, object> replyData = ServerUtils.ParseXmlResponse(reply);
if (replyData != null) if ((replyData != null) && replyData.ContainsKey("Value") && (replyData["Value"] != null))
{ {
if (replyData.ContainsKey("result") && (replyData["result"].ToString().ToLower() == "null")) uint perms = 0;
{ uint.TryParse(replyData["Value"].ToString(), out perms);
return new FriendInfo[0]; return perms;
}
List<FriendInfo> finfos = new List<FriendInfo>();
Dictionary<string, object>.ValueCollection finfosList = replyData.Values;
//m_log.DebugFormat("[FRIENDS CONNECTOR]: get neighbours returned {0} elements", rinfosList.Count);
foreach (object f in finfosList)
{
if (f is Dictionary<string, object>)
{
FriendInfo finfo = new FriendInfo((Dictionary<string, object>)f);
finfos.Add(finfo);
} }
else else
m_log.DebugFormat("[HGFRIENDS CONNECTOR]: GetFriends {0} received invalid response type {1}", m_log.DebugFormat("[HGFRIENDS CONNECTOR]: GetFriendPerms {0} received null response",
PrincipalID, f.GetType());
}
// Success
return finfos.ToArray();
}
else
m_log.DebugFormat("[HGFRIENDS CONNECTOR]: GetFriends {0} received null response",
PrincipalID); PrincipalID);
} }
@ -120,7 +101,7 @@ namespace OpenSim.Services.Connectors.Hypergrid
m_log.DebugFormat("[HGFRIENDS CONNECTOR]: Exception when contacting friends server: {0}", e.Message); m_log.DebugFormat("[HGFRIENDS CONNECTOR]: Exception when contacting friends server: {0}", e.Message);
} }
return new FriendInfo[0]; return 0;
} }

View File

@ -77,6 +77,11 @@ namespace OpenSim.Services.Connectors.SimianGrid
#region IFriendsService #region IFriendsService
public FriendInfo[] GetFriends(UUID principalID) public FriendInfo[] GetFriends(UUID principalID)
{
return GetFriends(principalID.ToString());
}
public FriendInfo[] GetFriends(string principalID)
{ {
if (String.IsNullOrEmpty(m_serverUrl)) if (String.IsNullOrEmpty(m_serverUrl))
return new FriendInfo[0]; return new FriendInfo[0];
@ -95,7 +100,14 @@ namespace OpenSim.Services.Connectors.SimianGrid
UUID friendID = friendEntry["Key"].AsUUID(); UUID friendID = friendEntry["Key"].AsUUID();
FriendInfo friend = new FriendInfo(); FriendInfo friend = new FriendInfo();
friend.PrincipalID = principalID; if (!UUID.TryParse(principalID, out friend.PrincipalID))
{
string tmp = string.Empty;
if (!Util.ParseUniversalUserIdentifier(principalID, out friend.PrincipalID, out tmp, out tmp, out tmp))
// bad record. ignore this entry
continue;
}
friend.Friend = friendID.ToString(); friend.Friend = friendID.ToString();
friend.MyFlags = friendEntry["Value"].AsInteger(); friend.MyFlags = friendEntry["Value"].AsInteger();
friend.TheirFlags = -1; friend.TheirFlags = -1;
@ -174,7 +186,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
#endregion IFriendsService #endregion IFriendsService
private OSDArray GetFriended(UUID ownerID) private OSDArray GetFriended(string ownerID)
{ {
NameValueCollection requestArgs = new NameValueCollection NameValueCollection requestArgs = new NameValueCollection
{ {
@ -195,7 +207,7 @@ namespace OpenSim.Services.Connectors.SimianGrid
} }
} }
private OSDArray GetFriendedBy(UUID ownerID) private OSDArray GetFriendedBy(string ownerID)
{ {
NameValueCollection requestArgs = new NameValueCollection NameValueCollection requestArgs = new NameValueCollection
{ {

View File

@ -63,6 +63,32 @@ namespace OpenSim.Services.Friends
return info.ToArray(); return info.ToArray();
} }
public virtual FriendInfo[] GetFriends(string PrincipalID)
{
FriendsData[] data = m_Database.GetFriends(PrincipalID);
List<FriendInfo> info = new List<FriendInfo>();
foreach (FriendsData d in data)
{
FriendInfo i = new FriendInfo();
if (!UUID.TryParse(d.PrincipalID, out i.PrincipalID))
{
string tmp = string.Empty;
if (!Util.ParseUniversalUserIdentifier(d.PrincipalID, out i.PrincipalID, out tmp, out tmp, out tmp))
// bad record. ignore this entry
continue;
}
i.Friend = d.Friend;
i.MyFlags = Convert.ToInt32(d.Data["Flags"]);
i.TheirFlags = Convert.ToInt32(d.Data["TheirFlags"]);
info.Add(i);
}
return info.ToArray();
}
public virtual bool StoreFriend(string PrincipalID, string Friend, int flags) public virtual bool StoreFriend(string PrincipalID, string Friend, int flags)
{ {
FriendsData d = new FriendsData(); FriendsData d = new FriendsData();

View File

@ -62,7 +62,7 @@ namespace OpenSim.Services.HypergridService
UUID userID; UUID userID;
if (UUID.TryParse(PrincipalID, out userID)) if (UUID.TryParse(PrincipalID, out userID))
{ {
FriendsData[] friendsData = m_Database.GetFriends(userID); FriendsData[] friendsData = m_Database.GetFriends(userID.ToString());
List<FriendsData> fList = new List<FriendsData>(friendsData); List<FriendsData> fList = new List<FriendsData>(friendsData);
if (fList.Find(delegate(FriendsData fdata) if (fList.Find(delegate(FriendsData fdata)
{ {
@ -70,6 +70,8 @@ namespace OpenSim.Services.HypergridService
}) != null) }) != null)
return false; return false;
} }
else
return false;
FriendsData d = new FriendsData(); FriendsData d = new FriendsData();
d.PrincipalID = PrincipalID; d.PrincipalID = PrincipalID;

View File

@ -74,6 +74,7 @@ namespace OpenSim.Services.Interfaces
public interface IFriendsService public interface IFriendsService
{ {
FriendInfo[] GetFriends(UUID PrincipalID); FriendInfo[] GetFriends(UUID PrincipalID);
FriendInfo[] GetFriends(string PrincipalID);
bool StoreFriend(string PrincipalID, string Friend, int flags); bool StoreFriend(string PrincipalID, string Friend, int flags);
bool Delete(UUID PrincipalID, string Friend); bool Delete(UUID PrincipalID, string Friend);
} }