SyncUserInbounds reconciles a user's inbound assignments. Exported for payment webhook use.
(userID string, selectedInboundIDs []string)
| 569 | |
| 570 | // SyncUserInbounds reconciles a user's inbound assignments. Exported for payment webhook use. |
| 571 | func (h *Handler) SyncUserInbounds(userID string, selectedInboundIDs []string) ([]string, error) { |
| 572 | wantedInbounds := make(map[string]inbounds.Inbound) |
| 573 | for _, ibID := range selectedInboundIDs { |
| 574 | ib, err := h.ibStore.GetInbound(ibID) |
| 575 | if err != nil { |
| 576 | continue |
| 577 | } |
| 578 | wantedInbounds[ibID] = ib |
| 579 | } |
| 580 | existing, err := h.userStore.ListDirectUserInboundsByUser(userID) |
| 581 | if err != nil { |
| 582 | return nil, err |
| 583 | } |
| 584 | existingByInbound := make(map[string]users.UserInbound, len(existing)) |
| 585 | for _, acc := range existing { |
| 586 | existingByInbound[acc.InboundID] = acc |
| 587 | } |
| 588 | changedNodeIDs := make(map[string]struct{}) |
| 589 | for ibID, ib := range wantedInbounds { |
| 590 | if _, ok := existingByInbound[ibID]; !ok { |
| 591 | secret := panelRandomToken(12) |
| 592 | if ib.Protocol == "shadowsocks" && strings.HasPrefix(ib.Method, "2022-") { |
| 593 | secret = generateSSPassword(ib.Method) |
| 594 | } |
| 595 | acc := users.UserInbound{ |
| 596 | ID: idgen.NextString(), |
| 597 | UserID: userID, |
| 598 | InboundID: ibID, |
| 599 | NodeID: ib.NodeID, |
| 600 | UUID: panelRandomUUID(), |
| 601 | Secret: secret, |
| 602 | } |
| 603 | if _, err := h.userStore.UpsertUserInbound(acc); err != nil { |
| 604 | return nil, err |
| 605 | } |
| 606 | changedNodeIDs[ib.NodeID] = struct{}{} |
| 607 | } |
| 608 | } |
| 609 | for ibID, acc := range existingByInbound { |
| 610 | if _, wanted := wantedInbounds[ibID]; !wanted { |
| 611 | if err := h.userStore.DeleteUserInbound(acc.ID); err != nil { |
| 612 | return nil, err |
| 613 | } |
| 614 | changedNodeIDs[acc.NodeID] = struct{}{} |
| 615 | } |
| 616 | } |
| 617 | affected := make([]string, 0, len(changedNodeIDs)) |
| 618 | for id := range changedNodeIDs { |
| 619 | affected = append(affected, id) |
| 620 | } |
| 621 | return affected, nil |
| 622 | } |
| 623 | |
| 624 | func collectUserIDs(accesses []users.UserInbound) []string { |
| 625 | seen := make(map[string]struct{}) |
no test coverage detected