(ctx context.Context, req *api.PerformUploadKeysRequest, res *api.PerformUploadKeysResponse)
| 698 | } |
| 699 | |
| 700 | func (a *KeyInternalAPI) uploadOneTimeKeys(ctx context.Context, req *api.PerformUploadKeysRequest, res *api.PerformUploadKeysResponse) { |
| 701 | if req.UserID == "" { |
| 702 | res.Error = &api.KeyError{ |
| 703 | Err: "user ID missing", |
| 704 | } |
| 705 | } |
| 706 | if req.DeviceID != "" && len(req.OneTimeKeys) == 0 { |
| 707 | counts, err := a.DB.OneTimeKeysCount(ctx, req.UserID, req.DeviceID) |
| 708 | if err != nil { |
| 709 | res.Error = &api.KeyError{ |
| 710 | Err: fmt.Sprintf("a.DB.OneTimeKeysCount: %s", err), |
| 711 | } |
| 712 | } |
| 713 | if counts != nil { |
| 714 | res.OneTimeKeyCounts = append(res.OneTimeKeyCounts, *counts) |
| 715 | } |
| 716 | return |
| 717 | } |
| 718 | for _, key := range req.OneTimeKeys { |
| 719 | // grab existing keys based on (user/device/algorithm/key ID) |
| 720 | keyIDsWithAlgorithms := make([]string, len(key.KeyJSON)) |
| 721 | i := 0 |
| 722 | for keyIDWithAlgo := range key.KeyJSON { |
| 723 | keyIDsWithAlgorithms[i] = keyIDWithAlgo |
| 724 | i++ |
| 725 | } |
| 726 | existingKeys, err := a.DB.ExistingOneTimeKeys(ctx, req.UserID, req.DeviceID, keyIDsWithAlgorithms) |
| 727 | if err != nil { |
| 728 | res.KeyError(req.UserID, req.DeviceID, &api.KeyError{ |
| 729 | Err: "failed to query existing one-time keys: " + err.Error(), |
| 730 | }) |
| 731 | continue |
| 732 | } |
| 733 | for keyIDWithAlgo := range existingKeys { |
| 734 | // if keys exist and the JSON doesn't match, error out as the key already exists |
| 735 | if !bytes.Equal(existingKeys[keyIDWithAlgo], key.KeyJSON[keyIDWithAlgo]) { |
| 736 | res.KeyError(req.UserID, req.DeviceID, &api.KeyError{ |
| 737 | Err: fmt.Sprintf("%s device %s: algorithm / key ID %s one-time key already exists", req.UserID, req.DeviceID, keyIDWithAlgo), |
| 738 | }) |
| 739 | continue |
| 740 | } |
| 741 | } |
| 742 | // store one-time keys |
| 743 | counts, err := a.DB.StoreOneTimeKeys(ctx, key) |
| 744 | if err != nil { |
| 745 | res.KeyError(req.UserID, req.DeviceID, &api.KeyError{ |
| 746 | Err: fmt.Sprintf("%s device %s : failed to store one-time keys: %s", req.UserID, req.DeviceID, err.Error()), |
| 747 | }) |
| 748 | continue |
| 749 | } |
| 750 | // collect counts |
| 751 | res.OneTimeKeyCounts = append(res.OneTimeKeyCounts, *counts) |
| 752 | } |
| 753 | |
| 754 | } |
| 755 | |
| 756 | func emitDeviceKeyChanges(producer KeyChangeProducer, existing, new []api.DeviceMessage, onlyUpdateDisplayName bool) error { |
| 757 | // if we only want to update the display names, we can skip the checks below |
no test coverage detected