コード例 #1
0
ファイル: SystemController.cs プロジェクト: xSke/PluralKit
    public async Task <IActionResult> PostSwitch([FromBody] PostSwitchParams param)
    {
        if (param.Members.Distinct().Count() != param.Members.Count)
        {
            return(BadRequest("Duplicate members in member list."));
        }

        await using var conn = await _db.Obtain();

        // We get the current switch, if it exists
        var latestSwitch = await _repo.GetLatestSwitch(User.CurrentSystem());

        if (latestSwitch != null)
        {
            var latestSwitchMembers = _repo.GetSwitchMembers(conn, latestSwitch.Id);

            // Bail if this switch is identical to the latest one
            if (await latestSwitchMembers.Select(m => m.Hid).SequenceEqualAsync(param.Members.ToAsyncEnumerable()))
            {
                return(BadRequest("New members identical to existing fronters."));
            }
        }

        // Resolve member objects for all given IDs
        var membersList =
            (await conn.QueryAsync <PKMember>("select * from members where hid = any(@Hids)",
                                              new { Hids = param.Members })).ToList();

        foreach (var member in membersList)
        {
            if (member.System != User.CurrentSystem())
            {
                return(BadRequest($"Cannot switch to member '{member.Hid}' not in system."));
            }
        }

        // membersList is in DB order, and we want it in actual input order
        // so we go through a dict and map the original input appropriately
        var membersDict = membersList.ToDictionary(m => m.Hid);

        var membersInOrder = new List <PKMember>();

        // We do this without .Select() since we want to have the early return bail if it doesn't find the member
        foreach (var givenMemberId in param.Members)
        {
            if (!membersDict.TryGetValue(givenMemberId, out var member))
            {
                return(BadRequest($"Member '{givenMemberId}' not found."));
            }
            membersInOrder.Add(member);
        }

        // Finally, log the switch (yay!)
        await _repo.AddSwitch(conn, User.CurrentSystem(), membersInOrder.Select(m => m.Id).ToList());

        return(NoContent());
    }
コード例 #2
0
ファイル: SwitchControllerV2.cs プロジェクト: xSke/PluralKit
    public async Task <IActionResult> SwitchCreate(string systemRef, [FromBody] PostSwitchParams data)
    {
        var system = await ResolveSystem(systemRef);

        if (system == null)
        {
            throw Errors.SystemNotFound;
        }
        if (ContextFor(system) != LookupContext.ByOwner)
        {
            throw Errors.GenericMissingPermissions;
        }

        if (data.Members.Distinct().Count() != data.Members.Count)
        {
            throw Errors.DuplicateMembersInList;
        }

        if (data.Timestamp != null && await _repo.GetSwitches(system.Id).Select(x => x.Timestamp)
            .ContainsAsync(data.Timestamp.Value))
        {
            throw Errors.SameSwitchTimestampError;
        }

        var members = new List <PKMember>();

        foreach (var memberRef in data.Members)
        {
            var member = await ResolveMember(memberRef);

            if (member == null)
            {
                throw Errors.MemberNotFoundWithRef(memberRef);
            }
            if (member.System != system.Id)
            {
                throw Errors.NotOwnMemberErrorWithRef(memberRef);
            }
            members.Add(member);
        }

        // We get the current switch, if it exists
        var latestSwitch = await _repo.GetLatestSwitch(system.Id);

        if (latestSwitch != null && (data.Timestamp == null || data.Timestamp > latestSwitch.Timestamp))
        {
            var latestSwitchMembers = _db.Execute(conn => _repo.GetSwitchMembers(conn, latestSwitch.Id));

            // Bail if this switch is identical to the latest one
            if (await latestSwitchMembers.Select(m => m.Hid)
                .SequenceEqualAsync(members.Select(m => m.Hid).ToAsyncEnumerable()))
            {
                throw Errors.SameSwitchMembersError;
            }
        }

        var newSwitch =
            await _db.Execute(conn => _repo.AddSwitch(conn, system.Id, members.Select(m => m.Id).ToList()));

        if (data.Timestamp != null)
        {
            await _repo.MoveSwitch(newSwitch.Id, data.Timestamp.Value);
        }

        return(Ok(new FrontersReturnNew
        {
            Uuid = newSwitch.Uuid,
            Timestamp = data.Timestamp != null ? data.Timestamp.Value : newSwitch.Timestamp,
            Members = members.Select(x => x.ToJson(LookupContext.ByOwner, v: APIVersion.V2)),
        }));
    }