opensim-development – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 eva 1 /*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSimulator Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27  
28 using System;
29 using System.Collections.Generic;
30 using System.Reflection;
31 using System.Timers;
32 using log4net;
33 using Nini.Config;
34  
35 using OpenMetaverse;
36 using OpenSim.Data;
37 using OpenSim.Framework;
38 using OpenSim.Services.Interfaces;
39  
40 namespace OpenSim.Groups
41 {
42 public class GroupsService : GroupsServiceBase
43 {
44 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
45  
46 public const GroupPowers DefaultEveryonePowers = GroupPowers.AllowSetHome |
47 GroupPowers.Accountable |
48 GroupPowers.JoinChat |
49 GroupPowers.AllowVoiceChat |
50 GroupPowers.ReceiveNotices |
51 GroupPowers.StartProposal |
52 GroupPowers.VoteOnProposal;
53  
54 public const GroupPowers OwnerPowers = GroupPowers.Accountable |
55 GroupPowers.AllowEditLand |
56 GroupPowers.AllowFly |
57 GroupPowers.AllowLandmark |
58 GroupPowers.AllowRez |
59 GroupPowers.AllowSetHome |
60 GroupPowers.AllowVoiceChat |
61 GroupPowers.AssignMember |
62 GroupPowers.AssignMemberLimited |
63 GroupPowers.ChangeActions |
64 GroupPowers.ChangeIdentity |
65 GroupPowers.ChangeMedia |
66 GroupPowers.ChangeOptions |
67 GroupPowers.CreateRole |
68 GroupPowers.DeedObject |
69 GroupPowers.DeleteRole |
70 GroupPowers.Eject |
71 GroupPowers.FindPlaces |
72 GroupPowers.Invite |
73 GroupPowers.JoinChat |
74 GroupPowers.LandChangeIdentity |
75 GroupPowers.LandDeed |
76 GroupPowers.LandDivideJoin |
77 GroupPowers.LandEdit |
78 GroupPowers.LandEjectAndFreeze |
79 GroupPowers.LandGardening |
80 GroupPowers.LandManageAllowed |
81 GroupPowers.LandManageBanned |
82 GroupPowers.LandManagePasses |
83 GroupPowers.LandOptions |
84 GroupPowers.LandRelease |
85 GroupPowers.LandSetSale |
86 GroupPowers.ModerateChat |
87 GroupPowers.ObjectManipulate |
88 GroupPowers.ObjectSetForSale |
89 GroupPowers.ReceiveNotices |
90 GroupPowers.RemoveMember |
91 GroupPowers.ReturnGroupOwned |
92 GroupPowers.ReturnGroupSet |
93 GroupPowers.ReturnNonGroup |
94 GroupPowers.RoleProperties |
95 GroupPowers.SendNotices |
96 GroupPowers.SetLandingPoint |
97 GroupPowers.StartProposal |
98 GroupPowers.VoteOnProposal;
99  
100 #region Daily Cleanup
101  
102 private Timer m_CleanupTimer;
103  
104 public GroupsService(IConfigSource config, string configName)
105 : base(config, configName)
106 {
107 }
108  
109 public GroupsService(IConfigSource config)
110 : this(config, string.Empty)
111 {
112 // Once a day
113 m_CleanupTimer = new Timer(24 * 60 * 60 * 1000);
114 m_CleanupTimer.AutoReset = true;
115 m_CleanupTimer.Elapsed += new ElapsedEventHandler(m_CleanupTimer_Elapsed);
116 m_CleanupTimer.Enabled = true;
117 m_CleanupTimer.Start();
118 }
119  
120 private void m_CleanupTimer_Elapsed(object sender, ElapsedEventArgs e)
121 {
122 m_Database.DeleteOldNotices();
123 m_Database.DeleteOldInvites();
124 }
125  
126 #endregion
127  
128 public UUID CreateGroup(string RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment,
129 bool allowPublish, bool maturePublish, UUID founderID, out string reason)
130 {
131 reason = string.Empty;
132  
133 // Check if the group already exists
134 if (m_Database.RetrieveGroup(name) != null)
135 {
136 reason = "A group with that name already exists";
137 return UUID.Zero;
138 }
139  
140 // Create the group
141 GroupData data = new GroupData();
142 data.GroupID = UUID.Random();
143 data.Data = new Dictionary<string, string>();
144 data.Data["Name"] = name;
145 data.Data["Charter"] = charter;
146 data.Data["InsigniaID"] = insigniaID.ToString();
147 data.Data["FounderID"] = founderID.ToString();
148 data.Data["MembershipFee"] = membershipFee.ToString();
149 data.Data["OpenEnrollment"] = openEnrollment ? "1" : "0";
150 data.Data["ShowInList"] = showInList ? "1" : "0";
151 data.Data["AllowPublish"] = allowPublish ? "1" : "0";
152 data.Data["MaturePublish"] = maturePublish ? "1" : "0";
153 data.Data["OwnerRoleID"] = UUID.Random().ToString();
154  
155 if (!m_Database.StoreGroup(data))
156 return UUID.Zero;
157  
158 // Create Everyone role
159 _AddOrUpdateGroupRole(RequestingAgentID, data.GroupID, UUID.Zero, "Everyone", "Everyone in the group", "Member of " + name, (ulong)DefaultEveryonePowers, true);
160  
161 // Create Owner role
162 UUID roleID = UUID.Random();
163 _AddOrUpdateGroupRole(RequestingAgentID, data.GroupID, roleID, "Owners", "Owners of the group", "Owner of " + name, (ulong)OwnerPowers, true);
164  
165 // Add founder to group
166 _AddAgentToGroup(RequestingAgentID, founderID.ToString(), data.GroupID, roleID);
167  
168 return data.GroupID;
169 }
170  
171 public void UpdateGroup(string RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish)
172 {
173 GroupData data = m_Database.RetrieveGroup(groupID);
174 if (data == null)
175 return;
176  
177 // Check perms
178 if (!HasPower(RequestingAgentID, groupID, GroupPowers.ChangeActions))
179 {
180 m_log.DebugFormat("[Groups]: ({0}) Attempt at updating group {1} denied because of lack of permission", RequestingAgentID, groupID);
181 return;
182 }
183  
184 data.GroupID = groupID;
185 data.Data["Charter"] = charter;
186 data.Data["ShowInList"] = showInList ? "1" : "0";
187 data.Data["InsigniaID"] = insigniaID.ToString();
188 data.Data["MembershipFee"] = membershipFee.ToString();
189 data.Data["OpenEnrollment"] = openEnrollment ? "1" : "0";
190 data.Data["AllowPublish"] = allowPublish ? "1" : "0";
191 data.Data["MaturePublish"] = maturePublish ? "1" : "0";
192  
193 m_Database.StoreGroup(data);
194  
195 }
196  
197 public ExtendedGroupRecord GetGroupRecord(string RequestingAgentID, UUID GroupID)
198 {
199 GroupData data = m_Database.RetrieveGroup(GroupID);
200  
201 return _GroupDataToRecord(data);
202 }
203  
204 public ExtendedGroupRecord GetGroupRecord(string RequestingAgentID, string GroupName)
205 {
206 GroupData data = m_Database.RetrieveGroup(GroupName);
207  
208 return _GroupDataToRecord(data);
209 }
210  
211 public List<DirGroupsReplyData> FindGroups(string RequestingAgentID, string search)
212 {
213 List<DirGroupsReplyData> groups = new List<DirGroupsReplyData>();
214  
215 GroupData[] data = m_Database.RetrieveGroups(search);
216  
217 if (data != null && data.Length > 0)
218 {
219 foreach (GroupData d in data)
220 {
221 // Don't list group proxies
222 if (d.Data.ContainsKey("Location") && d.Data["Location"] != string.Empty)
223 continue;
224  
225 DirGroupsReplyData g = new DirGroupsReplyData();
226 g.groupID = d.GroupID;
227  
228 if (d.Data.ContainsKey("Name"))
229 g.groupName = d.Data["Name"];
230 else
231 m_log.DebugFormat("[Groups]: Key Name not found");
232  
233 g.members = m_Database.MemberCount(d.GroupID);
234  
235 groups.Add(g);
236 }
237 }
238  
239 return groups;
240 }
241  
242 public List<ExtendedGroupMembersData> GetGroupMembers(string RequestingAgentID, UUID GroupID)
243 {
244 List<ExtendedGroupMembersData> members = new List<ExtendedGroupMembersData>();
245  
246 GroupData group = m_Database.RetrieveGroup(GroupID);
247 if (group == null)
248 return members;
249  
250 UUID ownerRoleID = new UUID(group.Data["OwnerRoleID"]);
251  
252 RoleData[] roles = m_Database.RetrieveRoles(GroupID);
253 if (roles == null)
254 // something wrong with this group
255 return members;
256 List<RoleData> rolesList = new List<RoleData>(roles);
257  
258 // Check visibility?
259 // When we don't want to check visibility, we pass it "all" as the requestingAgentID
260 bool checkVisibility = !RequestingAgentID.Equals(UUID.Zero.ToString());
261  
262 if (checkVisibility)
263 {
264 // Is the requester a member of the group?
265 bool isInGroup = false;
266 if (m_Database.RetrieveMember(GroupID, RequestingAgentID) != null)
267 isInGroup = true;
268  
269 if (!isInGroup) // reduce the roles to the visible ones
270 rolesList = rolesList.FindAll(r => (UInt64.Parse(r.Data["Powers"]) & (ulong)GroupPowers.MemberVisible) != 0);
271 }
272  
273 MembershipData[] datas = m_Database.RetrieveMembers(GroupID);
274 if (datas == null || (datas != null && datas.Length == 0))
275 return members;
276  
277 // OK, we have everything we need
278  
279 foreach (MembershipData d in datas)
280 {
281 RoleMembershipData[] rolememberships = m_Database.RetrieveMemberRoles(GroupID, d.PrincipalID);
282 List<RoleMembershipData> rolemembershipsList = new List<RoleMembershipData>(rolememberships);
283  
284 ExtendedGroupMembersData m = new ExtendedGroupMembersData();
285  
286 // What's this person's current role in the group?
287 UUID selectedRole = new UUID(d.Data["SelectedRoleID"]);
288 RoleData selected = rolesList.Find(r => r.RoleID == selectedRole);
289  
290 if (selected != null)
291 {
292 m.Title = selected.Data["Title"];
293 m.AgentPowers = UInt64.Parse(selected.Data["Powers"]);
294  
295 m.AgentID = d.PrincipalID;
296 m.AcceptNotices = d.Data["AcceptNotices"] == "1" ? true : false;
297 m.Contribution = Int32.Parse(d.Data["Contribution"]);
298 m.ListInProfile = d.Data["ListInProfile"] == "1" ? true : false;
299  
300 // Is this person an owner of the group?
301 m.IsOwner = (rolemembershipsList.Find(r => r.RoleID == ownerRoleID) != null) ? true : false;
302  
303 members.Add(m);
304 }
305 }
306  
307 return members;
308 }
309  
310 public bool AddGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers, out string reason)
311 {
312 reason = string.Empty;
313 // check that the requesting agent has permissions to add role
314 if (!HasPower(RequestingAgentID, groupID, GroupPowers.CreateRole))
315 {
316 m_log.DebugFormat("[Groups]: ({0}) Attempt at creating role in group {1} denied because of lack of permission", RequestingAgentID, groupID);
317 reason = "Insufficient permission to create role";
318 return false;
319 }
320  
321 return _AddOrUpdateGroupRole(RequestingAgentID, groupID, roleID, name, description, title, powers, true);
322  
323 }
324  
325 public bool UpdateGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers)
326 {
327 // check perms
328 if (!HasPower(RequestingAgentID, groupID, GroupPowers.ChangeActions))
329 {
330 m_log.DebugFormat("[Groups]: ({0}) Attempt at changing role in group {1} denied because of lack of permission", RequestingAgentID, groupID);
331 return false;
332 }
333  
334 return _AddOrUpdateGroupRole(RequestingAgentID, groupID, roleID, name, description, title, powers, false);
335 }
336  
337 public void RemoveGroupRole(string RequestingAgentID, UUID groupID, UUID roleID)
338 {
339 // check perms
340 if (!HasPower(RequestingAgentID, groupID, GroupPowers.DeleteRole))
341 {
342 m_log.DebugFormat("[Groups]: ({0}) Attempt at deleting role from group {1} denied because of lack of permission", RequestingAgentID, groupID);
343 return;
344 }
345  
346 // Can't delete Everyone and Owners roles
347 if (roleID == UUID.Zero)
348 {
349 m_log.DebugFormat("[Groups]: Attempt at deleting Everyone role from group {0} denied", groupID);
350 return;
351 }
352  
353 GroupData group = m_Database.RetrieveGroup(groupID);
354 if (group == null)
355 {
356 m_log.DebugFormat("[Groups]: Attempt at deleting role from non-existing group {0}", groupID);
357 return;
358 }
359  
360 if (roleID == new UUID(group.Data["OwnerRoleID"]))
361 {
362 m_log.DebugFormat("[Groups]: Attempt at deleting Owners role from group {0} denied", groupID);
363 return;
364 }
365  
366 _RemoveGroupRole(groupID, roleID);
367 }
368  
369 public List<GroupRolesData> GetGroupRoles(string RequestingAgentID, UUID GroupID)
370 {
371 // TODO: check perms
372 return _GetGroupRoles(GroupID);
373 }
374  
375 public List<ExtendedGroupRoleMembersData> GetGroupRoleMembers(string RequestingAgentID, UUID GroupID)
376 {
377 // TODO: check perms
378  
379 // Is the requester a member of the group?
380 bool isInGroup = false;
381 if (m_Database.RetrieveMember(GroupID, RequestingAgentID) != null)
382 isInGroup = true;
383  
384 return _GetGroupRoleMembers(GroupID, isInGroup);
385 }
386  
387 public bool AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, string token, out string reason)
388 {
389 reason = string.Empty;
390  
391 _AddAgentToGroup(RequestingAgentID, AgentID, GroupID, RoleID, token);
392  
393 return true;
394 }
395  
396 public void RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID)
397 {
398 // check perms
399 if (RequestingAgentID != AgentID && !HasPower(RequestingAgentID, GroupID, GroupPowers.Eject))
400 return;
401  
402 _RemoveAgentFromGroup(RequestingAgentID, AgentID, GroupID);
403 }
404  
405 public bool AddAgentToGroupInvite(string RequestingAgentID, UUID inviteID, UUID groupID, UUID roleID, string agentID)
406 {
407 // Check whether the invitee is already a member of the group
408 MembershipData m = m_Database.RetrieveMember(groupID, agentID);
409 if (m != null)
410 return false;
411  
412 // Check permission to invite
413 if (!HasPower(RequestingAgentID, groupID, GroupPowers.Invite))
414 {
415 m_log.DebugFormat("[Groups]: ({0}) Attempt at inviting to group {1} denied because of lack of permission", RequestingAgentID, groupID);
416 return false;
417 }
418  
419 // Check whether there are pending invitations and delete them
420 InvitationData invite = m_Database.RetrieveInvitation(groupID, agentID);
421 if (invite != null)
422 m_Database.DeleteInvite(invite.InviteID);
423  
424 invite = new InvitationData();
425 invite.InviteID = inviteID;
426 invite.PrincipalID = agentID;
427 invite.GroupID = groupID;
428 invite.RoleID = roleID;
429 invite.Data = new Dictionary<string, string>();
430  
431 return m_Database.StoreInvitation(invite);
432 }
433  
434 public GroupInviteInfo GetAgentToGroupInvite(string RequestingAgentID, UUID inviteID)
435 {
436 InvitationData data = m_Database.RetrieveInvitation(inviteID);
437  
438 if (data == null)
439 return null;
440  
441 GroupInviteInfo inviteInfo = new GroupInviteInfo();
442 inviteInfo.AgentID = data.PrincipalID;
443 inviteInfo.GroupID = data.GroupID;
444 inviteInfo.InviteID = data.InviteID;
445 inviteInfo.RoleID = data.RoleID;
446  
447 return inviteInfo;
448 }
449  
450 public void RemoveAgentToGroupInvite(string RequestingAgentID, UUID inviteID)
451 {
452 m_Database.DeleteInvite(inviteID);
453 }
454  
455 public bool AddAgentToGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
456 {
457 //if (!m_Database.CheckOwnerRole(RequestingAgentID, GroupID, RoleID))
458 // return;
459  
460 // check permissions
461 bool limited = HasPower(RequestingAgentID, GroupID, GroupPowers.AssignMemberLimited);
462 bool unlimited = HasPower(RequestingAgentID, GroupID, GroupPowers.AssignMember) | IsOwner(RequestingAgentID, GroupID);
463 if (!limited || !unlimited)
464 {
465 m_log.DebugFormat("[Groups]: ({0}) Attempt at assigning {1} to role {2} denied because of lack of permission", RequestingAgentID, AgentID, RoleID);
466 return false;
467 }
468  
469 // AssignMemberLimited means that the person can assign another person to the same roles that she has in the group
470 if (!unlimited && limited)
471 {
472 // check whether person's has this role
473 RoleMembershipData rolemembership = m_Database.RetrieveRoleMember(GroupID, RoleID, AgentID);
474 if (rolemembership == null)
475 {
476 m_log.DebugFormat("[Groups]: ({0}) Attempt at assigning {1} to role {2} denied because of limited permission", RequestingAgentID, AgentID, RoleID);
477 return false;
478 }
479 }
480  
481 _AddAgentToGroupRole(RequestingAgentID, AgentID, GroupID, RoleID);
482  
483 return true;
484 }
485  
486 public bool RemoveAgentFromGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
487 {
488 // Don't remove from Everyone role!
489 if (RoleID == UUID.Zero)
490 return false;
491  
492 // check permissions
493 bool unlimited = HasPower(RequestingAgentID, GroupID, GroupPowers.AssignMember) || IsOwner(RequestingAgentID, GroupID);
494 if (!unlimited)
495 {
496 m_log.DebugFormat("[Groups]: ({0}) Attempt at removing {1} from role {2} denied because of lack of permission", RequestingAgentID, AgentID, RoleID);
497 return false;
498 }
499  
500 RoleMembershipData rolemember = m_Database.RetrieveRoleMember(GroupID, RoleID, AgentID);
501  
502 if (rolemember == null)
503 return false;
504  
505 m_Database.DeleteRoleMember(rolemember);
506  
507 // Find another role for this person
508 UUID newRoleID = UUID.Zero; // Everyone
509 RoleMembershipData[] rdata = m_Database.RetrieveMemberRoles(GroupID, AgentID);
510 if (rdata != null)
511 foreach (RoleMembershipData r in rdata)
512 {
513 if (r.RoleID != UUID.Zero)
514 {
515 newRoleID = r.RoleID;
516 break;
517 }
518 }
519  
520 MembershipData member = m_Database.RetrieveMember(GroupID, AgentID);
521 if (member != null)
522 {
523 member.Data["SelectedRoleID"] = newRoleID.ToString();
524 m_Database.StoreMember(member);
525 }
526  
527 return true;
528 }
529  
530 public List<GroupRolesData> GetAgentGroupRoles(string RequestingAgentID, string AgentID, UUID GroupID)
531 {
532 List<GroupRolesData> roles = new List<GroupRolesData>();
533 // TODO: check permissions
534  
535 RoleMembershipData[] data = m_Database.RetrieveMemberRoles(GroupID, AgentID);
536 if (data == null || (data != null && data.Length ==0))
537 return roles;
538  
539 foreach (RoleMembershipData d in data)
540 {
541 RoleData rdata = m_Database.RetrieveRole(GroupID, d.RoleID);
542 if (rdata == null) // hippos
543 continue;
544  
545 GroupRolesData r = new GroupRolesData();
546 r.Name = rdata.Data["Name"];
547 r.Powers = UInt64.Parse(rdata.Data["Powers"]);
548 r.RoleID = rdata.RoleID;
549 r.Title = rdata.Data["Title"];
550  
551 roles.Add(r);
552 }
553  
554 return roles;
555 }
556  
557 public ExtendedGroupMembershipData SetAgentActiveGroup(string RequestingAgentID, string AgentID, UUID GroupID)
558 {
559 // TODO: check perms
560 PrincipalData principal = new PrincipalData();
561 principal.PrincipalID = AgentID;
562 principal.ActiveGroupID = GroupID;
563 m_Database.StorePrincipal(principal);
564  
565 return GetAgentGroupMembership(RequestingAgentID, AgentID, GroupID);
566 }
567  
568 public ExtendedGroupMembershipData GetAgentActiveMembership(string RequestingAgentID, string AgentID)
569 {
570 // 1. get the principal data for the active group
571 PrincipalData principal = m_Database.RetrievePrincipal(AgentID);
572 if (principal == null)
573 return null;
574  
575 return GetAgentGroupMembership(RequestingAgentID, AgentID, principal.ActiveGroupID);
576 }
577  
578 public ExtendedGroupMembershipData GetAgentGroupMembership(string RequestingAgentID, string AgentID, UUID GroupID)
579 {
580 return GetAgentGroupMembership(RequestingAgentID, AgentID, GroupID, null);
581 }
582  
583 private ExtendedGroupMembershipData GetAgentGroupMembership(string RequestingAgentID, string AgentID, UUID GroupID, MembershipData membership)
584 {
585 // 2. get the active group
586 GroupData group = m_Database.RetrieveGroup(GroupID);
587 if (group == null)
588 return null;
589  
590 // 3. get the membership info if we don't have it already
591 if (membership == null)
592 {
593 membership = m_Database.RetrieveMember(group.GroupID, AgentID);
594 if (membership == null)
595 return null;
596 }
597  
598 // 4. get the active role
599 UUID activeRoleID = new UUID(membership.Data["SelectedRoleID"]);
600 RoleData role = m_Database.RetrieveRole(group.GroupID, activeRoleID);
601  
602 ExtendedGroupMembershipData data = new ExtendedGroupMembershipData();
603 data.AcceptNotices = membership.Data["AcceptNotices"] == "1" ? true : false;
604 data.AccessToken = membership.Data["AccessToken"];
605 data.Active = true;
606 data.ActiveRole = activeRoleID;
607 data.AllowPublish = group.Data["AllowPublish"] == "1" ? true : false;
608 data.Charter = group.Data["Charter"];
609 data.Contribution = Int32.Parse(membership.Data["Contribution"]);
610 data.FounderID = new UUID(group.Data["FounderID"]);
611 data.GroupID = new UUID(group.GroupID);
612 data.GroupName = group.Data["Name"];
613 data.GroupPicture = new UUID(group.Data["InsigniaID"]);
614 if (role != null)
615 {
616 data.GroupPowers = UInt64.Parse(role.Data["Powers"]);
617 data.GroupTitle = role.Data["Title"];
618 }
619 data.ListInProfile = membership.Data["ListInProfile"] == "1" ? true : false;
620 data.MaturePublish = group.Data["MaturePublish"] == "1" ? true : false;
621 data.MembershipFee = Int32.Parse(group.Data["MembershipFee"]);
622 data.OpenEnrollment = group.Data["OpenEnrollment"] == "1" ? true : false;
623 data.ShowInList = group.Data["ShowInList"] == "1" ? true : false;
624  
625 return data;
626 }
627  
628 public List<GroupMembershipData> GetAgentGroupMemberships(string RequestingAgentID, string AgentID)
629 {
630 List<GroupMembershipData> memberships = new List<GroupMembershipData>();
631  
632 // 1. Get all the groups that this person is a member of
633 MembershipData[] mdata = m_Database.RetrieveMemberships(AgentID);
634  
635 if (mdata == null || (mdata != null && mdata.Length == 0))
636 return memberships;
637  
638 foreach (MembershipData d in mdata)
639 {
640 GroupMembershipData gmember = GetAgentGroupMembership(RequestingAgentID, AgentID, d.GroupID, d);
641 if (gmember != null)
642 {
643 memberships.Add(gmember);
644 //m_log.DebugFormat("[XXX]: Member of {0} as {1}", gmember.GroupName, gmember.GroupTitle);
645 //Util.PrintCallStack();
646 }
647 }
648  
649 return memberships;
650 }
651  
652 public void SetAgentActiveGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
653 {
654 MembershipData data = m_Database.RetrieveMember(GroupID, AgentID);
655 if (data == null)
656 return;
657  
658 data.Data["SelectedRoleID"] = RoleID.ToString();
659 m_Database.StoreMember(data);
660 }
661  
662 public void UpdateMembership(string RequestingAgentID, string AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile)
663 {
664 // TODO: check perms
665  
666 MembershipData membership = m_Database.RetrieveMember(GroupID, AgentID);
667 if (membership == null)
668 return;
669  
670 membership.Data["AcceptNotices"] = AcceptNotices ? "1" : "0";
671 membership.Data["ListInProfile"] = ListInProfile ? "1" : "0";
672  
673 m_Database.StoreMember(membership);
674 }
675  
676 public bool AddGroupNotice(string RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message,
677 bool hasAttachment, byte attType, string attName, UUID attItemID, string attOwnerID)
678 {
679 // Check perms
680 if (!HasPower(RequestingAgentID, groupID, GroupPowers.SendNotices))
681 {
682 m_log.DebugFormat("[Groups]: ({0}) Attempt at sending notice to group {1} denied because of lack of permission", RequestingAgentID, groupID);
683 return false;
684 }
685  
686 return _AddNotice(groupID, noticeID, fromName, subject, message, hasAttachment, attType, attName, attItemID, attOwnerID);
687 }
688  
689 public GroupNoticeInfo GetGroupNotice(string RequestingAgentID, UUID noticeID)
690 {
691 NoticeData data = m_Database.RetrieveNotice(noticeID);
692  
693 if (data == null)
694 return null;
695  
696 return _NoticeDataToInfo(data);
697 }
698  
699 public List<ExtendedGroupNoticeData> GetGroupNotices(string RequestingAgentID, UUID groupID)
700 {
701 NoticeData[] data = m_Database.RetrieveNotices(groupID);
702 List<ExtendedGroupNoticeData> infos = new List<ExtendedGroupNoticeData>();
703  
704 if (data == null || (data != null && data.Length == 0))
705 return infos;
706  
707 foreach (NoticeData d in data)
708 {
709 ExtendedGroupNoticeData info = _NoticeDataToData(d);
710 infos.Add(info);
711 }
712  
713 return infos;
714 }
715  
716 public void ResetAgentGroupChatSessions(string agentID)
717 {
718 }
719  
720 public bool hasAgentBeenInvitedToGroupChatSession(string agentID, UUID groupID)
721 {
722 return false;
723 }
724  
725 public bool hasAgentDroppedGroupChatSession(string agentID, UUID groupID)
726 {
727 return false;
728 }
729  
730 public void AgentDroppedFromGroupChatSession(string agentID, UUID groupID)
731 {
732 }
733  
734 public void AgentInvitedToGroupChatSession(string agentID, UUID groupID)
735 {
736 }
737  
738 #region Actions without permission checks
739  
740 protected void _AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
741 {
742 _AddAgentToGroup(RequestingAgentID, AgentID, GroupID, RoleID, string.Empty);
743 }
744  
745 protected void _RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID)
746 {
747 // 1. Delete membership
748 m_Database.DeleteMember(GroupID, AgentID);
749  
750 // 2. Remove from rolememberships
751 m_Database.DeleteMemberAllRoles(GroupID, AgentID);
752  
753 // 3. if it was active group, inactivate it
754 PrincipalData principal = m_Database.RetrievePrincipal(AgentID);
755 if (principal != null && principal.ActiveGroupID == GroupID)
756 {
757 principal.ActiveGroupID = UUID.Zero;
758 m_Database.StorePrincipal(principal);
759 }
760 }
761  
762 protected void _AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, string accessToken)
763 {
764 // Check if it's already there
765 MembershipData data = m_Database.RetrieveMember(GroupID, AgentID);
766 if (data != null)
767 return;
768  
769 // Add the membership
770 data = new MembershipData();
771 data.PrincipalID = AgentID;
772 data.GroupID = GroupID;
773 data.Data = new Dictionary<string, string>();
774 data.Data["SelectedRoleID"] = RoleID.ToString();
775 data.Data["Contribution"] = "0";
776 data.Data["ListInProfile"] = "1";
777 data.Data["AcceptNotices"] = "1";
778 data.Data["AccessToken"] = accessToken;
779  
780 m_Database.StoreMember(data);
781  
782 // Add principal to everyone role
783 _AddAgentToGroupRole(RequestingAgentID, AgentID, GroupID, UUID.Zero);
784  
785 // Add principal to role, if different from everyone role
786 if (RoleID != UUID.Zero)
787 _AddAgentToGroupRole(RequestingAgentID, AgentID, GroupID, RoleID);
788  
789 // Make thit this active group
790 PrincipalData pdata = new PrincipalData();
791 pdata.PrincipalID = AgentID;
792 pdata.ActiveGroupID = GroupID;
793 m_Database.StorePrincipal(pdata);
794  
795 }
796  
797 protected bool _AddOrUpdateGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers, bool add)
798 {
799 RoleData data = m_Database.RetrieveRole(groupID, roleID);
800  
801 if (add && data != null) // it already exists, can't create
802 {
803 m_log.DebugFormat("[Groups]: Group {0} already exists. Can't create it again", groupID);
804 return false;
805 }
806  
807 if (!add && data == null) // it deosn't exist, can't update
808 {
809 m_log.DebugFormat("[Groups]: Group {0} doesn't exist. Can't update it", groupID);
810 return false;
811 }
812  
813 if (add)
814 data = new RoleData();
815  
816 data.GroupID = groupID;
817 data.RoleID = roleID;
818 data.Data = new Dictionary<string, string>();
819 data.Data["Name"] = name;
820 data.Data["Description"] = description;
821 data.Data["Title"] = title;
822 data.Data["Powers"] = powers.ToString();
823  
824 return m_Database.StoreRole(data);
825 }
826  
827 protected void _RemoveGroupRole(UUID groupID, UUID roleID)
828 {
829 m_Database.DeleteRole(groupID, roleID);
830 }
831  
832 protected void _AddAgentToGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
833 {
834 RoleMembershipData data = m_Database.RetrieveRoleMember(GroupID, RoleID, AgentID);
835 if (data != null)
836 return;
837  
838 data = new RoleMembershipData();
839 data.GroupID = GroupID;
840 data.PrincipalID = AgentID;
841 data.RoleID = RoleID;
842 m_Database.StoreRoleMember(data);
843  
844 // Make it the SelectedRoleID
845 MembershipData membership = m_Database.RetrieveMember(GroupID, AgentID);
846 if (membership == null)
847 {
848 m_log.DebugFormat("[Groups]: ({0}) No such member {0} in group {1}", AgentID, GroupID);
849 return;
850 }
851  
852 membership.Data["SelectedRoleID"] = RoleID.ToString();
853 m_Database.StoreMember(membership);
854  
855 }
856  
857 protected List<GroupRolesData> _GetGroupRoles(UUID groupID)
858 {
859 List<GroupRolesData> roles = new List<GroupRolesData>();
860  
861 RoleData[] data = m_Database.RetrieveRoles(groupID);
862  
863 if (data == null || (data != null && data.Length == 0))
864 return roles;
865  
866 foreach (RoleData d in data)
867 {
868 GroupRolesData r = new GroupRolesData();
869 r.Description = d.Data["Description"];
870 r.Members = m_Database.RoleMemberCount(groupID, d.RoleID);
871 r.Name = d.Data["Name"];
872 r.Powers = UInt64.Parse(d.Data["Powers"]);
873 r.RoleID = d.RoleID;
874 r.Title = d.Data["Title"];
875  
876 roles.Add(r);
877 }
878  
879 return roles;
880 }
881  
882 protected List<ExtendedGroupRoleMembersData> _GetGroupRoleMembers(UUID GroupID, bool isInGroup)
883 {
884 List<ExtendedGroupRoleMembersData> rmembers = new List<ExtendedGroupRoleMembersData>();
885  
886 RoleData[] rdata = new RoleData[0];
887 if (!isInGroup)
888 {
889 rdata = m_Database.RetrieveRoles(GroupID);
890 if (rdata == null || (rdata != null && rdata.Length == 0))
891 return rmembers;
892 }
893 List<RoleData> rlist = new List<RoleData>(rdata);
894 if (!isInGroup)
895 rlist = rlist.FindAll(r => (UInt64.Parse(r.Data["Powers"]) & (ulong)GroupPowers.MemberVisible) != 0);
896  
897 RoleMembershipData[] data = m_Database.RetrieveRolesMembers(GroupID);
898  
899 if (data == null || (data != null && data.Length == 0))
900 return rmembers;
901  
902 foreach (RoleMembershipData d in data)
903 {
904 if (!isInGroup)
905 {
906 RoleData rd = rlist.Find(_r => _r.RoleID == d.RoleID); // visible role
907 if (rd == null)
908 continue;
909 }
910  
911 ExtendedGroupRoleMembersData r = new ExtendedGroupRoleMembersData();
912 r.MemberID = d.PrincipalID;
913 r.RoleID = d.RoleID;
914  
915 rmembers.Add(r);
916 }
917  
918 return rmembers;
919 }
920  
921 protected bool _AddNotice(UUID groupID, UUID noticeID, string fromName, string subject, string message,
922 bool hasAttachment, byte attType, string attName, UUID attItemID, string attOwnerID)
923 {
924 NoticeData data = new NoticeData();
925 data.GroupID = groupID;
926 data.NoticeID = noticeID;
927 data.Data = new Dictionary<string, string>();
928 data.Data["FromName"] = fromName;
929 data.Data["Subject"] = subject;
930 data.Data["Message"] = message;
931 data.Data["HasAttachment"] = hasAttachment ? "1" : "0";
932 if (hasAttachment)
933 {
934 data.Data["AttachmentType"] = attType.ToString();
935 data.Data["AttachmentName"] = attName;
936 data.Data["AttachmentItemID"] = attItemID.ToString();
937 data.Data["AttachmentOwnerID"] = attOwnerID;
938 }
939 data.Data["TMStamp"] = ((uint)Util.UnixTimeSinceEpoch()).ToString();
940  
941 return m_Database.StoreNotice(data);
942 }
943  
944 #endregion
945  
946 #region structure translations
947 ExtendedGroupRecord _GroupDataToRecord(GroupData data)
948 {
949 if (data == null)
950 return null;
951  
952 ExtendedGroupRecord rec = new ExtendedGroupRecord();
953 rec.AllowPublish = data.Data["AllowPublish"] == "1" ? true : false;
954 rec.Charter = data.Data["Charter"];
955 rec.FounderID = new UUID(data.Data["FounderID"]);
956 rec.GroupID = data.GroupID;
957 rec.GroupName = data.Data["Name"];
958 rec.GroupPicture = new UUID(data.Data["InsigniaID"]);
959 rec.MaturePublish = data.Data["MaturePublish"] == "1" ? true : false;
960 rec.MembershipFee = Int32.Parse(data.Data["MembershipFee"]);
961 rec.OpenEnrollment = data.Data["OpenEnrollment"] == "1" ? true : false;
962 rec.OwnerRoleID = new UUID(data.Data["OwnerRoleID"]);
963 rec.ShowInList = data.Data["ShowInList"] == "1" ? true : false;
964 rec.ServiceLocation = data.Data["Location"];
965 rec.MemberCount = m_Database.MemberCount(data.GroupID);
966 rec.RoleCount = m_Database.RoleCount(data.GroupID);
967  
968 return rec;
969 }
970  
971 GroupNoticeInfo _NoticeDataToInfo(NoticeData data)
972 {
973 GroupNoticeInfo notice = new GroupNoticeInfo();
974 notice.GroupID = data.GroupID;
975 notice.Message = data.Data["Message"];
976 notice.noticeData = _NoticeDataToData(data);
977  
978 return notice;
979 }
980  
981 ExtendedGroupNoticeData _NoticeDataToData(NoticeData data)
982 {
983 ExtendedGroupNoticeData notice = new ExtendedGroupNoticeData();
984 notice.FromName = data.Data["FromName"];
985 notice.NoticeID = data.NoticeID;
986 notice.Subject = data.Data["Subject"];
987 notice.Timestamp = uint.Parse((string)data.Data["TMStamp"]);
988 notice.HasAttachment = data.Data["HasAttachment"] == "1" ? true : false;
989 if (notice.HasAttachment)
990 {
991 notice.AttachmentName = data.Data["AttachmentName"];
992 notice.AttachmentItemID = new UUID(data.Data["AttachmentItemID"].ToString());
993 notice.AttachmentType = byte.Parse(data.Data["AttachmentType"].ToString());
994 notice.AttachmentOwnerID = data.Data["AttachmentOwnerID"].ToString();
995 }
996  
997  
998 return notice;
999 }
1000  
1001 #endregion
1002  
1003 #region permissions
1004 private bool HasPower(string agentID, UUID groupID, GroupPowers power)
1005 {
1006 RoleMembershipData[] rmembership = m_Database.RetrieveMemberRoles(groupID, agentID);
1007 if (rmembership == null || (rmembership != null && rmembership.Length == 0))
1008 return false;
1009  
1010 foreach (RoleMembershipData rdata in rmembership)
1011 {
1012 RoleData role = m_Database.RetrieveRole(groupID, rdata.RoleID);
1013 if ( (UInt64.Parse(role.Data["Powers"]) & (ulong)power) != 0 )
1014 return true;
1015 }
1016 return false;
1017 }
1018  
1019 private bool IsOwner(string agentID, UUID groupID)
1020 {
1021 GroupData group = m_Database.RetrieveGroup(groupID);
1022 if (group == null)
1023 return false;
1024  
1025 RoleMembershipData rmembership = m_Database.RetrieveRoleMember(groupID, new UUID(group.Data["OwnerRoleID"]), agentID);
1026 if (rmembership == null)
1027 return false;
1028  
1029 return true;
1030 }
1031 #endregion
1032  
1033 }
1034 }