diff options
author | Diva Canto | 2011-05-22 16:51:03 -0700 |
---|---|---|
committer | Diva Canto | 2011-05-22 16:51:03 -0700 |
commit | 336665e03532cf9d7a1ad65d5071e7050bf6ecd0 (patch) | |
tree | 45c7c1145de1b5af3ff198bcb29564a2547e4575 /OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs | |
parent | File to be removed (diff) | |
download | opensim-SC_OLD-336665e03532cf9d7a1ad65d5071e7050bf6ecd0.zip opensim-SC_OLD-336665e03532cf9d7a1ad65d5071e7050bf6ecd0.tar.gz opensim-SC_OLD-336665e03532cf9d7a1ad65d5071e7050bf6ecd0.tar.bz2 opensim-SC_OLD-336665e03532cf9d7a1ad65d5071e7050bf6ecd0.tar.xz |
More on HG Friends. Added Delete(string, string) across the board. Added security to friendship identifiers so that they can safely be deleted across worlds. Had to change Get(string) to use LIKE because the secret in the identifier is not always known -- affects only HG visitors. BOTTOM LINE SO FAR: HG friendships established and deleted safely across grids, local rights working but not (yet?) being transmitted back.
Diffstat (limited to 'OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs')
-rw-r--r-- | OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs | 212 |
1 files changed, 151 insertions, 61 deletions
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs index abffb94..c55839f 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs | |||
@@ -72,8 +72,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
72 | UUID id; | 72 | UUID id; |
73 | if (!UUID.TryParse(finfo.Friend, out id)) | 73 | if (!UUID.TryParse(finfo.Friend, out id)) |
74 | { | 74 | { |
75 | string url = string.Empty, first = string.Empty, last = string.Empty; | 75 | string url = string.Empty, first = string.Empty, last = string.Empty, tmp = string.Empty; |
76 | if (Util.ParseUniversalUserIdentifier(finfo.Friend, out id, out url, out first, out last)) | 76 | if (Util.ParseUniversalUserIdentifier(finfo.Friend, out id, out url, out first, out last, out tmp)) |
77 | { | 77 | { |
78 | IUserManagement uMan = m_Scenes[0].RequestModuleInterface<IUserManagement>(); | 78 | IUserManagement uMan = m_Scenes[0].RequestModuleInterface<IUserManagement>(); |
79 | uMan.AddUser(id, url + ";" + first + " " + last); | 79 | uMan.AddUser(id, url + ";" + first + " " + last); |
@@ -103,22 +103,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
103 | return false; | 103 | return false; |
104 | } | 104 | } |
105 | 105 | ||
106 | protected override FriendInfo[] GetFriendsFromService(IClientAPI client) | ||
107 | { | ||
108 | UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, client.AgentId); | ||
109 | if (account1 != null) | ||
110 | return base.GetFriendsFromService(client); | ||
111 | |||
112 | // Foreigner | ||
113 | AgentCircuitData agentClientCircuit = ((Scene)(client.Scene)).AuthenticateHandler.GetAgentCircuitData(client.CircuitCode); | ||
114 | string agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit); | ||
115 | |||
116 | FriendInfo[] finfos = FriendsService.GetFriends(agentUUI); | ||
117 | m_log.DebugFormat("[HGFRIENDS MODULE]: Fetched {0} local friends for visitor {1}", finfos.Length, agentUUI); | ||
118 | return finfos; | ||
119 | } | ||
120 | |||
121 | |||
122 | protected override bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last) | 106 | protected override bool GetAgentInfo(UUID scopeID, string fid, out UUID agentID, out string first, out string last) |
123 | { | 107 | { |
124 | first = "Unknown"; last = "User"; | 108 | first = "Unknown"; last = "User"; |
@@ -126,8 +110,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
126 | return true; | 110 | return true; |
127 | 111 | ||
128 | // fid is not a UUID... | 112 | // fid is not a UUID... |
129 | string url = string.Empty; | 113 | string url = string.Empty, tmp = string.Empty; |
130 | if (Util.ParseUniversalUserIdentifier(fid, out agentID, out url, out first, out last)) | 114 | if (Util.ParseUniversalUserIdentifier(fid, out agentID, out url, out first, out last, out tmp)) |
131 | { | 115 | { |
132 | IUserManagement userMan = m_Scenes[0].RequestModuleInterface<IUserManagement>(); | 116 | IUserManagement userMan = m_Scenes[0].RequestModuleInterface<IUserManagement>(); |
133 | userMan.AddUser(agentID, url + ";" + first + " " + last); | 117 | userMan.AddUser(agentID, url + ";" + first + " " + last); |
@@ -164,7 +148,38 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
164 | return "Please confirm this friendship you made while you were away."; | 148 | return "Please confirm this friendship you made while you were away."; |
165 | } | 149 | } |
166 | 150 | ||
167 | protected override bool SimpleStore(UUID agentID, UUID friendID, int rights) | 151 | protected override FriendInfo GetFriend(FriendInfo[] friends, UUID friendID) |
152 | { | ||
153 | foreach (FriendInfo fi in friends) | ||
154 | { | ||
155 | if (fi.Friend.StartsWith(friendID.ToString())) | ||
156 | return fi; | ||
157 | } | ||
158 | return null; | ||
159 | } | ||
160 | |||
161 | |||
162 | protected override FriendInfo[] GetFriendsFromService(IClientAPI client) | ||
163 | { | ||
164 | UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, client.AgentId); | ||
165 | if (account1 != null) | ||
166 | return base.GetFriendsFromService(client); | ||
167 | |||
168 | FriendInfo[] finfos = new FriendInfo[0]; | ||
169 | // Foreigner | ||
170 | AgentCircuitData agentClientCircuit = ((Scene)(client.Scene)).AuthenticateHandler.GetAgentCircuitData(client.CircuitCode); | ||
171 | if (agentClientCircuit != null) | ||
172 | { | ||
173 | string agentUUI = Util.ProduceUserUniversalIdentifier(agentClientCircuit); | ||
174 | |||
175 | m_log.DebugFormat("[XXX] GetFriendsFromService to {0}", agentUUI); | ||
176 | finfos = FriendsService.GetFriends(agentUUI); | ||
177 | m_log.DebugFormat("[HGFRIENDS MODULE]: Fetched {0} local friends for visitor {1}", finfos.Length, agentUUI); | ||
178 | } | ||
179 | return finfos; | ||
180 | } | ||
181 | |||
182 | protected override bool StoreRights(UUID agentID, UUID friendID, int rights) | ||
168 | { | 183 | { |
169 | UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID); | 184 | UserAccount account1 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID); |
170 | UserAccount account2 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friendID); | 185 | UserAccount account2 = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, friendID); |
@@ -172,30 +187,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
172 | if (account1 != null && account2 != null) | 187 | if (account1 != null && account2 != null) |
173 | { | 188 | { |
174 | // local grid users | 189 | // local grid users |
175 | return base.SimpleStore(agentID, friendID, rights); | 190 | return base.StoreRights(agentID, friendID, rights); |
176 | } | 191 | } |
177 | 192 | ||
178 | if (account1 != null) | 193 | if (account1 != null) // agent is local, friend is foreigner |
179 | { | 194 | { |
180 | FriendInfo[] finfos = GetFriends(agentID); | 195 | FriendInfo[] finfos = GetFriends(agentID); |
181 | if (finfos.Length > 0) | 196 | FriendInfo finfo = GetFriend(finfos, friendID); |
197 | if (finfo != null) | ||
182 | { | 198 | { |
183 | FriendInfo finfo = GetFriend(finfos, friendID); | ||
184 | FriendsService.StoreFriend(agentID.ToString(), finfo.Friend, rights); | 199 | FriendsService.StoreFriend(agentID.ToString(), finfo.Friend, rights); |
185 | return true; | 200 | return true; |
186 | } | 201 | } |
187 | } | 202 | } |
188 | if (account2 != null) | 203 | |
204 | if (account2 != null) // agent is foreigner, friend is local | ||
189 | { | 205 | { |
190 | IClientAPI client = LocateClientObject(agentID); | 206 | string agentUUI = GetUUI(friendID, agentID); |
191 | if (client != null) | 207 | if (agentUUI != string.Empty) |
192 | { | 208 | { |
193 | AgentCircuitData acircuit = m_Scenes[0].AuthenticateHandler.GetAgentCircuitData(client.CircuitCode); | 209 | FriendsService.StoreFriend(agentUUI, friendID.ToString(), rights); |
194 | if (acircuit != null) | 210 | return true; |
195 | { | ||
196 | FriendsService.StoreFriend(Util.ProduceUserUniversalIdentifier(acircuit), friendID.ToString(), rights); | ||
197 | return true; | ||
198 | } | ||
199 | } | 211 | } |
200 | } | 212 | } |
201 | 213 | ||
@@ -233,7 +245,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
233 | return; | 245 | return; |
234 | } | 246 | } |
235 | 247 | ||
236 | |||
237 | // ok, at least one of them is foreigner, let's get their data | 248 | // ok, at least one of them is foreigner, let's get their data |
238 | IClientAPI agentClient = LocateClientObject(agentID); | 249 | IClientAPI agentClient = LocateClientObject(agentID); |
239 | IClientAPI friendClient = LocateClientObject(friendID); | 250 | IClientAPI friendClient = LocateClientObject(friendID); |
@@ -257,13 +268,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
257 | friendFriendService = friendClientCircuit.ServiceURLs["FriendsServerURI"].ToString(); | 268 | friendFriendService = friendClientCircuit.ServiceURLs["FriendsServerURI"].ToString(); |
258 | } | 269 | } |
259 | 270 | ||
260 | m_log.DebugFormat("[XXX] HG Friendship! thisUUI={0}; friendUUI={1}; foreignThisFriendService={2}; foreignFriendFriendService={3}", | 271 | m_log.DebugFormat("[HGFRIENDS MODULE] HG Friendship! thisUUI={0}; friendUUI={1}; foreignThisFriendService={2}; foreignFriendFriendService={3}", |
261 | agentUUI, friendUUI, agentFriendService, friendFriendService); | 272 | agentUUI, friendUUI, agentFriendService, friendFriendService); |
262 | 273 | ||
274 | // Generate a random 8-character hex number that will sign this friendship | ||
275 | string secret = UUID.Random().ToString().Substring(0, 8); | ||
276 | |||
263 | if (agentAccount != null) // agent is local, 'friend' is foreigner | 277 | if (agentAccount != null) // agent is local, 'friend' is foreigner |
264 | { | 278 | { |
265 | // This may happen when the agent returned home, in which case the friend is not there | 279 | // This may happen when the agent returned home, in which case the friend is not there |
266 | // We need to llok for its information in the friends list itself | 280 | // We need to look for its information in the friends list itself |
281 | bool confirming = false; | ||
267 | if (friendUUI == string.Empty) | 282 | if (friendUUI == string.Empty) |
268 | { | 283 | { |
269 | FriendInfo[] finfos = GetFriends(agentID); | 284 | FriendInfo[] finfos = GetFriends(agentID); |
@@ -272,35 +287,41 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
272 | if (finfo.TheirFlags == -1) | 287 | if (finfo.TheirFlags == -1) |
273 | { | 288 | { |
274 | if (finfo.Friend.StartsWith(friendID.ToString())) | 289 | if (finfo.Friend.StartsWith(friendID.ToString())) |
290 | { | ||
275 | friendUUI = finfo.Friend; | 291 | friendUUI = finfo.Friend; |
292 | confirming = true; | ||
293 | } | ||
276 | } | 294 | } |
277 | } | 295 | } |
278 | } | 296 | } |
279 | 297 | ||
298 | // If it's confirming the friendship, we already have the full friendUUI with the secret | ||
299 | string theFriendUUID = confirming ? friendUUI : friendUUI + ";" + secret; | ||
300 | |||
280 | // store in the local friends service a reference to the foreign friend | 301 | // store in the local friends service a reference to the foreign friend |
281 | FriendsService.StoreFriend(agentID.ToString(), friendUUI, 1); | 302 | FriendsService.StoreFriend(agentID.ToString(), theFriendUUID, 1); |
282 | // and also the converse | 303 | // and also the converse |
283 | FriendsService.StoreFriend(friendUUI, agentID.ToString(), 1); | 304 | FriendsService.StoreFriend(theFriendUUID, agentID.ToString(), 1); |
284 | 305 | ||
285 | if (friendClientCircuit != null) | 306 | if (!confirming && friendClientCircuit != null) |
286 | { | 307 | { |
287 | // store in the foreign friends service a reference to the local agent | 308 | // store in the foreign friends service a reference to the local agent |
288 | HGFriendsServicesConnector friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID); | 309 | HGFriendsServicesConnector friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID); |
289 | friendsConn.NewFriendship(friendID, agentUUI); | 310 | friendsConn.NewFriendship(friendID, agentUUI + ";" + secret); |
290 | } | 311 | } |
291 | } | 312 | } |
292 | else if (friendAccount != null) // 'friend' is local, agent is foreigner | 313 | else if (friendAccount != null) // 'friend' is local, agent is foreigner |
293 | { | 314 | { |
294 | // store in the local friends service a reference to the foreign agent | 315 | // store in the local friends service a reference to the foreign agent |
295 | FriendsService.StoreFriend(friendID.ToString(), agentUUI, 1); | 316 | FriendsService.StoreFriend(friendID.ToString(), agentUUI + ";" + secret, 1); |
296 | // and also the converse | 317 | // and also the converse |
297 | FriendsService.StoreFriend(agentUUI, friendID.ToString(), 1); | 318 | FriendsService.StoreFriend(agentUUI + ";" + secret, friendID.ToString(), 1); |
298 | 319 | ||
299 | if (agentClientCircuit != null) | 320 | if (agentClientCircuit != null) |
300 | { | 321 | { |
301 | // store in the foreign friends service a reference to the local agent | 322 | // store in the foreign friends service a reference to the local agent |
302 | HGFriendsServicesConnector friendsConn = new HGFriendsServicesConnector(agentFriendService, agentClientCircuit.SessionID, agentClientCircuit.ServiceSessionID); | 323 | HGFriendsServicesConnector friendsConn = new HGFriendsServicesConnector(agentFriendService, agentClientCircuit.SessionID, agentClientCircuit.ServiceSessionID); |
303 | friendsConn.NewFriendship(agentID, friendUUI); | 324 | friendsConn.NewFriendship(agentID, friendUUI + ";" + secret); |
304 | } | 325 | } |
305 | } | 326 | } |
306 | else // They're both foreigners! | 327 | else // They're both foreigners! |
@@ -309,43 +330,112 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends | |||
309 | if (agentClientCircuit != null) | 330 | if (agentClientCircuit != null) |
310 | { | 331 | { |
311 | friendsConn = new HGFriendsServicesConnector(agentFriendService, agentClientCircuit.SessionID, agentClientCircuit.ServiceSessionID); | 332 | friendsConn = new HGFriendsServicesConnector(agentFriendService, agentClientCircuit.SessionID, agentClientCircuit.ServiceSessionID); |
312 | friendsConn.NewFriendship(agentID, friendUUI); | 333 | friendsConn.NewFriendship(agentID, friendUUI + ";" + secret); |
313 | } | 334 | } |
314 | if (friendClientCircuit != null) | 335 | if (friendClientCircuit != null) |
315 | { | 336 | { |
316 | friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID); | 337 | friendsConn = new HGFriendsServicesConnector(friendFriendService, friendClientCircuit.SessionID, friendClientCircuit.ServiceSessionID); |
317 | friendsConn.NewFriendship(friendID, agentUUI); | 338 | friendsConn.NewFriendship(friendID, agentUUI + ";" + secret); |
318 | } | 339 | } |
319 | } | 340 | } |
320 | // my brain hurts now | 341 | // my brain hurts now |
321 | } | 342 | } |
322 | 343 | ||
323 | protected override FriendInfo GetFriend(FriendInfo[] friends, UUID friendID) | 344 | protected override bool DeleteFriendship(UUID agentID, UUID exfriendID) |
324 | { | 345 | { |
325 | foreach (FriendInfo fi in friends) | 346 | UserAccount agentAccount = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, agentID); |
347 | UserAccount friendAccount = UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, exfriendID); | ||
348 | // Are they both local users? | ||
349 | if (agentAccount != null && friendAccount != null) | ||
326 | { | 350 | { |
327 | if (fi.Friend.StartsWith(friendID.ToString())) | 351 | // local grid users |
328 | return fi; | 352 | return base.DeleteFriendship(agentID, exfriendID); |
329 | } | 353 | } |
330 | return null; | 354 | |
355 | // ok, at least one of them is foreigner, let's get their data | ||
356 | string agentUUI = string.Empty; | ||
357 | string friendUUI = string.Empty; | ||
358 | |||
359 | if (agentAccount != null) // agent is local, 'friend' is foreigner | ||
360 | { | ||
361 | // We need to look for its information in the friends list itself | ||
362 | FriendInfo[] finfos = GetFriends(agentID); | ||
363 | FriendInfo finfo = GetFriend(finfos, exfriendID); | ||
364 | if (finfo != null) | ||
365 | { | ||
366 | friendUUI = finfo.Friend; | ||
367 | |||
368 | // delete in the local friends service the reference to the foreign friend | ||
369 | FriendsService.Delete(agentID, friendUUI); | ||
370 | // and also the converse | ||
371 | FriendsService.Delete(friendUUI, agentID.ToString()); | ||
372 | |||
373 | // notify the exfriend's service | ||
374 | Util.FireAndForget(delegate { Delete(exfriendID, agentID, friendUUI); }); | ||
375 | |||
376 | m_log.DebugFormat("[HGFRIENDS MODULE]: {0} terminated {1}", agentID, friendUUI); | ||
377 | return true; | ||
378 | } | ||
379 | } | ||
380 | else if (friendAccount != null) // agent is foreigner, 'friend' is local | ||
381 | { | ||
382 | agentUUI = GetUUI(exfriendID, agentID); | ||
383 | |||
384 | if (agentUUI != string.Empty) | ||
385 | { | ||
386 | // delete in the local friends service the reference to the foreign agent | ||
387 | FriendsService.Delete(exfriendID, agentUUI); | ||
388 | // and also the converse | ||
389 | FriendsService.Delete(agentUUI, exfriendID.ToString()); | ||
390 | |||
391 | // notify the agent's service? | ||
392 | Util.FireAndForget(delegate { Delete(agentID, exfriendID, agentUUI); }); | ||
393 | |||
394 | m_log.DebugFormat("[HGFRIENDS MODULE]: {0} terminated {1}", agentUUI, exfriendID); | ||
395 | return true; | ||
396 | } | ||
397 | } | ||
398 | //else They're both foreigners! Can't handle this | ||
399 | |||
400 | return false; | ||
331 | } | 401 | } |
332 | 402 | ||
333 | protected override void DeleteFriendship(UUID agentID, UUID exfriendID) | 403 | private string GetUUI(UUID localUser, UUID foreignUser) |
334 | { | 404 | { |
335 | base.DeleteFriendship(agentID, exfriendID); | 405 | // Let's see if the user is here by any chance |
336 | // Maybe some of the base deletes will fail. | 406 | FriendInfo[] finfos = GetFriends(localUser); |
337 | // Let's delete the local friendship with foreign friend | 407 | if (finfos != EMPTY_FRIENDS) // friend is here, cool |
338 | FriendInfo[] friends = GetFriends(agentID); | ||
339 | foreach (FriendInfo finfo in friends) | ||
340 | { | 408 | { |
341 | if (finfo.Friend != exfriendID.ToString() && finfo.Friend.StartsWith(exfriendID.ToString())) | 409 | FriendInfo finfo = GetFriend(finfos, foreignUser); |
410 | if (finfo != null) | ||
342 | { | 411 | { |
343 | FriendsService.Delete(agentID, exfriendID.ToString()); | 412 | return finfo.Friend; |
344 | // TODO: delete the friendship on the other side | ||
345 | // Should use the homeurl given in finfo.Friend | ||
346 | } | 413 | } |
347 | } | 414 | } |
415 | else // user is not currently on this sim, need to get from the service | ||
416 | { | ||
417 | finfos = FriendsService.GetFriends(localUser); | ||
418 | foreach (FriendInfo finfo in finfos) | ||
419 | { | ||
420 | if (finfo.Friend.StartsWith(foreignUser.ToString())) // found it! | ||
421 | { | ||
422 | return finfo.Friend; | ||
423 | } | ||
424 | } | ||
425 | } | ||
426 | return string.Empty; | ||
348 | } | 427 | } |
349 | 428 | ||
429 | private void Delete(UUID foreignUser, UUID localUser, string uui) | ||
430 | { | ||
431 | UUID id; | ||
432 | string url = string.Empty, secret = string.Empty, tmp = string.Empty; | ||
433 | if (Util.ParseUniversalUserIdentifier(uui, out id, out url, out tmp, out tmp, out secret)) | ||
434 | { | ||
435 | m_log.DebugFormat("[HGFRIENDS MODULE]: Deleting friendship from {0}", url); | ||
436 | HGFriendsServicesConnector friendConn = new HGFriendsServicesConnector(url); | ||
437 | friendConn.DeleteFriendship(foreignUser, localUser, secret); | ||
438 | } | ||
439 | } | ||
350 | } | 440 | } |
351 | } | 441 | } |