1035 lines
42 KiB
C#
1035 lines
42 KiB
C#
/*
|
|
* Copyright (c) Contributors, http://opensimulator.org/
|
|
* See CONTRIBUTORS.TXT for a full list of copyright holders.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
* * Redistributions of source code must retain the above copyright
|
|
* notice, this list of conditions and the following disclaimer.
|
|
* * Redistributions in binary form must reproduce the above copyright
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
* documentation and/or other materials provided with the distribution.
|
|
* * Neither the name of the OpenSimulator Project nor the
|
|
* names of its contributors may be used to endorse or promote products
|
|
* derived from this software without specific prior written permission.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
|
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
|
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
*/
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Reflection;
|
|
using System.Timers;
|
|
using log4net;
|
|
using Nini.Config;
|
|
|
|
using OpenMetaverse;
|
|
using OpenSim.Data;
|
|
using OpenSim.Framework;
|
|
using OpenSim.Services.Interfaces;
|
|
|
|
namespace OpenSim.Groups
|
|
{
|
|
public class GroupsService : GroupsServiceBase
|
|
{
|
|
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
|
|
|
|
public const GroupPowers DefaultEveryonePowers = GroupPowers.AllowSetHome |
|
|
GroupPowers.Accountable |
|
|
GroupPowers.JoinChat |
|
|
GroupPowers.AllowVoiceChat |
|
|
GroupPowers.ReceiveNotices |
|
|
GroupPowers.StartProposal |
|
|
GroupPowers.VoteOnProposal;
|
|
|
|
public const GroupPowers OwnerPowers = GroupPowers.Accountable |
|
|
GroupPowers.AllowEditLand |
|
|
GroupPowers.AllowFly |
|
|
GroupPowers.AllowLandmark |
|
|
GroupPowers.AllowRez |
|
|
GroupPowers.AllowSetHome |
|
|
GroupPowers.AllowVoiceChat |
|
|
GroupPowers.AssignMember |
|
|
GroupPowers.AssignMemberLimited |
|
|
GroupPowers.ChangeActions |
|
|
GroupPowers.ChangeIdentity |
|
|
GroupPowers.ChangeMedia |
|
|
GroupPowers.ChangeOptions |
|
|
GroupPowers.CreateRole |
|
|
GroupPowers.DeedObject |
|
|
GroupPowers.DeleteRole |
|
|
GroupPowers.Eject |
|
|
GroupPowers.FindPlaces |
|
|
GroupPowers.Invite |
|
|
GroupPowers.JoinChat |
|
|
GroupPowers.LandChangeIdentity |
|
|
GroupPowers.LandDeed |
|
|
GroupPowers.LandDivideJoin |
|
|
GroupPowers.LandEdit |
|
|
GroupPowers.LandEjectAndFreeze |
|
|
GroupPowers.LandGardening |
|
|
GroupPowers.LandManageAllowed |
|
|
GroupPowers.LandManageBanned |
|
|
GroupPowers.LandManagePasses |
|
|
GroupPowers.LandOptions |
|
|
GroupPowers.LandRelease |
|
|
GroupPowers.LandSetSale |
|
|
GroupPowers.ModerateChat |
|
|
GroupPowers.ObjectManipulate |
|
|
GroupPowers.ObjectSetForSale |
|
|
GroupPowers.ReceiveNotices |
|
|
GroupPowers.RemoveMember |
|
|
GroupPowers.ReturnGroupOwned |
|
|
GroupPowers.ReturnGroupSet |
|
|
GroupPowers.ReturnNonGroup |
|
|
GroupPowers.RoleProperties |
|
|
GroupPowers.SendNotices |
|
|
GroupPowers.SetLandingPoint |
|
|
GroupPowers.StartProposal |
|
|
GroupPowers.VoteOnProposal;
|
|
|
|
#region Daily Cleanup
|
|
|
|
private Timer m_CleanupTimer;
|
|
|
|
public GroupsService(IConfigSource config, string configName)
|
|
: base(config, configName)
|
|
{
|
|
}
|
|
|
|
public GroupsService(IConfigSource config)
|
|
: this(config, string.Empty)
|
|
{
|
|
// Once a day
|
|
m_CleanupTimer = new Timer(24 * 60 * 60 * 1000);
|
|
m_CleanupTimer.AutoReset = true;
|
|
m_CleanupTimer.Elapsed += new ElapsedEventHandler(m_CleanupTimer_Elapsed);
|
|
m_CleanupTimer.Enabled = true;
|
|
m_CleanupTimer.Start();
|
|
}
|
|
|
|
private void m_CleanupTimer_Elapsed(object sender, ElapsedEventArgs e)
|
|
{
|
|
m_Database.DeleteOldNotices();
|
|
m_Database.DeleteOldInvites();
|
|
}
|
|
|
|
#endregion
|
|
|
|
public UUID CreateGroup(string RequestingAgentID, string name, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment,
|
|
bool allowPublish, bool maturePublish, UUID founderID, out string reason)
|
|
{
|
|
reason = string.Empty;
|
|
|
|
// Check if the group already exists
|
|
if (m_Database.RetrieveGroup(name) != null)
|
|
{
|
|
reason = "A group with that name already exists";
|
|
return UUID.Zero;
|
|
}
|
|
|
|
// Create the group
|
|
GroupData data = new GroupData();
|
|
data.GroupID = UUID.Random();
|
|
data.Data = new Dictionary<string, string>();
|
|
data.Data["Name"] = name;
|
|
data.Data["Charter"] = charter;
|
|
data.Data["InsigniaID"] = insigniaID.ToString();
|
|
data.Data["FounderID"] = founderID.ToString();
|
|
data.Data["MembershipFee"] = membershipFee.ToString();
|
|
data.Data["OpenEnrollment"] = openEnrollment ? "1" : "0";
|
|
data.Data["ShowInList"] = showInList ? "1" : "0";
|
|
data.Data["AllowPublish"] = allowPublish ? "1" : "0";
|
|
data.Data["MaturePublish"] = maturePublish ? "1" : "0";
|
|
data.Data["OwnerRoleID"] = UUID.Random().ToString();
|
|
|
|
if (!m_Database.StoreGroup(data))
|
|
return UUID.Zero;
|
|
|
|
// Create Everyone role
|
|
_AddOrUpdateGroupRole(RequestingAgentID, data.GroupID, UUID.Zero, "Everyone", "Everyone in the group", "Member of " + name, (ulong)DefaultEveryonePowers, true);
|
|
|
|
// Create Owner role
|
|
UUID roleID = UUID.Random();
|
|
_AddOrUpdateGroupRole(RequestingAgentID, data.GroupID, roleID, "Owners", "Owners of the group", "Owner of " + name, (ulong)OwnerPowers, true);
|
|
|
|
// Add founder to group
|
|
_AddAgentToGroup(RequestingAgentID, founderID.ToString(), data.GroupID, roleID);
|
|
|
|
return data.GroupID;
|
|
}
|
|
|
|
public void UpdateGroup(string RequestingAgentID, UUID groupID, string charter, bool showInList, UUID insigniaID, int membershipFee, bool openEnrollment, bool allowPublish, bool maturePublish)
|
|
{
|
|
GroupData data = m_Database.RetrieveGroup(groupID);
|
|
if (data == null)
|
|
return;
|
|
|
|
// Check perms
|
|
if (!HasPower(RequestingAgentID, groupID, GroupPowers.ChangeActions))
|
|
{
|
|
m_log.DebugFormat("[Groups]: ({0}) Attempt at updating group {1} denied because of lack of permission", RequestingAgentID, groupID);
|
|
return;
|
|
}
|
|
|
|
data.GroupID = groupID;
|
|
data.Data["Charter"] = charter;
|
|
data.Data["ShowInList"] = showInList ? "1" : "0";
|
|
data.Data["InsigniaID"] = insigniaID.ToString();
|
|
data.Data["MembershipFee"] = membershipFee.ToString();
|
|
data.Data["OpenEnrollment"] = openEnrollment ? "1" : "0";
|
|
data.Data["AllowPublish"] = allowPublish ? "1" : "0";
|
|
data.Data["MaturePublish"] = maturePublish ? "1" : "0";
|
|
|
|
m_Database.StoreGroup(data);
|
|
|
|
}
|
|
|
|
public ExtendedGroupRecord GetGroupRecord(string RequestingAgentID, UUID GroupID)
|
|
{
|
|
GroupData data = m_Database.RetrieveGroup(GroupID);
|
|
|
|
return _GroupDataToRecord(data);
|
|
}
|
|
|
|
public ExtendedGroupRecord GetGroupRecord(string RequestingAgentID, string GroupName)
|
|
{
|
|
GroupData data = m_Database.RetrieveGroup(GroupName);
|
|
|
|
return _GroupDataToRecord(data);
|
|
}
|
|
|
|
public List<DirGroupsReplyData> FindGroups(string RequestingAgentID, string search)
|
|
{
|
|
List<DirGroupsReplyData> groups = new List<DirGroupsReplyData>();
|
|
|
|
GroupData[] data = m_Database.RetrieveGroups(search);
|
|
|
|
if (data != null && data.Length > 0)
|
|
{
|
|
foreach (GroupData d in data)
|
|
{
|
|
// Don't list group proxies
|
|
if (d.Data.ContainsKey("Location") && d.Data["Location"] != string.Empty)
|
|
continue;
|
|
|
|
DirGroupsReplyData g = new DirGroupsReplyData();
|
|
g.groupID = d.GroupID;
|
|
|
|
if (d.Data.ContainsKey("Name"))
|
|
g.groupName = d.Data["Name"];
|
|
else
|
|
m_log.DebugFormat("[Groups]: Key Name not found");
|
|
|
|
g.members = m_Database.MemberCount(d.GroupID);
|
|
|
|
groups.Add(g);
|
|
}
|
|
}
|
|
|
|
return groups;
|
|
}
|
|
|
|
public List<ExtendedGroupMembersData> GetGroupMembers(string RequestingAgentID, UUID GroupID)
|
|
{
|
|
List<ExtendedGroupMembersData> members = new List<ExtendedGroupMembersData>();
|
|
|
|
GroupData group = m_Database.RetrieveGroup(GroupID);
|
|
if (group == null)
|
|
return members;
|
|
|
|
UUID ownerRoleID = new UUID(group.Data["OwnerRoleID"]);
|
|
|
|
RoleData[] roles = m_Database.RetrieveRoles(GroupID);
|
|
if (roles == null)
|
|
// something wrong with this group
|
|
return members;
|
|
List<RoleData> rolesList = new List<RoleData>(roles);
|
|
|
|
// Check visibility?
|
|
// When we don't want to check visibility, we pass it "all" as the requestingAgentID
|
|
bool checkVisibility = !RequestingAgentID.Equals("all");
|
|
m_log.DebugFormat("[ZZZ]: AgentID is {0}. checkVisibility is {1}", RequestingAgentID, checkVisibility);
|
|
if (checkVisibility)
|
|
{
|
|
// Is the requester a member of the group?
|
|
bool isInGroup = false;
|
|
if (m_Database.RetrieveMember(GroupID, RequestingAgentID) != null)
|
|
isInGroup = true;
|
|
|
|
if (!isInGroup) // reduce the roles to the visible ones
|
|
rolesList = rolesList.FindAll(r => (UInt64.Parse(r.Data["Powers"]) & (ulong)GroupPowers.MemberVisible) != 0);
|
|
}
|
|
|
|
MembershipData[] datas = m_Database.RetrieveMembers(GroupID);
|
|
if (datas == null || (datas != null && datas.Length == 0))
|
|
return members;
|
|
|
|
// OK, we have everything we need
|
|
|
|
foreach (MembershipData d in datas)
|
|
{
|
|
RoleMembershipData[] rolememberships = m_Database.RetrieveMemberRoles(GroupID, d.PrincipalID);
|
|
List<RoleMembershipData> rolemembershipsList = new List<RoleMembershipData>(rolememberships);
|
|
|
|
ExtendedGroupMembersData m = new ExtendedGroupMembersData();
|
|
|
|
// What's this person's current role in the group?
|
|
UUID selectedRole = new UUID(d.Data["SelectedRoleID"]);
|
|
RoleData selected = rolesList.Find(r => r.RoleID == selectedRole);
|
|
|
|
if (selected != null)
|
|
{
|
|
m.Title = selected.Data["Title"];
|
|
m.AgentPowers = UInt64.Parse(selected.Data["Powers"]);
|
|
|
|
m.AgentID = d.PrincipalID;
|
|
m.AcceptNotices = d.Data["AcceptNotices"] == "1" ? true : false;
|
|
m.Contribution = Int32.Parse(d.Data["Contribution"]);
|
|
m.ListInProfile = d.Data["ListInProfile"] == "1" ? true : false;
|
|
|
|
// Is this person an owner of the group?
|
|
m.IsOwner = (rolemembershipsList.Find(r => r.RoleID == ownerRoleID) != null) ? true : false;
|
|
|
|
members.Add(m);
|
|
}
|
|
}
|
|
|
|
return members;
|
|
}
|
|
|
|
public bool AddGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers, out string reason)
|
|
{
|
|
reason = string.Empty;
|
|
// check that the requesting agent has permissions to add role
|
|
if (!HasPower(RequestingAgentID, groupID, GroupPowers.CreateRole))
|
|
{
|
|
m_log.DebugFormat("[Groups]: ({0}) Attempt at creating role in group {1} denied because of lack of permission", RequestingAgentID, groupID);
|
|
reason = "Insufficient permission to create role";
|
|
return false;
|
|
}
|
|
|
|
return _AddOrUpdateGroupRole(RequestingAgentID, groupID, roleID, name, description, title, powers, true);
|
|
|
|
}
|
|
|
|
public bool UpdateGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers)
|
|
{
|
|
// check perms
|
|
if (!HasPower(RequestingAgentID, groupID, GroupPowers.ChangeActions))
|
|
{
|
|
m_log.DebugFormat("[Groups]: ({0}) Attempt at changing role in group {1} denied because of lack of permission", RequestingAgentID, groupID);
|
|
return false;
|
|
}
|
|
|
|
return _AddOrUpdateGroupRole(RequestingAgentID, groupID, roleID, name, description, title, powers, false);
|
|
}
|
|
|
|
public void RemoveGroupRole(string RequestingAgentID, UUID groupID, UUID roleID)
|
|
{
|
|
// check perms
|
|
if (!HasPower(RequestingAgentID, groupID, GroupPowers.DeleteRole))
|
|
{
|
|
m_log.DebugFormat("[Groups]: ({0}) Attempt at deleting role from group {1} denied because of lack of permission", RequestingAgentID, groupID);
|
|
return;
|
|
}
|
|
|
|
// Can't delete Everyone and Owners roles
|
|
if (roleID == UUID.Zero)
|
|
{
|
|
m_log.DebugFormat("[Groups]: Attempt at deleting Everyone role from group {0} denied", groupID);
|
|
return;
|
|
}
|
|
|
|
GroupData group = m_Database.RetrieveGroup(groupID);
|
|
if (group == null)
|
|
{
|
|
m_log.DebugFormat("[Groups]: Attempt at deleting role from non-existing group {0}", groupID);
|
|
return;
|
|
}
|
|
|
|
if (roleID == new UUID(group.Data["OwnerRoleID"]))
|
|
{
|
|
m_log.DebugFormat("[Groups]: Attempt at deleting Owners role from group {0} denied", groupID);
|
|
return;
|
|
}
|
|
|
|
_RemoveGroupRole(groupID, roleID);
|
|
}
|
|
|
|
public List<GroupRolesData> GetGroupRoles(string RequestingAgentID, UUID GroupID)
|
|
{
|
|
// TODO: check perms
|
|
return _GetGroupRoles(GroupID);
|
|
}
|
|
|
|
public List<ExtendedGroupRoleMembersData> GetGroupRoleMembers(string RequestingAgentID, UUID GroupID)
|
|
{
|
|
// TODO: check perms
|
|
|
|
// Is the requester a member of the group?
|
|
bool isInGroup = false;
|
|
if (m_Database.RetrieveMember(GroupID, RequestingAgentID) != null)
|
|
isInGroup = true;
|
|
|
|
return _GetGroupRoleMembers(GroupID, isInGroup);
|
|
}
|
|
|
|
public bool AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, string token, out string reason)
|
|
{
|
|
reason = string.Empty;
|
|
|
|
_AddAgentToGroup(RequestingAgentID, AgentID, GroupID, RoleID, token);
|
|
|
|
return true;
|
|
}
|
|
|
|
public void RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID)
|
|
{
|
|
// check perms
|
|
if (RequestingAgentID != AgentID && !HasPower(RequestingAgentID, GroupID, GroupPowers.Eject))
|
|
return;
|
|
|
|
_RemoveAgentFromGroup(RequestingAgentID, AgentID, GroupID);
|
|
}
|
|
|
|
public bool AddAgentToGroupInvite(string RequestingAgentID, UUID inviteID, UUID groupID, UUID roleID, string agentID)
|
|
{
|
|
// Check whether the invitee is already a member of the group
|
|
MembershipData m = m_Database.RetrieveMember(groupID, agentID);
|
|
if (m != null)
|
|
return false;
|
|
|
|
// Check permission to invite
|
|
if (!HasPower(RequestingAgentID, groupID, GroupPowers.Invite))
|
|
{
|
|
m_log.DebugFormat("[Groups]: ({0}) Attempt at inviting to group {1} denied because of lack of permission", RequestingAgentID, groupID);
|
|
return false;
|
|
}
|
|
|
|
// Check whether there are pending invitations and delete them
|
|
InvitationData invite = m_Database.RetrieveInvitation(groupID, agentID);
|
|
if (invite != null)
|
|
m_Database.DeleteInvite(invite.InviteID);
|
|
|
|
invite = new InvitationData();
|
|
invite.InviteID = inviteID;
|
|
invite.PrincipalID = agentID;
|
|
invite.GroupID = groupID;
|
|
invite.RoleID = roleID;
|
|
invite.Data = new Dictionary<string, string>();
|
|
|
|
return m_Database.StoreInvitation(invite);
|
|
}
|
|
|
|
public GroupInviteInfo GetAgentToGroupInvite(string RequestingAgentID, UUID inviteID)
|
|
{
|
|
InvitationData data = m_Database.RetrieveInvitation(inviteID);
|
|
|
|
if (data == null)
|
|
return null;
|
|
|
|
GroupInviteInfo inviteInfo = new GroupInviteInfo();
|
|
inviteInfo.AgentID = data.PrincipalID;
|
|
inviteInfo.GroupID = data.GroupID;
|
|
inviteInfo.InviteID = data.InviteID;
|
|
inviteInfo.RoleID = data.RoleID;
|
|
|
|
return inviteInfo;
|
|
}
|
|
|
|
public void RemoveAgentToGroupInvite(string RequestingAgentID, UUID inviteID)
|
|
{
|
|
m_Database.DeleteInvite(inviteID);
|
|
}
|
|
|
|
public bool AddAgentToGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
|
|
{
|
|
//if (!m_Database.CheckOwnerRole(RequestingAgentID, GroupID, RoleID))
|
|
// return;
|
|
|
|
// check permissions
|
|
bool limited = HasPower(RequestingAgentID, GroupID, GroupPowers.AssignMemberLimited);
|
|
bool unlimited = HasPower(RequestingAgentID, GroupID, GroupPowers.AssignMember) | IsOwner(RequestingAgentID, GroupID);
|
|
if (!limited || !unlimited)
|
|
{
|
|
m_log.DebugFormat("[Groups]: ({0}) Attempt at assigning {1} to role {2} denied because of lack of permission", RequestingAgentID, AgentID, RoleID);
|
|
return false;
|
|
}
|
|
|
|
// AssignMemberLimited means that the person can assign another person to the same roles that she has in the group
|
|
if (!unlimited && limited)
|
|
{
|
|
// check whether person's has this role
|
|
RoleMembershipData rolemembership = m_Database.RetrieveRoleMember(GroupID, RoleID, AgentID);
|
|
if (rolemembership == null)
|
|
{
|
|
m_log.DebugFormat("[Groups]: ({0}) Attempt at assigning {1} to role {2} denied because of limited permission", RequestingAgentID, AgentID, RoleID);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
_AddAgentToGroupRole(RequestingAgentID, AgentID, GroupID, RoleID);
|
|
|
|
return true;
|
|
}
|
|
|
|
public bool RemoveAgentFromGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
|
|
{
|
|
// Don't remove from Everyone role!
|
|
if (RoleID == UUID.Zero)
|
|
return false;
|
|
|
|
// check permissions
|
|
bool unlimited = HasPower(RequestingAgentID, GroupID, GroupPowers.AssignMember) || IsOwner(RequestingAgentID, GroupID);
|
|
if (!unlimited)
|
|
{
|
|
m_log.DebugFormat("[Groups]: ({0}) Attempt at removing {1} from role {2} denied because of lack of permission", RequestingAgentID, AgentID, RoleID);
|
|
return false;
|
|
}
|
|
|
|
RoleMembershipData rolemember = m_Database.RetrieveRoleMember(GroupID, RoleID, AgentID);
|
|
|
|
if (rolemember == null)
|
|
return false;
|
|
|
|
m_Database.DeleteRoleMember(rolemember);
|
|
|
|
// Find another role for this person
|
|
UUID newRoleID = UUID.Zero; // Everyone
|
|
RoleMembershipData[] rdata = m_Database.RetrieveMemberRoles(GroupID, AgentID);
|
|
if (rdata != null)
|
|
foreach (RoleMembershipData r in rdata)
|
|
{
|
|
if (r.RoleID != UUID.Zero)
|
|
{
|
|
newRoleID = r.RoleID;
|
|
break;
|
|
}
|
|
}
|
|
|
|
MembershipData member = m_Database.RetrieveMember(GroupID, AgentID);
|
|
if (member != null)
|
|
{
|
|
member.Data["SelectedRoleID"] = newRoleID.ToString();
|
|
m_Database.StoreMember(member);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public List<GroupRolesData> GetAgentGroupRoles(string RequestingAgentID, string AgentID, UUID GroupID)
|
|
{
|
|
List<GroupRolesData> roles = new List<GroupRolesData>();
|
|
// TODO: check permissions
|
|
|
|
RoleMembershipData[] data = m_Database.RetrieveMemberRoles(GroupID, AgentID);
|
|
if (data == null || (data != null && data.Length ==0))
|
|
return roles;
|
|
|
|
foreach (RoleMembershipData d in data)
|
|
{
|
|
RoleData rdata = m_Database.RetrieveRole(GroupID, d.RoleID);
|
|
if (rdata == null) // hippos
|
|
continue;
|
|
|
|
GroupRolesData r = new GroupRolesData();
|
|
r.Name = rdata.Data["Name"];
|
|
r.Powers = UInt64.Parse(rdata.Data["Powers"]);
|
|
r.RoleID = rdata.RoleID;
|
|
r.Title = rdata.Data["Title"];
|
|
|
|
roles.Add(r);
|
|
}
|
|
|
|
return roles;
|
|
}
|
|
|
|
public ExtendedGroupMembershipData SetAgentActiveGroup(string RequestingAgentID, string AgentID, UUID GroupID)
|
|
{
|
|
// TODO: check perms
|
|
PrincipalData principal = new PrincipalData();
|
|
principal.PrincipalID = AgentID;
|
|
principal.ActiveGroupID = GroupID;
|
|
m_Database.StorePrincipal(principal);
|
|
|
|
return GetAgentGroupMembership(RequestingAgentID, AgentID, GroupID);
|
|
}
|
|
|
|
public ExtendedGroupMembershipData GetAgentActiveMembership(string RequestingAgentID, string AgentID)
|
|
{
|
|
// 1. get the principal data for the active group
|
|
PrincipalData principal = m_Database.RetrievePrincipal(AgentID);
|
|
if (principal == null)
|
|
return null;
|
|
|
|
return GetAgentGroupMembership(RequestingAgentID, AgentID, principal.ActiveGroupID);
|
|
}
|
|
|
|
public ExtendedGroupMembershipData GetAgentGroupMembership(string RequestingAgentID, string AgentID, UUID GroupID)
|
|
{
|
|
return GetAgentGroupMembership(RequestingAgentID, AgentID, GroupID, null);
|
|
}
|
|
|
|
private ExtendedGroupMembershipData GetAgentGroupMembership(string RequestingAgentID, string AgentID, UUID GroupID, MembershipData membership)
|
|
{
|
|
// 2. get the active group
|
|
GroupData group = m_Database.RetrieveGroup(GroupID);
|
|
if (group == null)
|
|
return null;
|
|
|
|
// 3. get the membership info if we don't have it already
|
|
if (membership == null)
|
|
{
|
|
membership = m_Database.RetrieveMember(group.GroupID, AgentID);
|
|
if (membership == null)
|
|
return null;
|
|
}
|
|
|
|
// 4. get the active role
|
|
UUID activeRoleID = new UUID(membership.Data["SelectedRoleID"]);
|
|
RoleData role = m_Database.RetrieveRole(group.GroupID, activeRoleID);
|
|
|
|
ExtendedGroupMembershipData data = new ExtendedGroupMembershipData();
|
|
data.AcceptNotices = membership.Data["AcceptNotices"] == "1" ? true : false;
|
|
data.AccessToken = membership.Data["AccessToken"];
|
|
data.Active = true;
|
|
data.ActiveRole = activeRoleID;
|
|
data.AllowPublish = group.Data["AllowPublish"] == "1" ? true : false;
|
|
data.Charter = group.Data["Charter"];
|
|
data.Contribution = Int32.Parse(membership.Data["Contribution"]);
|
|
data.FounderID = new UUID(group.Data["FounderID"]);
|
|
data.GroupID = new UUID(group.GroupID);
|
|
data.GroupName = group.Data["Name"];
|
|
data.GroupPicture = new UUID(group.Data["InsigniaID"]);
|
|
if (role != null)
|
|
{
|
|
data.GroupPowers = UInt64.Parse(role.Data["Powers"]);
|
|
data.GroupTitle = role.Data["Title"];
|
|
}
|
|
data.ListInProfile = membership.Data["ListInProfile"] == "1" ? true : false;
|
|
data.MaturePublish = group.Data["MaturePublish"] == "1" ? true : false;
|
|
data.MembershipFee = Int32.Parse(group.Data["MembershipFee"]);
|
|
data.OpenEnrollment = group.Data["OpenEnrollment"] == "1" ? true : false;
|
|
data.ShowInList = group.Data["ShowInList"] == "1" ? true : false;
|
|
|
|
return data;
|
|
}
|
|
|
|
public List<GroupMembershipData> GetAgentGroupMemberships(string RequestingAgentID, string AgentID)
|
|
{
|
|
List<GroupMembershipData> memberships = new List<GroupMembershipData>();
|
|
|
|
// 1. Get all the groups that this person is a member of
|
|
MembershipData[] mdata = m_Database.RetrieveMemberships(AgentID);
|
|
|
|
if (mdata == null || (mdata != null && mdata.Length == 0))
|
|
return memberships;
|
|
|
|
foreach (MembershipData d in mdata)
|
|
{
|
|
GroupMembershipData gmember = GetAgentGroupMembership(RequestingAgentID, AgentID, d.GroupID, d);
|
|
if (gmember != null)
|
|
{
|
|
memberships.Add(gmember);
|
|
//m_log.DebugFormat("[XXX]: Member of {0} as {1}", gmember.GroupName, gmember.GroupTitle);
|
|
//Util.PrintCallStack();
|
|
}
|
|
}
|
|
|
|
return memberships;
|
|
}
|
|
|
|
public void SetAgentActiveGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
|
|
{
|
|
MembershipData data = m_Database.RetrieveMember(GroupID, AgentID);
|
|
if (data == null)
|
|
return;
|
|
|
|
data.Data["SelectedRoleID"] = RoleID.ToString();
|
|
m_Database.StoreMember(data);
|
|
}
|
|
|
|
public void UpdateMembership(string RequestingAgentID, string AgentID, UUID GroupID, bool AcceptNotices, bool ListInProfile)
|
|
{
|
|
// TODO: check perms
|
|
|
|
MembershipData membership = m_Database.RetrieveMember(GroupID, AgentID);
|
|
if (membership == null)
|
|
return;
|
|
|
|
membership.Data["AcceptNotices"] = AcceptNotices ? "1" : "0";
|
|
membership.Data["ListInProfile"] = ListInProfile ? "1" : "0";
|
|
|
|
m_Database.StoreMember(membership);
|
|
}
|
|
|
|
public bool AddGroupNotice(string RequestingAgentID, UUID groupID, UUID noticeID, string fromName, string subject, string message,
|
|
bool hasAttachment, byte attType, string attName, UUID attItemID, string attOwnerID)
|
|
{
|
|
// Check perms
|
|
if (!HasPower(RequestingAgentID, groupID, GroupPowers.SendNotices))
|
|
{
|
|
m_log.DebugFormat("[Groups]: ({0}) Attempt at sending notice to group {1} denied because of lack of permission", RequestingAgentID, groupID);
|
|
return false;
|
|
}
|
|
|
|
return _AddNotice(groupID, noticeID, fromName, subject, message, hasAttachment, attType, attName, attItemID, attOwnerID);
|
|
}
|
|
|
|
public GroupNoticeInfo GetGroupNotice(string RequestingAgentID, UUID noticeID)
|
|
{
|
|
NoticeData data = m_Database.RetrieveNotice(noticeID);
|
|
|
|
if (data == null)
|
|
return null;
|
|
|
|
return _NoticeDataToInfo(data);
|
|
}
|
|
|
|
public List<ExtendedGroupNoticeData> GetGroupNotices(string RequestingAgentID, UUID groupID)
|
|
{
|
|
NoticeData[] data = m_Database.RetrieveNotices(groupID);
|
|
List<ExtendedGroupNoticeData> infos = new List<ExtendedGroupNoticeData>();
|
|
|
|
if (data == null || (data != null && data.Length == 0))
|
|
return infos;
|
|
|
|
foreach (NoticeData d in data)
|
|
{
|
|
ExtendedGroupNoticeData info = _NoticeDataToData(d);
|
|
infos.Add(info);
|
|
}
|
|
|
|
return infos;
|
|
}
|
|
|
|
public void ResetAgentGroupChatSessions(string agentID)
|
|
{
|
|
}
|
|
|
|
public bool hasAgentBeenInvitedToGroupChatSession(string agentID, UUID groupID)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
public bool hasAgentDroppedGroupChatSession(string agentID, UUID groupID)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
public void AgentDroppedFromGroupChatSession(string agentID, UUID groupID)
|
|
{
|
|
}
|
|
|
|
public void AgentInvitedToGroupChatSession(string agentID, UUID groupID)
|
|
{
|
|
}
|
|
|
|
#region Actions without permission checks
|
|
|
|
protected void _AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
|
|
{
|
|
_AddAgentToGroup(RequestingAgentID, AgentID, GroupID, RoleID, string.Empty);
|
|
}
|
|
|
|
protected void _RemoveAgentFromGroup(string RequestingAgentID, string AgentID, UUID GroupID)
|
|
{
|
|
// 1. Delete membership
|
|
m_Database.DeleteMember(GroupID, AgentID);
|
|
|
|
// 2. Remove from rolememberships
|
|
m_Database.DeleteMemberAllRoles(GroupID, AgentID);
|
|
|
|
// 3. if it was active group, inactivate it
|
|
PrincipalData principal = m_Database.RetrievePrincipal(AgentID);
|
|
if (principal != null && principal.ActiveGroupID == GroupID)
|
|
{
|
|
principal.ActiveGroupID = UUID.Zero;
|
|
m_Database.StorePrincipal(principal);
|
|
}
|
|
}
|
|
|
|
protected void _AddAgentToGroup(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID, string accessToken)
|
|
{
|
|
// Check if it's already there
|
|
MembershipData data = m_Database.RetrieveMember(GroupID, AgentID);
|
|
if (data != null)
|
|
return;
|
|
|
|
// Add the membership
|
|
data = new MembershipData();
|
|
data.PrincipalID = AgentID;
|
|
data.GroupID = GroupID;
|
|
data.Data = new Dictionary<string, string>();
|
|
data.Data["SelectedRoleID"] = RoleID.ToString();
|
|
data.Data["Contribution"] = "0";
|
|
data.Data["ListInProfile"] = "1";
|
|
data.Data["AcceptNotices"] = "1";
|
|
data.Data["AccessToken"] = accessToken;
|
|
|
|
m_Database.StoreMember(data);
|
|
|
|
// Add principal to everyone role
|
|
_AddAgentToGroupRole(RequestingAgentID, AgentID, GroupID, UUID.Zero);
|
|
|
|
// Add principal to role, if different from everyone role
|
|
if (RoleID != UUID.Zero)
|
|
_AddAgentToGroupRole(RequestingAgentID, AgentID, GroupID, RoleID);
|
|
|
|
// Make thit this active group
|
|
PrincipalData pdata = new PrincipalData();
|
|
pdata.PrincipalID = AgentID;
|
|
pdata.ActiveGroupID = GroupID;
|
|
m_Database.StorePrincipal(pdata);
|
|
|
|
}
|
|
|
|
protected bool _AddOrUpdateGroupRole(string RequestingAgentID, UUID groupID, UUID roleID, string name, string description, string title, ulong powers, bool add)
|
|
{
|
|
RoleData data = m_Database.RetrieveRole(groupID, roleID);
|
|
|
|
if (add && data != null) // it already exists, can't create
|
|
{
|
|
m_log.DebugFormat("[Groups]: Group {0} already exists. Can't create it again", groupID);
|
|
return false;
|
|
}
|
|
|
|
if (!add && data == null) // it deosn't exist, can't update
|
|
{
|
|
m_log.DebugFormat("[Groups]: Group {0} doesn't exist. Can't update it", groupID);
|
|
return false;
|
|
}
|
|
|
|
if (add)
|
|
data = new RoleData();
|
|
|
|
data.GroupID = groupID;
|
|
data.RoleID = roleID;
|
|
data.Data = new Dictionary<string, string>();
|
|
data.Data["Name"] = name;
|
|
data.Data["Description"] = description;
|
|
data.Data["Title"] = title;
|
|
data.Data["Powers"] = powers.ToString();
|
|
|
|
return m_Database.StoreRole(data);
|
|
}
|
|
|
|
protected void _RemoveGroupRole(UUID groupID, UUID roleID)
|
|
{
|
|
m_Database.DeleteRole(groupID, roleID);
|
|
}
|
|
|
|
protected void _AddAgentToGroupRole(string RequestingAgentID, string AgentID, UUID GroupID, UUID RoleID)
|
|
{
|
|
RoleMembershipData data = m_Database.RetrieveRoleMember(GroupID, RoleID, AgentID);
|
|
if (data != null)
|
|
return;
|
|
|
|
data = new RoleMembershipData();
|
|
data.GroupID = GroupID;
|
|
data.PrincipalID = AgentID;
|
|
data.RoleID = RoleID;
|
|
m_Database.StoreRoleMember(data);
|
|
|
|
// Make it the SelectedRoleID
|
|
MembershipData membership = m_Database.RetrieveMember(GroupID, AgentID);
|
|
if (membership == null)
|
|
{
|
|
m_log.DebugFormat("[Groups]: ({0}) No such member {0} in group {1}", AgentID, GroupID);
|
|
return;
|
|
}
|
|
|
|
membership.Data["SelectedRoleID"] = RoleID.ToString();
|
|
m_Database.StoreMember(membership);
|
|
|
|
}
|
|
|
|
protected List<GroupRolesData> _GetGroupRoles(UUID groupID)
|
|
{
|
|
List<GroupRolesData> roles = new List<GroupRolesData>();
|
|
|
|
RoleData[] data = m_Database.RetrieveRoles(groupID);
|
|
|
|
if (data == null || (data != null && data.Length == 0))
|
|
return roles;
|
|
|
|
foreach (RoleData d in data)
|
|
{
|
|
GroupRolesData r = new GroupRolesData();
|
|
r.Description = d.Data["Description"];
|
|
r.Members = m_Database.RoleMemberCount(groupID, d.RoleID);
|
|
r.Name = d.Data["Name"];
|
|
r.Powers = UInt64.Parse(d.Data["Powers"]);
|
|
r.RoleID = d.RoleID;
|
|
r.Title = d.Data["Title"];
|
|
|
|
roles.Add(r);
|
|
}
|
|
|
|
return roles;
|
|
}
|
|
|
|
protected List<ExtendedGroupRoleMembersData> _GetGroupRoleMembers(UUID GroupID, bool isInGroup)
|
|
{
|
|
List<ExtendedGroupRoleMembersData> rmembers = new List<ExtendedGroupRoleMembersData>();
|
|
|
|
RoleData[] rdata = new RoleData[0];
|
|
if (!isInGroup)
|
|
{
|
|
rdata = m_Database.RetrieveRoles(GroupID);
|
|
if (rdata == null || (rdata != null && rdata.Length == 0))
|
|
return rmembers;
|
|
}
|
|
List<RoleData> rlist = new List<RoleData>(rdata);
|
|
if (!isInGroup)
|
|
rlist = rlist.FindAll(r => (UInt64.Parse(r.Data["Powers"]) & (ulong)GroupPowers.MemberVisible) != 0);
|
|
|
|
RoleMembershipData[] data = m_Database.RetrieveRolesMembers(GroupID);
|
|
|
|
if (data == null || (data != null && data.Length == 0))
|
|
return rmembers;
|
|
|
|
foreach (RoleMembershipData d in data)
|
|
{
|
|
if (!isInGroup)
|
|
{
|
|
RoleData rd = rlist.Find(_r => _r.RoleID == d.RoleID); // visible role
|
|
if (rd == null)
|
|
continue;
|
|
}
|
|
|
|
ExtendedGroupRoleMembersData r = new ExtendedGroupRoleMembersData();
|
|
r.MemberID = d.PrincipalID;
|
|
r.RoleID = d.RoleID;
|
|
|
|
rmembers.Add(r);
|
|
}
|
|
|
|
return rmembers;
|
|
}
|
|
|
|
protected bool _AddNotice(UUID groupID, UUID noticeID, string fromName, string subject, string message,
|
|
bool hasAttachment, byte attType, string attName, UUID attItemID, string attOwnerID)
|
|
{
|
|
NoticeData data = new NoticeData();
|
|
data.GroupID = groupID;
|
|
data.NoticeID = noticeID;
|
|
data.Data = new Dictionary<string, string>();
|
|
data.Data["FromName"] = fromName;
|
|
data.Data["Subject"] = subject;
|
|
data.Data["Message"] = message;
|
|
data.Data["HasAttachment"] = hasAttachment ? "1" : "0";
|
|
if (hasAttachment)
|
|
{
|
|
data.Data["AttachmentType"] = attType.ToString();
|
|
data.Data["AttachmentName"] = attName;
|
|
data.Data["AttachmentItemID"] = attItemID.ToString();
|
|
data.Data["AttachmentOwnerID"] = attOwnerID;
|
|
}
|
|
data.Data["TMStamp"] = ((uint)Util.UnixTimeSinceEpoch()).ToString();
|
|
|
|
return m_Database.StoreNotice(data);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region structure translations
|
|
ExtendedGroupRecord _GroupDataToRecord(GroupData data)
|
|
{
|
|
if (data == null)
|
|
return null;
|
|
|
|
ExtendedGroupRecord rec = new ExtendedGroupRecord();
|
|
rec.AllowPublish = data.Data["AllowPublish"] == "1" ? true : false;
|
|
rec.Charter = data.Data["Charter"];
|
|
rec.FounderID = new UUID(data.Data["FounderID"]);
|
|
rec.GroupID = data.GroupID;
|
|
rec.GroupName = data.Data["Name"];
|
|
rec.GroupPicture = new UUID(data.Data["InsigniaID"]);
|
|
rec.MaturePublish = data.Data["MaturePublish"] == "1" ? true : false;
|
|
rec.MembershipFee = Int32.Parse(data.Data["MembershipFee"]);
|
|
rec.OpenEnrollment = data.Data["OpenEnrollment"] == "1" ? true : false;
|
|
rec.OwnerRoleID = new UUID(data.Data["OwnerRoleID"]);
|
|
rec.ShowInList = data.Data["ShowInList"] == "1" ? true : false;
|
|
rec.ServiceLocation = data.Data["Location"];
|
|
rec.MemberCount = m_Database.MemberCount(data.GroupID);
|
|
rec.RoleCount = m_Database.RoleCount(data.GroupID);
|
|
|
|
return rec;
|
|
}
|
|
|
|
GroupNoticeInfo _NoticeDataToInfo(NoticeData data)
|
|
{
|
|
GroupNoticeInfo notice = new GroupNoticeInfo();
|
|
notice.GroupID = data.GroupID;
|
|
notice.Message = data.Data["Message"];
|
|
notice.noticeData = _NoticeDataToData(data);
|
|
|
|
return notice;
|
|
}
|
|
|
|
ExtendedGroupNoticeData _NoticeDataToData(NoticeData data)
|
|
{
|
|
ExtendedGroupNoticeData notice = new ExtendedGroupNoticeData();
|
|
notice.FromName = data.Data["FromName"];
|
|
notice.NoticeID = data.NoticeID;
|
|
notice.Subject = data.Data["Subject"];
|
|
notice.Timestamp = uint.Parse((string)data.Data["TMStamp"]);
|
|
notice.HasAttachment = data.Data["HasAttachment"] == "1" ? true : false;
|
|
if (notice.HasAttachment)
|
|
{
|
|
notice.AttachmentName = data.Data["AttachmentName"];
|
|
notice.AttachmentItemID = new UUID(data.Data["AttachmentItemID"].ToString());
|
|
notice.AttachmentType = byte.Parse(data.Data["AttachmentType"].ToString());
|
|
notice.AttachmentOwnerID = data.Data["AttachmentOwnerID"].ToString();
|
|
}
|
|
|
|
|
|
return notice;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region permissions
|
|
private bool HasPower(string agentID, UUID groupID, GroupPowers power)
|
|
{
|
|
RoleMembershipData[] rmembership = m_Database.RetrieveMemberRoles(groupID, agentID);
|
|
if (rmembership == null || (rmembership != null && rmembership.Length == 0))
|
|
return false;
|
|
|
|
foreach (RoleMembershipData rdata in rmembership)
|
|
{
|
|
RoleData role = m_Database.RetrieveRole(groupID, rdata.RoleID);
|
|
if ( (UInt64.Parse(role.Data["Powers"]) & (ulong)power) != 0 )
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private bool IsOwner(string agentID, UUID groupID)
|
|
{
|
|
GroupData group = m_Database.RetrieveGroup(groupID);
|
|
if (group == null)
|
|
return false;
|
|
|
|
RoleMembershipData rmembership = m_Database.RetrieveRoleMember(groupID, new UUID(group.Data["OwnerRoleID"]), agentID);
|
|
if (rmembership == null)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
#endregion
|
|
|
|
}
|
|
}
|