aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Addons/Groups/Service/GroupsService.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Addons/Groups/Service/GroupsService.cs')
-rw-r--r--OpenSim/Addons/Groups/Service/GroupsService.cs1020
1 files changed, 1020 insertions, 0 deletions
diff --git a/OpenSim/Addons/Groups/Service/GroupsService.cs b/OpenSim/Addons/Groups/Service/GroupsService.cs
new file mode 100644
index 0000000..0668870
--- /dev/null
+++ b/OpenSim/Addons/Groups/Service/GroupsService.cs
@@ -0,0 +1,1020 @@
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
28using System;
29using System.Collections.Generic;
30using System.Reflection;
31using System.Timers;
32using log4net;
33using Nini.Config;
34
35using OpenMetaverse;
36using OpenSim.Data;
37using OpenSim.Framework;
38using OpenSim.Services.Interfaces;
39
40namespace 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 // Create the group
134 GroupData data = new GroupData();
135 data.GroupID = UUID.Random();
136 data.Data = new Dictionary<string, string>();
137 data.Data["Name"] = name;
138 data.Data["Charter"] = charter;
139 data.Data["InsigniaID"] = insigniaID.ToString();
140 data.Data["FounderID"] = founderID.ToString();
141 data.Data["MembershipFee"] = membershipFee.ToString();
142 data.Data["OpenEnrollment"] = openEnrollment ? "1" : "0";
143 data.Data["ShowInList"] = showInList ? "1" : "0";
144 data.Data["AllowPublish"] = allowPublish ? "1" : "0";
145 data.Data["MaturePublish"] = maturePublish ? "1" : "0";
146 data.Data["OwnerRoleID"] = UUID.Random().ToString();
147
148 if (!m_Database.StoreGroup(data))
149 return UUID.Zero;
150
151 // Create Everyone role
152 _AddOrUpdateGroupRole(RequestingAgentID, data.GroupID, UUID.Zero, "Everyone", "Everyone in the group", "Member of " + name, (ulong)DefaultEveryonePowers, true);
153
154 // Create Owner role
155 UUID roleID = UUID.Random();
156 _AddOrUpdateGroupRole(RequestingAgentID, data.GroupID, roleID, "Owners", "Owners of the group", "Owner of " + name, (ulong)OwnerPowers, true);
157
158 // Add founder to group
159 _AddAgentToGroup(RequestingAgentID, founderID.ToString(), data.GroupID, roleID);
160
161 return data.GroupID;
162 }
163
164 public void UpdateGroup(string RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish)
165 {
166 GroupData data = m_Database.RetrieveGroup(groupID);
167 if (data == null)
168 return;
169
170 // Check perms
171 if (!HasPower(RequestingAgentID, groupID, GroupPowers.ChangeActions))
172 {
173 m_log.DebugFormat("[Groups]: ({0}) Attempt at updating group {1} denied because of lack of permission", RequestingAgentID, groupID);
174 return;
175 }
176
177 data.GroupID = groupID;
178 data.Data["Charter"] = charter;
179 data.Data["ShowInList"] = showInList ? "1" : "0";
180 data.Data["InsigniaID"] = insigniaID.ToString();
181 data.Data["MembershipFee"] = membershipFee.ToString();
182 data.Data["OpenEnrollment"] = openEnrollment ? "1" : "0";
183 data.Data["AllowPublish"] = allowPublish ? "1" : "0";
184 data.Data["MaturePublish"] = maturePublish ? "1" : "0";
185
186 m_Database.StoreGroup(data);
187
188 }
189
190 public ExtendedGroupRecord GetGroupRecord(string RequestingAgentID, UUID GroupID)
191 {
192 GroupData data = m_Database.RetrieveGroup(GroupID);
193
194 return _GroupDataToRecord(data);
195 }
196
197 public ExtendedGroupRecord GetGroupRecord(string RequestingAgentID, string GroupName)
198 {
199 GroupData data = m_Database.RetrieveGroup(GroupName);
200
201 return _GroupDataToRecord(data);
202 }
203
204 public List<DirGroupsReplyData> FindGroups(string RequestingAgentID, string search)
205 {
206 List<DirGroupsReplyData> groups = new List<DirGroupsReplyData>();
207
208 GroupData[] data = m_Database.RetrieveGroups(search);
209
210 if (data != null && data.Length > 0)
211 {
212 foreach (GroupData d in data)
213 {
214 // Don't list group proxies
215 if (d.Data.ContainsKey("Location") && d.Data["Location"] != string.Empty)
216 continue;
217
218 DirGroupsReplyData g = new DirGroupsReplyData();
219 g.groupID = d.GroupID;
220
221 if (d.Data.ContainsKey("Name"))
222 g.groupName = d.Data["Name"];
223 else
224 m_log.DebugFormat("[Groups]: Key Name not found");
225
226 g.members = m_Database.MemberCount(d.GroupID);
227
228 groups.Add(g);
229 }
230 }
231
232 return groups;
233 }
234
235 public List<ExtendedGroupMembersData> GetGroupMembers(string RequestingAgentID, UUID GroupID)
236 {
237 List<ExtendedGroupMembersData> members = new List<ExtendedGroupMembersData>();
238
239 GroupData group = m_Database.RetrieveGroup(GroupID);
240 if (group == null)
241 return members;
242
243 UUID ownerRoleID = new UUID(group.Data["OwnerRoleID"]);
244
245 RoleData[] roles = m_Database.RetrieveRoles(GroupID);
246 if (roles == null)
247 // something wrong with this group
248 return members;
249 List<RoleData> rolesList = new List<RoleData>(roles);
250
251 // Is the requester a member of the group?
252 bool isInGroup = false;
253 if (m_Database.RetrieveMember(GroupID, RequestingAgentID) != null)
254 isInGroup = true;
255
256 if (!isInGroup) // reduce the roles to the visible ones
257 rolesList = rolesList.FindAll(r => (UInt64.Parse(r.Data["Powers"]) & (ulong)GroupPowers.MemberVisible) != 0);
258
259 MembershipData[] datas = m_Database.RetrieveMembers(GroupID);
260 if (datas == null || (datas != null && datas.Length == 0))
261 return members;
262
263 // OK, we have everything we need
264
265 foreach (MembershipData d in datas)
266 {
267 RoleMembershipData[] rolememberships = m_Database.RetrieveMemberRoles(GroupID, d.PrincipalID);
268 List<RoleMembershipData> rolemembershipsList = new List<RoleMembershipData>(rolememberships);
269
270 ExtendedGroupMembersData m = new ExtendedGroupMembersData();
271
272 // What's this person's current role in the group?
273 UUID selectedRole = new UUID(d.Data["SelectedRoleID"]);
274 RoleData selected = rolesList.Find(r => r.RoleID == selectedRole);
275
276 if (selected != null)
277 {
278 m.Title = selected.Data["Title"];
279 m.AgentPowers = UInt64.Parse(selected.Data["Powers"]);
280
281 m.AgentID = d.PrincipalID;
282 m.AcceptNotices = d.Data["AcceptNotices"] == "1" ? true : false;
283 m.Contribution = Int32.Parse(d.Data["Contribution"]);
284 m.ListInProfile = d.Data["ListInProfile"] == "1" ? true : false;
285
286 // Is this person an owner of the group?
287 m.IsOwner = (rolemembershipsList.Find(r => r.RoleID == ownerRoleID) != null) ? true : false;
288
289 members.Add(m);
290 }
291 }
292
293 return members;
294 }
295
296 public bool AddGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers, out string reason)
297 {
298 reason = string.Empty;
299 // check that the requesting agent has permissions to add role
300 if (!HasPower(RequestingAgentID, groupID, GroupPowers.CreateRole))
301 {
302 m_log.DebugFormat("[Groups]: ({0}) Attempt at creating role in group {1} denied because of lack of permission", RequestingAgentID, groupID);
303 reason = "Insufficient permission to create role";
304 return false;
305 }
306
307 return _AddOrUpdateGroupRole(RequestingAgentID, groupID, roleID, name, description, title, powers, true);
308
309 }
310
311 public bool UpdateGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers)
312 {
313 // check perms
314 if (!HasPower(RequestingAgentID, groupID, GroupPowers.ChangeActions))
315 {
316 m_log.DebugFormat("[Groups]: ({0}) Attempt at changing role in group {1} denied because of lack of permission", RequestingAgentID, groupID);
317 return false;
318 }
319
320 return _AddOrUpdateGroupRole(RequestingAgentID, groupID, roleID, name, description, title, powers, false);
321 }
322
323 public void RemoveGroupRole(string RequestingAgentID, UUID groupID, UUID roleID)
324 {
325 // check perms
326 if (!HasPower(RequestingAgentID, groupID, GroupPowers.DeleteRole))
327 {
328 m_log.DebugFormat("[Groups]: ({0}) Attempt at deleting role from group {1} denied because of lack of permission", RequestingAgentID, groupID);
329 return;
330 }
331
332 // Can't delete Everyone and Owners roles
333 if (roleID == UUID.Zero)
334 {
335 m_log.DebugFormat("[Groups]: Attempt at deleting Everyone role from group {0} denied", groupID);
336 return;
337 }
338
339 GroupData group = m_Database.RetrieveGroup(groupID);
340 if (group == null)
341 {
342 m_log.DebugFormat("[Groups]: Attempt at deleting role from non-existing group {0}", groupID);
343 return;
344 }
345
346 if (roleID == new UUID(group.Data["OwnerRoleID"]))
347 {
348 m_log.DebugFormat("[Groups]: Attempt at deleting Owners role from group {0} denied", groupID);
349 return;
350 }
351
352 _RemoveGroupRole(groupID, roleID);
353 }
354
355 public List<GroupRolesData> GetGroupRoles(string RequestingAgentID, UUID GroupID)
356 {
357 // TODO: check perms
358 return _GetGroupRoles(GroupID);
359 }
360
361 public List<ExtendedGroupRoleMembersData> GetGroupRoleMembers(string RequestingAgentID, UUID GroupID)
362 {
363 // TODO: check perms
364
365 // Is the requester a member of the group?
366 bool isInGroup = false;
367 if (m_Database.RetrieveMember(GroupID, RequestingAgentID) != null)
368 isInGroup = true;
369
370 return _GetGroupRoleMembers(GroupID, isInGroup);
371 }
372
373 public bool AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, string token, out string reason)
374 {
375 reason = string.Empty;
376
377 _AddAgentToGroup(RequestingAgentID, AgentID, GroupID, RoleID, token);
378
379 return true;
380 }
381
382 public void RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID)
383 {
384 // check perms
385 if (RequestingAgentID != AgentID && !HasPower(RequestingAgentID, GroupID, GroupPowers.Eject))
386 return;
387
388 _RemoveAgentFromGroup(RequestingAgentID, AgentID, GroupID);
389 }
390
391 public bool AddAgentToGroupInvite(string RequestingAgentID, UUID inviteID, UUID groupID, UUID roleID, string agentID)
392 {
393 // Check whether the invitee is already a member of the group
394 MembershipData m = m_Database.RetrieveMember(groupID, agentID);
395 if (m != null)
396 return false;
397
398 // Check permission to invite
399 if (!HasPower(RequestingAgentID, groupID, GroupPowers.Invite))
400 {
401 m_log.DebugFormat("[Groups]: ({0}) Attempt at inviting to group {1} denied because of lack of permission", RequestingAgentID, groupID);
402 return false;
403 }
404
405 // Check whether there are pending invitations and delete them
406 InvitationData invite = m_Database.RetrieveInvitation(groupID, agentID);
407 if (invite != null)
408 m_Database.DeleteInvite(invite.InviteID);
409
410 invite = new InvitationData();
411 invite.InviteID = inviteID;
412 invite.PrincipalID = agentID;
413 invite.GroupID = groupID;
414 invite.RoleID = roleID;
415 invite.Data = new Dictionary<string, string>();
416
417 return m_Database.StoreInvitation(invite);
418 }
419
420 public GroupInviteInfo GetAgentToGroupInvite(string RequestingAgentID, UUID inviteID)
421 {
422 InvitationData data = m_Database.RetrieveInvitation(inviteID);
423
424 if (data == null)
425 return null;
426
427 GroupInviteInfo inviteInfo = new GroupInviteInfo();
428 inviteInfo.AgentID = data.PrincipalID;
429 inviteInfo.GroupID = data.GroupID;
430 inviteInfo.InviteID = data.InviteID;
431 inviteInfo.RoleID = data.RoleID;
432
433 return inviteInfo;
434 }
435
436 public void RemoveAgentToGroupInvite(string RequestingAgentID, UUID inviteID)
437 {
438 m_Database.DeleteInvite(inviteID);
439 }
440
441 public bool AddAgentToGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
442 {
443 //if (!m_Database.CheckOwnerRole(RequestingAgentID, GroupID, RoleID))
444 // return;
445
446 // check permissions
447 bool limited = HasPower(RequestingAgentID, GroupID, GroupPowers.AssignMemberLimited);
448 bool unlimited = HasPower(RequestingAgentID, GroupID, GroupPowers.AssignMember) | IsOwner(RequestingAgentID, GroupID);
449 if (!limited || !unlimited)
450 {
451 m_log.DebugFormat("[Groups]: ({0}) Attempt at assigning {1} to role {2} denied because of lack of permission", RequestingAgentID, AgentID, RoleID);
452 return false;
453 }
454
455 // AssignMemberLimited means that the person can assign another person to the same roles that she has in the group
456 if (!unlimited && limited)
457 {
458 // check whether person's has this role
459 RoleMembershipData rolemembership = m_Database.RetrieveRoleMember(GroupID, RoleID, AgentID);
460 if (rolemembership == null)
461 {
462 m_log.DebugFormat("[Groups]: ({0}) Attempt at assigning {1} to role {2} denied because of limited permission", RequestingAgentID, AgentID, RoleID);
463 return false;
464 }
465 }
466
467 _AddAgentToGroupRole(RequestingAgentID, AgentID, GroupID, RoleID);
468
469 return true;
470 }
471
472 public bool RemoveAgentFromGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
473 {
474 // Don't remove from Everyone role!
475 if (RoleID == UUID.Zero)
476 return false;
477
478 // check permissions
479 bool unlimited = HasPower(RequestingAgentID, GroupID, GroupPowers.AssignMember) || IsOwner(RequestingAgentID, GroupID);
480 if (!unlimited)
481 {
482 m_log.DebugFormat("[Groups]: ({0}) Attempt at removing {1} from role {2} denied because of lack of permission", RequestingAgentID, AgentID, RoleID);
483 return false;
484 }
485
486 RoleMembershipData rolemember = m_Database.RetrieveRoleMember(GroupID, RoleID, AgentID);
487
488 if (rolemember == null)
489 return false;
490
491 m_Database.DeleteRoleMember(rolemember);
492
493 // Find another role for this person
494 UUID newRoleID = UUID.Zero; // Everyone
495 RoleMembershipData[] rdata = m_Database.RetrieveMemberRoles(GroupID, AgentID);
496 if (rdata != null)
497 foreach (RoleMembershipData r in rdata)
498 {
499 if (r.RoleID != UUID.Zero)
500 {
501 newRoleID = r.RoleID;
502 break;
503 }
504 }
505
506 MembershipData member = m_Database.RetrieveMember(GroupID, AgentID);
507 if (member != null)
508 {
509 member.Data["SelectedRoleID"] = newRoleID.ToString();
510 m_Database.StoreMember(member);
511 }
512
513 return true;
514 }
515
516 public List<GroupRolesData> GetAgentGroupRoles(string RequestingAgentID, string AgentID, UUID GroupID)
517 {
518 List<GroupRolesData> roles = new List<GroupRolesData>();
519 // TODO: check permissions
520
521 RoleMembershipData[] data = m_Database.RetrieveMemberRoles(GroupID, AgentID);
522 if (data == null || (data != null && data.Length ==0))
523 return roles;
524
525 foreach (RoleMembershipData d in data)
526 {
527 RoleData rdata = m_Database.RetrieveRole(GroupID, d.RoleID);
528 if (rdata == null) // hippos
529 continue;
530
531 GroupRolesData r = new GroupRolesData();
532 r.Name = rdata.Data["Name"];
533 r.Powers = UInt64.Parse(rdata.Data["Powers"]);
534 r.RoleID = rdata.RoleID;
535 r.Title = rdata.Data["Title"];
536
537 roles.Add(r);
538 }
539
540 return roles;
541 }
542
543 public ExtendedGroupMembershipData SetAgentActiveGroup(string RequestingAgentID, string AgentID, UUID GroupID)
544 {
545 // TODO: check perms
546 PrincipalData principal = new PrincipalData();
547 principal.PrincipalID = AgentID;
548 principal.ActiveGroupID = GroupID;
549 m_Database.StorePrincipal(principal);
550
551 return GetAgentGroupMembership(RequestingAgentID, AgentID, GroupID);
552 }
553
554 public ExtendedGroupMembershipData GetAgentActiveMembership(string RequestingAgentID, string AgentID)
555 {
556 // 1. get the principal data for the active group
557 PrincipalData principal = m_Database.RetrievePrincipal(AgentID);
558 if (principal == null)
559 return null;
560
561 return GetAgentGroupMembership(RequestingAgentID, AgentID, principal.ActiveGroupID);
562 }
563
564 public ExtendedGroupMembershipData GetAgentGroupMembership(string RequestingAgentID, string AgentID, UUID GroupID)
565 {
566 return GetAgentGroupMembership(RequestingAgentID, AgentID, GroupID, null);
567 }
568
569 private ExtendedGroupMembershipData GetAgentGroupMembership(string RequestingAgentID, string AgentID, UUID GroupID, MembershipData membership)
570 {
571 // 2. get the active group
572 GroupData group = m_Database.RetrieveGroup(GroupID);
573 if (group == null)
574 return null;
575
576 // 3. get the membership info if we don't have it already
577 if (membership == null)
578 {
579 membership = m_Database.RetrieveMember(group.GroupID, AgentID);
580 if (membership == null)
581 return null;
582 }
583
584 // 4. get the active role
585 UUID activeRoleID = new UUID(membership.Data["SelectedRoleID"]);
586 RoleData role = m_Database.RetrieveRole(group.GroupID, activeRoleID);
587
588 ExtendedGroupMembershipData data = new ExtendedGroupMembershipData();
589 data.AcceptNotices = membership.Data["AcceptNotices"] == "1" ? true : false;
590 data.AccessToken = membership.Data["AccessToken"];
591 data.Active = true;
592 data.ActiveRole = activeRoleID;
593 data.AllowPublish = group.Data["AllowPublish"] == "1" ? true : false;
594 data.Charter = group.Data["Charter"];
595 data.Contribution = Int32.Parse(membership.Data["Contribution"]);
596 data.FounderID = new UUID(group.Data["FounderID"]);
597 data.GroupID = new UUID(group.GroupID);
598 data.GroupName = group.Data["Name"];
599 data.GroupPicture = new UUID(group.Data["InsigniaID"]);
600 if (role != null)
601 {
602 data.GroupPowers = UInt64.Parse(role.Data["Powers"]);
603 data.GroupTitle = role.Data["Title"];
604 }
605 data.ListInProfile = membership.Data["ListInProfile"] == "1" ? true : false;
606 data.MaturePublish = group.Data["MaturePublish"] == "1" ? true : false;
607 data.MembershipFee = Int32.Parse(group.Data["MembershipFee"]);
608 data.OpenEnrollment = group.Data["OpenEnrollment"] == "1" ? true : false;
609 data.ShowInList = group.Data["ShowInList"] == "1" ? true : false;
610
611 return data;
612 }
613
614 public List<GroupMembershipData> GetAgentGroupMemberships(string RequestingAgentID, string AgentID)
615 {
616 List<GroupMembershipData> memberships = new List<GroupMembershipData>();
617
618 // 1. Get all the groups that this person is a member of
619 MembershipData[] mdata = m_Database.RetrieveMemberships(AgentID);
620
621 if (mdata == null || (mdata != null && mdata.Length == 0))
622 return memberships;
623
624 foreach (MembershipData d in mdata)
625 {
626 GroupMembershipData gmember = GetAgentGroupMembership(RequestingAgentID, AgentID, d.GroupID, d);
627 if (gmember != null)
628 {
629 memberships.Add(gmember);
630 //m_log.DebugFormat("[XXX]: Member of {0} as {1}", gmember.GroupName, gmember.GroupTitle);
631 //Util.PrintCallStack();
632 }
633 }
634
635 return memberships;
636 }
637
638 public void SetAgentActiveGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
639 {
640 MembershipData data = m_Database.RetrieveMember(GroupID, AgentID);
641 if (data == null)
642 return;
643
644 data.Data["SelectedRoleID"] = RoleID.ToString();
645 m_Database.StoreMember(data);
646 }
647
648 public void UpdateMembership(string RequestingAgentID, string AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile)
649 {
650 // TODO: check perms
651
652 MembershipData membership = m_Database.RetrieveMember(GroupID, AgentID);
653 if (membership == null)
654 return;
655
656 membership.Data["AcceptNotices"] = AcceptNotices ? "1" : "0";
657 membership.Data["ListInProfile"] = ListInProfile ? "1" : "0";
658
659 m_Database.StoreMember(membership);
660 }
661
662 public bool AddGroupNotice(string RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message,
663 bool hasAttachment, byte attType, string attName, UUID attItemID, string attOwnerID)
664 {
665 // Check perms
666 if (!HasPower(RequestingAgentID, groupID, GroupPowers.SendNotices))
667 {
668 m_log.DebugFormat("[Groups]: ({0}) Attempt at sending notice to group {1} denied because of lack of permission", RequestingAgentID, groupID);
669 return false;
670 }
671
672 return _AddNotice(groupID, noticeID, fromName, subject, message, hasAttachment, attType, attName, attItemID, attOwnerID);
673 }
674
675 public GroupNoticeInfo GetGroupNotice(string RequestingAgentID, UUID noticeID)
676 {
677 NoticeData data = m_Database.RetrieveNotice(noticeID);
678
679 if (data == null)
680 return null;
681
682 return _NoticeDataToInfo(data);
683 }
684
685 public List<ExtendedGroupNoticeData> GetGroupNotices(string RequestingAgentID, UUID groupID)
686 {
687 NoticeData[] data = m_Database.RetrieveNotices(groupID);
688 List<ExtendedGroupNoticeData> infos = new List<ExtendedGroupNoticeData>();
689
690 if (data == null || (data != null && data.Length == 0))
691 return infos;
692
693 foreach (NoticeData d in data)
694 {
695 ExtendedGroupNoticeData info = _NoticeDataToData(d);
696 infos.Add(info);
697 }
698
699 return infos;
700 }
701
702 public void ResetAgentGroupChatSessions(string agentID)
703 {
704 }
705
706 public bool hasAgentBeenInvitedToGroupChatSession(string agentID, UUID groupID)
707 {
708 return false;
709 }
710
711 public bool hasAgentDroppedGroupChatSession(string agentID, UUID groupID)
712 {
713 return false;
714 }
715
716 public void AgentDroppedFromGroupChatSession(string agentID, UUID groupID)
717 {
718 }
719
720 public void AgentInvitedToGroupChatSession(string agentID, UUID groupID)
721 {
722 }
723
724 #region Actions without permission checks
725
726 private void _AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
727 {
728 _AddAgentToGroup(RequestingAgentID, AgentID, GroupID, RoleID, string.Empty);
729 }
730
731 public void _RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID)
732 {
733 // 1. Delete membership
734 m_Database.DeleteMember(GroupID, AgentID);
735
736 // 2. Remove from rolememberships
737 m_Database.DeleteMemberAllRoles(GroupID, AgentID);
738
739 // 3. if it was active group, inactivate it
740 PrincipalData principal = m_Database.RetrievePrincipal(AgentID);
741 if (principal != null && principal.ActiveGroupID == GroupID)
742 {
743 principal.ActiveGroupID = UUID.Zero;
744 m_Database.StorePrincipal(principal);
745 }
746 }
747
748 protected void _AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, string accessToken)
749 {
750 // Check if it's already there
751 MembershipData data = m_Database.RetrieveMember(GroupID, AgentID);
752 if (data != null)
753 return;
754
755 // Add the membership
756 data = new MembershipData();
757 data.PrincipalID = AgentID;
758 data.GroupID = GroupID;
759 data.Data = new Dictionary<string, string>();
760 data.Data["SelectedRoleID"] = RoleID.ToString();
761 data.Data["Contribution"] = "0";
762 data.Data["ListInProfile"] = "1";
763 data.Data["AcceptNotices"] = "1";
764 data.Data["AccessToken"] = accessToken;
765
766 m_Database.StoreMember(data);
767
768 // Add principal to everyone role
769 _AddAgentToGroupRole(RequestingAgentID, AgentID, GroupID, UUID.Zero);
770
771 // Add principal to role, if different from everyone role
772 if (RoleID != UUID.Zero)
773 _AddAgentToGroupRole(RequestingAgentID, AgentID, GroupID, RoleID);
774
775 // Make thit this active group
776 PrincipalData pdata = new PrincipalData();
777 pdata.PrincipalID = AgentID;
778 pdata.ActiveGroupID = GroupID;
779 m_Database.StorePrincipal(pdata);
780
781 }
782
783 private bool _AddOrUpdateGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers, bool add)
784 {
785 RoleData data = m_Database.RetrieveRole(groupID, roleID);
786
787 if (add && data != null) // it already exists, can't create
788 {
789 m_log.DebugFormat("[Groups]: Group {0} already exists. Can't create it again", groupID);
790 return false;
791 }
792
793 if (!add && data == null) // it deosn't exist, can't update
794 {
795 m_log.DebugFormat("[Groups]: Group {0} doesn't exist. Can't update it", groupID);
796 return false;
797 }
798
799 if (add)
800 data = new RoleData();
801
802 data.GroupID = groupID;
803 data.RoleID = roleID;
804 data.Data = new Dictionary<string, string>();
805 data.Data["Name"] = name;
806 data.Data["Description"] = description;
807 data.Data["Title"] = title;
808 data.Data["Powers"] = powers.ToString();
809
810 return m_Database.StoreRole(data);
811 }
812
813 private void _RemoveGroupRole(UUID groupID, UUID roleID)
814 {
815 m_Database.DeleteRole(groupID, roleID);
816 }
817
818 private void _AddAgentToGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
819 {
820 RoleMembershipData data = m_Database.RetrieveRoleMember(GroupID, RoleID, AgentID);
821 if (data != null)
822 return;
823
824 data = new RoleMembershipData();
825 data.GroupID = GroupID;
826 data.PrincipalID = AgentID;
827 data.RoleID = RoleID;
828 m_Database.StoreRoleMember(data);
829
830 // Make it the SelectedRoleID
831 MembershipData membership = m_Database.RetrieveMember(GroupID, AgentID);
832 if (membership == null)
833 {
834 m_log.DebugFormat("[Groups]: ({0}) No such member {0} in group {1}", AgentID, GroupID);
835 return;
836 }
837
838 membership.Data["SelectedRoleID"] = RoleID.ToString();
839 m_Database.StoreMember(membership);
840
841 }
842
843 private List<GroupRolesData> _GetGroupRoles(UUID groupID)
844 {
845 List<GroupRolesData> roles = new List<GroupRolesData>();
846
847 RoleData[] data = m_Database.RetrieveRoles(groupID);
848
849 if (data == null || (data != null && data.Length == 0))
850 return roles;
851
852 foreach (RoleData d in data)
853 {
854 GroupRolesData r = new GroupRolesData();
855 r.Description = d.Data["Description"];
856 r.Members = m_Database.RoleMemberCount(groupID, d.RoleID);
857 r.Name = d.Data["Name"];
858 r.Powers = UInt64.Parse(d.Data["Powers"]);
859 r.RoleID = d.RoleID;
860 r.Title = d.Data["Title"];
861
862 roles.Add(r);
863 }
864
865 return roles;
866 }
867
868 private List<ExtendedGroupRoleMembersData> _GetGroupRoleMembers(UUID GroupID, bool isInGroup)
869 {
870 List<ExtendedGroupRoleMembersData> rmembers = new List<ExtendedGroupRoleMembersData>();
871
872 RoleData[] rdata = new RoleData[0];
873 if (!isInGroup)
874 {
875 rdata = m_Database.RetrieveRoles(GroupID);
876 if (rdata == null || (rdata != null && rdata.Length == 0))
877 return rmembers;
878 }
879 List<RoleData> rlist = new List<RoleData>(rdata);
880 if (!isInGroup)
881 rlist = rlist.FindAll(r => (UInt64.Parse(r.Data["Powers"]) & (ulong)GroupPowers.MemberVisible) != 0);
882
883 RoleMembershipData[] data = m_Database.RetrieveRolesMembers(GroupID);
884
885 if (data == null || (data != null && data.Length == 0))
886 return rmembers;
887
888 foreach (RoleMembershipData d in data)
889 {
890 if (!isInGroup)
891 {
892 RoleData rd = rlist.Find(_r => _r.RoleID == d.RoleID); // visible role
893 if (rd == null)
894 continue;
895 }
896
897 ExtendedGroupRoleMembersData r = new ExtendedGroupRoleMembersData();
898 r.MemberID = d.PrincipalID;
899 r.RoleID = d.RoleID;
900
901 rmembers.Add(r);
902 }
903
904 return rmembers;
905 }
906
907 protected bool _AddNotice(UUID groupID, UUID noticeID, string fromName, string subject, string message,
908 bool hasAttachment, byte attType, string attName, UUID attItemID, string attOwnerID)
909 {
910 NoticeData data = new NoticeData();
911 data.GroupID = groupID;
912 data.NoticeID = noticeID;
913 data.Data = new Dictionary<string, string>();
914 data.Data["FromName"] = fromName;
915 data.Data["Subject"] = subject;
916 data.Data["Message"] = message;
917 data.Data["HasAttachment"] = hasAttachment ? "1" : "0";
918 if (hasAttachment)
919 {
920 data.Data["AttachmentType"] = attType.ToString();
921 data.Data["AttachmentName"] = attName;
922 data.Data["AttachmentItemID"] = attItemID.ToString();
923 data.Data["AttachmentOwnerID"] = attOwnerID;
924 }
925 data.Data["TMStamp"] = ((uint)Util.UnixTimeSinceEpoch()).ToString();
926
927 return m_Database.StoreNotice(data);
928 }
929
930 #endregion
931
932 #region structure translations
933 ExtendedGroupRecord _GroupDataToRecord(GroupData data)
934 {
935 if (data == null)
936 return null;
937
938 ExtendedGroupRecord rec = new ExtendedGroupRecord();
939 rec.AllowPublish = data.Data["AllowPublish"] == "1" ? true : false;
940 rec.Charter = data.Data["Charter"];
941 rec.FounderID = new UUID(data.Data["FounderID"]);
942 rec.GroupID = data.GroupID;
943 rec.GroupName = data.Data["Name"];
944 rec.GroupPicture = new UUID(data.Data["InsigniaID"]);
945 rec.MaturePublish = data.Data["MaturePublish"] == "1" ? true : false;
946 rec.MembershipFee = Int32.Parse(data.Data["MembershipFee"]);
947 rec.OpenEnrollment = data.Data["OpenEnrollment"] == "1" ? true : false;
948 rec.OwnerRoleID = new UUID(data.Data["OwnerRoleID"]);
949 rec.ShowInList = data.Data["ShowInList"] == "1" ? true : false;
950 rec.ServiceLocation = data.Data["Location"];
951 rec.MemberCount = m_Database.MemberCount(data.GroupID);
952 rec.RoleCount = m_Database.RoleCount(data.GroupID);
953
954 return rec;
955 }
956
957 GroupNoticeInfo _NoticeDataToInfo(NoticeData data)
958 {
959 GroupNoticeInfo notice = new GroupNoticeInfo();
960 notice.GroupID = data.GroupID;
961 notice.Message = data.Data["Message"];
962 notice.noticeData = _NoticeDataToData(data);
963
964 return notice;
965 }
966
967 ExtendedGroupNoticeData _NoticeDataToData(NoticeData data)
968 {
969 ExtendedGroupNoticeData notice = new ExtendedGroupNoticeData();
970 notice.FromName = data.Data["FromName"];
971 notice.NoticeID = data.NoticeID;
972 notice.Subject = data.Data["Subject"];
973 notice.Timestamp = uint.Parse((string)data.Data["TMStamp"]);
974 notice.HasAttachment = data.Data["HasAttachment"] == "1" ? true : false;
975 if (notice.HasAttachment)
976 {
977 notice.AttachmentName = data.Data["AttachmentName"];
978 notice.AttachmentItemID = new UUID(data.Data["AttachmentItemID"].ToString());
979 notice.AttachmentType = byte.Parse(data.Data["AttachmentType"].ToString());
980 notice.AttachmentOwnerID = data.Data["AttachmentOwnerID"].ToString();
981 }
982
983
984 return notice;
985 }
986
987 #endregion
988
989 #region permissions
990 private bool HasPower(string agentID, UUID groupID, GroupPowers power)
991 {
992 RoleMembershipData[] rmembership = m_Database.RetrieveMemberRoles(groupID, agentID);
993 if (rmembership == null || (rmembership != null && rmembership.Length == 0))
994 return false;
995
996 foreach (RoleMembershipData rdata in rmembership)
997 {
998 RoleData role = m_Database.RetrieveRole(groupID, rdata.RoleID);
999 if ( (UInt64.Parse(role.Data["Powers"]) & (ulong)power) != 0 )
1000 return true;
1001 }
1002 return false;
1003 }
1004
1005 private bool IsOwner(string agentID, UUID groupID)
1006 {
1007 GroupData group = m_Database.RetrieveGroup(groupID);
1008 if (group == null)
1009 return false;
1010
1011 RoleMembershipData rmembership = m_Database.RetrieveRoleMember(groupID, new UUID(group.Data["OwnerRoleID"]), agentID);
1012 if (rmembership == null)
1013 return false;
1014
1015 return true;
1016 }
1017 #endregion
1018
1019 }
1020}