예제 #1
0
        public static bool GetFeatureRequest(this Transaction transaction, out FeatureRequest featureRequest)
        {
            if (transaction is IFeatureRequestTransaction featureRequestTransaction)
            {
                featureRequest = featureRequestTransaction.Request;
                return(featureRequest != null);
            }

            featureRequest = null;
            return(false);
        }
예제 #2
0
 public virtual (bool, int) ValidateFeatureRequest(FeatureRequest featureRequest, Transaction transaction) => (false, 0);
예제 #3
0
        public override void ConsumeFeatureRequest(CommitItems commitItems, Commit commit, FeatureRequest featureRequest, Transaction transaction)
        {
            var friendRequest = featureRequest as FriendRequest;
            var friendMode    = friendRequest.FriendMode;
            var receiverData  = transaction.GetFeature <Receiver>(Receiver.FeatureId);

            var accountId = transaction.AccountId;
            var friendId  = receiverData.Receivers[0];

            var accountContainer = CurrentChain.GetFeatureAccount(accountId).GetOrAddFeatureContainer <FriendContainer>(FeatureId);
            var friendContainer  = CurrentChain.GetFeatureAccount(friendId).GetOrAddFeatureContainer <FriendContainer>(FeatureId);

            if (friendMode == FriendRequestMode.SendInvitation)
            {
                accountContainer.AddFriendInvitation(new FriendInvitation(accountId, friendId, accountId), transaction);
                friendContainer.AddFriendInvitation(new FriendInvitation(friendId, accountId, accountId), transaction);
            }
            else if (friendMode == FriendRequestMode.AcceptInvitation)
            {
                accountContainer.AcceptFriendInvitation(friendId, transaction);
                friendContainer.AcceptFriendInvitation(accountId, transaction);
            }
            else if (friendMode == FriendRequestMode.RejectInvitation)
            {
                accountContainer.RejectFriendInvitation(friendId, transaction);
                friendContainer.RejectFriendInvitation(accountId, transaction);
            }
            else if (friendMode == FriendRequestMode.Remove)
            {
                accountContainer.RemoveFriend(friendId, transaction);
                friendContainer.RemoveFriend(accountId, transaction);
            }

            commitItems.DirtyAccounts.Add(accountId);
            commitItems.DirtyAccounts.Add(friendId);
        }
예제 #4
0
        public override (bool, int) ValidateFeatureRequest(FeatureRequest featureRequest, Transaction transaction)
        {
            var error        = FriendError.None;
            var receiverData = transaction.GetFeature <Receiver>(Receiver.FeatureId);

            if (receiverData == null)
            {
                error = FriendError.ReceiverFeatureRequired;
                goto end;
            }

            if (receiverData.Receivers.Count != 1)
            {
                error = FriendError.InvalidFeatureRequest;
                goto end;
            }

            if (!(featureRequest is FriendRequest friendRequest))
            {
                error = FriendError.InvalidFeatureRequest;
                goto end;
            }

            var accountId = transaction.AccountId;
            var fanId     = receiverData.Receivers[0];

            var friendId = transaction.GetFeature <Receiver>(Receiver.FeatureId).Receivers[0];

            var friendTransaction = friendRequest;
            var dataAccount       = CurrentChain.GetFeatureAccount(accountId).GetFeatureContainer <FriendContainer>(FeatureId);
            var friendAccount     = CurrentChain.GetFeatureAccount(fanId).GetFeatureContainer <FriendContainer>(FeatureId);

            var friendMode = friendTransaction.FriendMode;

            if (friendMode == FriendRequestMode.SendInvitation)
            {
                if (friendId == accountId)
                {
                    error = FriendError.InvalidFriend;
                    goto end;
                }

                var hasError = false;
                if (dataAccount != null)
                {
                    if (dataAccount.HasFriend(friendId))
                    {
                        error = FriendError.AlreadyFriends;
                        goto end;
                    }

                    if (dataAccount.GetFriendInvitation(friendId) != null)
                    {
                        hasError = true;
                    }
                }
                else
                {
                    if (friendAccount != null && friendAccount.GetFriendInvitation(accountId) != null)
                    {
                        hasError = true;
                    }
                }

                if (hasError)
                {
                    error = FriendError.AlreadyInvited;
                    goto end;
                }
            }
            else if (friendMode == FriendRequestMode.AcceptInvitation || friendMode == FriendRequestMode.RejectInvitation)
            {
                if (dataAccount == null || friendAccount == null)
                {
                    error = FriendError.Unknown;
                    goto end;
                }

                var invitation       = dataAccount.GetFriendInvitation(friendId);
                var friendInvitation = friendAccount.GetFriendInvitation(accountId);

                if (invitation == null || !invitation.HasFriendAccountApproval || friendInvitation == null || !friendInvitation.HasAccountApproval)
                {
                    error = FriendError.InvalidFriend;
                    goto end;
                }
            }
            else if (friendMode == FriendRequestMode.Remove)
            {
                if (dataAccount == null || friendAccount == null)
                {
                    error = FriendError.Unknown;
                    goto end;
                }

                var isFriend      = dataAccount.HasFriend(friendId);
                var hasInvitation = dataAccount.GetFriendInvitation(friendId) != null;

                if (!(isFriend || hasInvitation))
                {
                    error = FriendError.InvalidFriend;
                    goto end;
                }
            }
            else
            {
                error = FriendError.Unknown;
                goto end;
            }

end:

            return(error == FriendError.None, (int)error);
        }
예제 #5
0
        public override void ConsumeFeatureRequest(CommitItems commitItems, Commit commit, FeatureRequest featureRequest, Transaction transaction)
        {
            var fanRequest   = featureRequest as FanRequest;
            var fanMode      = fanRequest.FanMode;
            var receiverData = transaction.GetFeature <Receiver>(Receiver.FeatureId);

            var accountId = transaction.AccountId;
            var fanId     = receiverData.Receivers[0];

            var accountContainer = CurrentChain.GetFeatureAccount(accountId).GetOrAddFeatureContainer <FanContainer>(FeatureId);
            var fanContainer     = CurrentChain.GetFeatureAccount(fanId).GetOrAddFeatureContainer <FanContainer>(FeatureId);

            if (fanMode == FanRequestMode.AddFanOf)
            {
                accountContainer.AddFanOf(fanId, transaction);
                fanContainer.AddFan(accountId, transaction);
            }
            else if (fanMode == FanRequestMode.RemoveFanOf)
            {
                accountContainer.RemoveFanOf(fanId, transaction);
                fanContainer.RemoveFan(accountId, transaction);
            }

            commitItems.DirtyAccounts.Add(accountId);
            commitItems.DirtyAccounts.Add(fanId);
        }
예제 #6
0
        public override (bool, int) ValidateFeatureRequest(FeatureRequest featureRequest, Transaction transaction)
        {
            var error        = FanError.None;
            var receiverData = transaction.GetFeature <Receiver>(Receiver.FeatureId);

            if (receiverData == null)
            {
                error = FanError.ReceiverFeatureRequired;
                goto end;
            }

            if (receiverData.Receivers.Count != 1)
            {
                error = FanError.InvalidFeatureRequest;
                goto end;
            }

            if (!(featureRequest is FanRequest fanRequest))
            {
                error = FanError.InvalidFeatureRequest;
                goto end;
            }

            var accountId = transaction.AccountId;
            var fanId     = receiverData.Receivers[0];

            if (fanId == accountId)
            {
                error = FanError.InvalidFan;
                goto end;
            }

            var accountContainer = CurrentChain.GetFeatureAccount(accountId).GetFeatureContainer <FanContainer>(FeatureId);
            var fanContainer     = CurrentChain.GetFeatureAccount(fanId).GetFeatureContainer <FanContainer>(FeatureId);

            if (accountContainer != null)
            {
                var fanOf = accountContainer.IsFanOf(fanId);
                if (fanRequest.FanMode == FanRequestMode.AddFanOf)
                {
                    if (fanOf)
                    {
                        error = FanError.AlreadyFan;
                        goto end;
                    }
                }
                else if (fanRequest.FanMode == FanRequestMode.RemoveFanOf)
                {
                    if (!fanOf)
                    {
                        error = FanError.InvalidFan;
                        goto end;
                    }
                }
                else
                {
                    error = FanError.Unknown;
                    goto end;
                }
            }
            else
            {
                if (fanContainer != null)
                {
                    var isFan = fanContainer.IsFan(accountId);
                    if (fanRequest.FanMode == FanRequestMode.AddFanOf)
                    {
                        if (isFan)
                        {
                            error = FanError.AlreadyFan;
                            goto end;
                        }
                    }
                    else if (fanRequest.FanMode == FanRequestMode.RemoveFanOf)
                    {
                        if (!isFan)
                        {
                            error = FanError.InvalidFan;
                            goto end;
                        }
                    }
                    else
                    {
                        error = FanError.Unknown;
                        goto end;
                    }
                }
            }
end:

            return(error == FanError.None, (int)error);
        }
예제 #7
0
        public override void ConsumeFeatureRequest(CommitItems commitItems, Commit commit, FeatureRequest featureRequest, Transaction transaction)
        {
            var accountId = transaction.AccountId;

            if (featureRequest.RequestId == GroupRegistrationRequest.GroupRegistrationRequestId)
            {
                var feature      = transaction.GetFeature <GroupAdministration>(FeatureId);
                var container    = CurrentChain.GetFeatureAccount(accountId).GetOrAddFeatureContainer <GroupAdministrationContainer>(FeatureId);
                var registration = featureRequest as GroupRegistrationRequest;

                var groupid = feature.NewGroupId;
                var group   = new GroupAdministrationInfo(groupid, accountId, transaction.TransactionId, transaction.Timestamp, registration.GroupFlags);

                lock (this)
                    _groups[groupid] = group;
                _groupStorage.Storage.AddEntry(groupid, group.ToByteArray());

                container.AddGroup(groupid);
                commitItems.DirtyAccounts.Add(accountId);
            }
            else if (featureRequest.RequestId == GroupAdministrationRequest.GroupAdministrationRequestId)
            {
                var request = featureRequest as GroupAdministrationRequest;
                var groupId = request.GroupId;
                var group   = GetGroupInfo(groupId);

                group.ConsumeGroupAdministrationRequest(transaction, request, out var dirtyGroupAccounts);
                commit.DirtyIds.Add(groupId);

                foreach (var added in dirtyGroupAccounts.AddedAccounts)
                {
                    var container = CurrentChain.GetFeatureAccount(added).GetOrAddFeatureContainer <GroupAdministrationContainer>(FeatureId);
                    container.AddGroup(groupId);
                    commitItems.DirtyAccounts.Add(added);
                }

                foreach (var removed in dirtyGroupAccounts.RemovedAccounts)
                {
                    var container = CurrentChain.GetFeatureAccount(removed).GetOrAddFeatureContainer <GroupAdministrationContainer>(FeatureId);
                    container.RemoveGroup(groupId);
                    commitItems.DirtyAccounts.Add(removed);
                }
            }
        }
예제 #8
0
        public override (bool, int) ValidateFeatureRequest(FeatureRequest featureRequest, Transaction transaction)
        {
            if (featureRequest.RequestId == GroupRegistrationRequest.GroupRegistrationRequestId)
            {
                var feature = transaction.GetFeature <GroupAdministration>(FeatureId);
                if (feature == null || !feature.IsRegistration)
                {
                    return(false, (int)GroupAdministrationError.GroupAdministrationFeatureMissing);
                }

                return(true, 0);
            }
            else if (featureRequest.RequestId == GroupAdministrationRequest.GroupAdministrationRequestId)
            {
                var error = GroupAdministrationError.None;

                var groupData = transaction.GetFeature <GroupAdministration>(FeatureId);
                if (groupData == null || !groupData.IsAdministration)
                {
                    error = GroupAdministrationError.GroupAdministrationFeatureMissing;
                    goto end;
                }

                var accountId = transaction.AccountId;
                var request   = featureRequest as GroupAdministrationRequest;
                var selfOnly  = request.SelfOnly(accountId);

                var receiverData = transaction.GetFeature <Receiver>(Receiver.FeatureId);
                if (receiverData == null && !selfOnly)
                {
                    error = GroupAdministrationError.ReceiverFeatureMissing;
                    goto end;
                }

                var group = GetGroupInfo(request.GroupId);
                if (group == null)
                {
                    error = GroupAdministrationError.InvalidGroup;
                    goto end;
                }

                var groupAccount = group.IsGroupAccount(accountId, out var accountFlags);
                var groupAdmin   = groupAccount && (accountFlags & GroupAccountFlags.Admin) != 0;

                if (!(selfOnly || groupAdmin))
                {
                    error = GroupAdministrationError.NoGroupPermission;
                    goto end;
                }

                if (request.UpdatedFlags.Count > 0)
                {
                    if (!groupAdmin)
                    {
                        error = GroupAdministrationError.NoGroupPermission;
                        goto end;
                    }

                    foreach (var update in request.UpdatedFlags)
                    {
                        var flags = update.Value;
                        if ((flags & GroupAccountFlags.HasAccountApproval) != 0 || (flags & GroupAccountFlags.HasAdminApproval) != 0)
                        {
                            error = GroupAdministrationError.NoGroupPermission;
                            goto end;
                        }
                    }
                }

                foreach (var removed in request.RemovedAccounts)
                {
                    if (!group.IsGroupAccountOrPending(removed))
                    {
                        error = GroupAdministrationError.NoGroupAccount;
                        goto end;
                    }
                }

                foreach (var added in request.AddedAccounts)
                {
                    var id    = added.Key;
                    var flags = added.Value;

                    if (group.IsGroupAccount(id))
                    {
                        error = GroupAdministrationError.GroupAlreadyAdded;
                        goto end;
                    }

                    if (groupAdmin)
                    {
                        if ((flags & GroupAccountFlags.HasAdminApproval) == 0)
                        {
                            error = GroupAdministrationError.NoGroupApproval;
                            goto end;
                        }
                    }
                    else
                    {
                        if (flags != GroupAccountFlags.HasAccountApproval)
                        {
                            error = GroupAdministrationError.NoGroupApproval;
                            goto end;
                        }
                    }

                    var pending = group.IsPendingAccount(id, out var pendingFlags);
                    if (pending)
                    {
                        if (groupAdmin)
                        {
                            if ((pendingFlags & GroupAccountFlags.HasAdminApproval) != 0)
                            {
                                error = GroupAdministrationError.GroupAlreadyPending;
                                goto end;
                            }

                            // no account approval?
                            if ((pendingFlags & GroupAccountFlags.HasAccountApproval) == 0)
                            {
                                error = GroupAdministrationError.NoGroupApproval;
                                goto end;
                            }
                        }
                        else
                        {
                            if ((pendingFlags & GroupAccountFlags.HasAccountApproval) != 0)
                            {
                                error = GroupAdministrationError.GroupAlreadyPending;
                                goto end;
                            }

                            // no admin approval?
                            if ((pendingFlags & GroupAccountFlags.HasAdminApproval) == 0)
                            {
                                error = GroupAdministrationError.NoGroupApproval;
                                goto end;
                            }
                        }
                    }
                    else
                    {
                        if ((group.Flags & GroupFlags.AdminOnlyInvitation) != 0 && !groupAdmin)
                        {
                            error = GroupAdministrationError.NoGroupPermission;
                            goto end;
                        }
                    }
                }
end:
                return(error == GroupAdministrationError.None, (int)error);
            }

            return(false, (int)GroupAdministrationError.InvalidFeatureRequest);
        }