attachments.go

v1.0.0
Doc Versions Source
1
package bitwarden
2
3
import (
4
	"bytes"
5
	"context"
6
	"fmt"
7
	"io"
8
	"mime/multipart"
9
	"net/http"
10
	"net/url"
11
)
12
13
// AttachmentsService handles file attachment operations.
14
type AttachmentsService struct {
15
	t *transport
16
}
17
18
// Create uploads a file attachment to a vault item.
19
func (s *AttachmentsService) Create(ctx context.Context, itemID, filename string, file io.Reader) (*Item, error) {
20
	var buf bytes.Buffer
21
	writer := multipart.NewWriter(&buf)
22
23
	part, err := writer.CreateFormFile("file", filename)
24
	if err != nil {
25
		return nil, fmt.Errorf("create form file: %w", err)
26
	}
27
28
	if _, err := io.Copy(part, file); err != nil {
29
		return nil, fmt.Errorf("copy file data: %w", err)
30
	}
31
32
	if err := writer.Close(); err != nil {
33
		return nil, fmt.Errorf("close multipart writer: %w", err)
34
	}
35
36
	u := s.t.baseURL + "/attachment?itemid=" + itemID
37
	req, err := http.NewRequestWithContext(ctx, http.MethodPost, u, &buf)
38
	if err != nil {
39
		return nil, fmt.Errorf("create request: %w", err)
40
	}
41
	req.Header.Set("Content-Type", writer.FormDataContentType())
42
43
	resp, err := s.t.httpClient.Do(req)
44
	if err != nil {
45
		return nil, fmt.Errorf("execute request: %w", err)
46
	}
47
	defer resp.Body.Close()
48
49
	respBody, err := io.ReadAll(resp.Body)
50
	if err != nil {
51
		return nil, fmt.Errorf("read response: %w", err)
52
	}
53
54
	if resp.StatusCode >= 400 {
55
		return nil, &APIError{
56
			StatusCode: resp.StatusCode,
57
			Message:    string(respBody),
58
		}
59
	}
60
61
	return decodeObjectResponsePtr[Item](respBody)
62
}
63
64
// Get downloads an attachment by ID from a vault item. Returns the raw file contents.
65
func (s *AttachmentsService) Get(ctx context.Context, attachmentID, itemID string) ([]byte, error) {
66
	q := url.Values{"itemid": {itemID}}
67
	data, err := s.t.get(ctx, "/object/attachment/"+attachmentID, q)
68
	if err != nil {
69
		return nil, err
70
	}
71
	return data, nil
72
}
73
74
// Delete removes an attachment by ID from a vault item.
75
func (s *AttachmentsService) Delete(ctx context.Context, attachmentID, itemID string) error {
76
	q := url.Values{"itemid": {itemID}}
77
	_, err := s.t.do(ctx, http.MethodDelete, "/object/attachment/"+attachmentID, q, nil)
78
	return err
79
}
80

Source Files