direct_folders.go

v1.0.0
Doc Versions Source
1
package bitwarden
2
3
import (
4
	"context"
5
	"encoding/json"
6
	"fmt"
7
	"strings"
8
)
9
10
// DirectFoldersService handles folder operations via the direct server API.
11
type DirectFoldersService struct {
12
	dc *DirectClient
13
}
14
15
func (s *DirectFoldersService) List(ctx context.Context, search string) ([]Folder, error) {
16
	kc := s.dc.getKeyChain()
17
	if kc == nil {
18
		return nil, &VaultLockedError{}
19
	}
20
21
	// Try cache first
22
	if cached, ok := s.dc.cache.getFolders(); ok {
23
		return filterFoldersFromCache(cached, search, kc), nil
24
	}
25
26
	data, err := s.dc.transport.Get(ctx, "/api/folders", nil)
27
	if err != nil {
28
		return nil, err
29
	}
30
31
	var resp struct {
32
		Data []json.RawMessage `json:"data"`
33
	}
34
	if err := json.Unmarshal(data, &resp); err != nil {
35
		return nil, fmt.Errorf("parse folders list: %w", err)
36
	}
37
38
	var folders []Folder
39
	for _, raw := range resp.Data {
40
		f, err := decryptFolder(raw, kc)
41
		if err != nil {
42
			continue
43
		}
44
		if search == "" || strings.Contains(strings.ToLower(f.Name), strings.ToLower(search)) {
45
			folders = append(folders, *f)
46
		}
47
	}
48
	return folders, nil
49
}
50
51
func (s *DirectFoldersService) Get(ctx context.Context, id string) (*Folder, error) {
52
	kc := s.dc.getKeyChain()
53
	if kc == nil {
54
		return nil, &VaultLockedError{}
55
	}
56
57
	// Try cache first
58
	if cached, ok := s.dc.cache.getFolder(id); ok {
59
		return cached, nil
60
	}
61
62
	data, err := s.dc.transport.Get(ctx, "/api/folders/"+id, nil)
63
	if err != nil {
64
		return nil, err
65
	}
66
67
	return decryptFolder(data, kc)
68
}
69
70
func (s *DirectFoldersService) Create(ctx context.Context, folder Folder) (*Folder, error) {
71
	kc := s.dc.getKeyChain()
72
	if kc == nil {
73
		return nil, &VaultLockedError{}
74
	}
75
76
	enc, err := encryptFolder(folder, kc)
77
	if err != nil {
78
		return nil, err
79
	}
80
81
	data, err := s.dc.transport.Post(ctx, "/api/folders", enc)
82
	if err != nil {
83
		return nil, err
84
	}
85
86
	created, err := decryptFolder(data, kc)
87
	if err != nil {
88
		return nil, err
89
	}
90
	s.dc.cache.upsertFolder(*created)
91
	return created, nil
92
}
93
94
func (s *DirectFoldersService) Update(ctx context.Context, id string, folder Folder) (*Folder, error) {
95
	kc := s.dc.getKeyChain()
96
	if kc == nil {
97
		return nil, &VaultLockedError{}
98
	}
99
100
	enc, err := encryptFolder(folder, kc)
101
	if err != nil {
102
		return nil, err
103
	}
104
105
	data, err := s.dc.transport.Put(ctx, "/api/folders/"+id, enc)
106
	if err != nil {
107
		return nil, err
108
	}
109
110
	updated, err := decryptFolder(data, kc)
111
	if err != nil {
112
		return nil, err
113
	}
114
	s.dc.cache.upsertFolder(*updated)
115
	return updated, nil
116
}
117
118
func (s *DirectFoldersService) Delete(ctx context.Context, id string) error {
119
	_, err := s.dc.transport.Delete(ctx, "/api/folders/"+id)
120
	if err == nil {
121
		s.dc.cache.removeFolder(id)
122
	}
123
	return err
124
}
125

Source Files