CopyObject enriches request metadata for CopyObject with Encryption Materials, if required by the datasource
(ctx context.Context, from *tree.Node, to *tree.Node, requestData *models.CopyRequestData)
| 303 | |
| 304 | // CopyObject enriches request metadata for CopyObject with Encryption Materials, if required by the datasource |
| 305 | func (e *Handler) CopyObject(ctx context.Context, from *tree.Node, to *tree.Node, requestData *models.CopyRequestData) (models.ObjectInfo, error) { |
| 306 | srcInfo, er1 := nodes.GetBranchInfo(ctx, "from") |
| 307 | destInfo, er2 := nodes.GetBranchInfo(ctx, "to") |
| 308 | if er1 != nil || er2 != nil { |
| 309 | return models.ObjectInfo{}, errors.Tag(er1, er2) |
| 310 | } |
| 311 | readCtx := nodes.WithBranchInfo(ctx, "in", srcInfo, true) |
| 312 | writeCtx := nodes.WithBranchInfo(ctx, "in", destInfo, true) |
| 313 | // Ds are not encrypted, let if flow |
| 314 | if srcInfo.EncryptionMode != object.EncryptionMode_MASTER && destInfo.EncryptionMode != object.EncryptionMode_MASTER { |
| 315 | return e.Next.CopyObject(ctx, from, to, requestData) |
| 316 | } |
| 317 | if requestData.Metadata == nil { |
| 318 | requestData.Metadata = map[string]string{} |
| 319 | } |
| 320 | // request type |
| 321 | move := requestData.IsMove() |
| 322 | sameClient := destInfo.Client == srcInfo.Client |
| 323 | |
| 324 | if move && sameClient { |
| 325 | // Move on same DS will maintain all metadata, nothing special to do for encryption |
| 326 | return e.Next.CopyObject(ctx, from, to, requestData) |
| 327 | } |
| 328 | |
| 329 | cloneFrom := from.Clone() |
| 330 | cloneTo := to.Clone() |
| 331 | if sameClient { |
| 332 | if len(cloneFrom.Uuid) == 0 { |
| 333 | rsp, readErr := e.Next.ReadNode(readCtx, &tree.ReadNodeRequest{ |
| 334 | Node: from, |
| 335 | }) |
| 336 | if readErr != nil { |
| 337 | return models.ObjectInfo{}, readErr |
| 338 | } |
| 339 | if len(rsp.Node.Uuid) == 0 { |
| 340 | return models.ObjectInfo{}, errors.WithMessage(errors.NodeNotFound) |
| 341 | } |
| 342 | cloneFrom.Uuid = rsp.Node.Uuid |
| 343 | } |
| 344 | // Force target Uuid to copy encryption material |
| 345 | cloneTo.RenewUuidIfEmpty(cloneTo.Uuid == cloneFrom.Uuid) |
| 346 | |
| 347 | // Just add the metadata and let underlying handler do the job |
| 348 | requestData.Metadata[common.XAmzMetaNodeUuid] = cloneTo.Uuid |
| 349 | requestData.Metadata[common.XAmzMetaClearSize] = fmt.Sprintf("%d", cloneFrom.Size) |
| 350 | l, er := e.Next.CopyObject(ctx, from, to, requestData) |
| 351 | if er == nil { |
| 352 | if err := e.copyNodeEncryptionData(ctx, cloneFrom, cloneTo); err != nil { |
| 353 | return l, err |
| 354 | } |
| 355 | } |
| 356 | return l, er |
| 357 | } else { |
| 358 | // We have to encrypt/decrypt on the fly |
| 359 | destPath := cloneTo.ZapPath() |
| 360 | if cloneFrom.Uuid == "" || cloneFrom.Size == 0 { |
| 361 | rsp, readErr := e.Next.ReadNode(readCtx, &tree.ReadNodeRequest{ |
| 362 | Node: cloneFrom, |