fake.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. /*
  2. Copyright © The ESO Authors
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. https://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package fake
  14. import (
  15. "errors"
  16. "fmt"
  17. "github.com/1Password/connect-sdk-go/onepassword"
  18. )
  19. // OnePasswordMockClient is a fake connect.Client.
  20. type OnePasswordMockClient struct {
  21. MockVaults map[string][]onepassword.Vault
  22. MockItems map[string][]onepassword.Item // ID and Title only
  23. MockItemFields map[string]map[string][]*onepassword.ItemField
  24. MockFileContents map[string][]byte
  25. UpdateItemValidateFunc func(*onepassword.Item, string) (*onepassword.Item, error)
  26. CreateItemValidateFunc func(*onepassword.Item, string) (*onepassword.Item, error)
  27. DeleteItemValidateFunc func(*onepassword.Item, string) error
  28. }
  29. // NewMockClient returns an instantiated mock client.
  30. func NewMockClient() *OnePasswordMockClient {
  31. return &OnePasswordMockClient{
  32. MockVaults: map[string][]onepassword.Vault{},
  33. MockItems: map[string][]onepassword.Item{},
  34. MockItemFields: map[string]map[string][]*onepassword.ItemField{},
  35. MockFileContents: map[string][]byte{},
  36. }
  37. }
  38. // GetVaults unused fake.
  39. func (mockClient *OnePasswordMockClient) GetVaults() ([]onepassword.Vault, error) {
  40. return []onepassword.Vault{}, nil
  41. }
  42. // GetVault unused fake.
  43. func (mockClient *OnePasswordMockClient) GetVault(uuid string) (*onepassword.Vault, error) {
  44. return mockClient.GetVaultByTitle(uuid)
  45. }
  46. // GetVaultByUUID unused fake.
  47. func (mockClient *OnePasswordMockClient) GetVaultByUUID(uuid string) (*onepassword.Vault, error) {
  48. return &mockClient.MockVaults[uuid][0], nil
  49. }
  50. // GetVaultByTitle returns a vault, you must preload, only one.
  51. func (mockClient *OnePasswordMockClient) GetVaultByTitle(uuid string) (*onepassword.Vault, error) {
  52. if len(mockClient.MockVaults[uuid]) != 0 {
  53. return &mockClient.MockVaults[uuid][0], nil
  54. }
  55. return &onepassword.Vault{}, nil
  56. }
  57. // GetVaultsByTitle returns a list of vaults, you must preload.
  58. func (mockClient *OnePasswordMockClient) GetVaultsByTitle(uuid string) ([]onepassword.Vault, error) {
  59. return mockClient.MockVaults[uuid], nil
  60. }
  61. // GetItems returns []onepassword.Item, you must preload.
  62. func (mockClient *OnePasswordMockClient) GetItems(vaultUUID string) ([]onepassword.Item, error) {
  63. return mockClient.MockItems[vaultUUID], nil
  64. }
  65. // GetItem returns a *onepassword.Item, you must preload.
  66. func (mockClient *OnePasswordMockClient) GetItem(itemUUID, vaultUUID string) (*onepassword.Item, error) {
  67. return mockClient.GetItemByUUID(itemUUID, vaultUUID)
  68. }
  69. // GetItemByUUID returns a *onepassword.Item, you must preload.
  70. func (mockClient *OnePasswordMockClient) GetItemByUUID(itemUUID, vaultUUID string) (*onepassword.Item, error) {
  71. for _, item := range mockClient.MockItems[vaultUUID] {
  72. if item.ID == itemUUID {
  73. // load the fields that GetItemsByTitle does not
  74. item.Fields = mockClient.MockItemFields[vaultUUID][itemUUID]
  75. return &item, nil
  76. }
  77. }
  78. return &onepassword.Item{}, errors.New("status 400: Invalid GetItemByUUID")
  79. }
  80. // GetItemByTitle unused fake.
  81. func (mockClient *OnePasswordMockClient) GetItemByTitle(_, _ string) (*onepassword.Item, error) {
  82. return &onepassword.Item{}, nil
  83. }
  84. // GetItemsByTitle returns a list of items, you must preload.
  85. func (mockClient *OnePasswordMockClient) GetItemsByTitle(itemUUID, vaultUUID string) ([]onepassword.Item, error) {
  86. items := []onepassword.Item{}
  87. for _, item := range mockClient.MockItems[vaultUUID] {
  88. if item.Title == itemUUID {
  89. items = append(items, item)
  90. }
  91. }
  92. return items, nil
  93. }
  94. // CreateItem will call a validation function if set.
  95. func (mockClient *OnePasswordMockClient) CreateItem(i *onepassword.Item, s string) (*onepassword.Item, error) {
  96. if mockClient.CreateItemValidateFunc != nil {
  97. item, err := mockClient.CreateItemValidateFunc(i, s)
  98. if err == nil {
  99. mockClient.MockItems[i.Vault.ID] = append(mockClient.MockItems[i.Vault.ID], *item)
  100. if mockClient.MockItemFields[i.Vault.ID] == nil {
  101. mockClient.MockItemFields[i.Vault.ID] = make(map[string][]*onepassword.ItemField)
  102. }
  103. mockClient.MockItemFields[i.Vault.ID][i.ID] = item.Fields
  104. }
  105. return item, err
  106. }
  107. return &onepassword.Item{}, nil
  108. }
  109. // UpdateItem will call a validation function if set.
  110. func (mockClient *OnePasswordMockClient) UpdateItem(i *onepassword.Item, s string) (*onepassword.Item, error) {
  111. if mockClient.UpdateItemValidateFunc != nil {
  112. updatedItem, err := mockClient.UpdateItemValidateFunc(i, s)
  113. if err == nil {
  114. for index, item := range mockClient.MockItems[i.Vault.ID] {
  115. if item.ID == updatedItem.ID {
  116. mockClient.MockItems[i.Vault.ID][index] = *updatedItem
  117. mockClient.MockItemFields[i.Vault.ID][updatedItem.ID] = updatedItem.Fields
  118. break
  119. }
  120. }
  121. }
  122. return updatedItem, err
  123. }
  124. return &onepassword.Item{}, nil
  125. }
  126. // DeleteItem will call a validation function if set.
  127. func (mockClient *OnePasswordMockClient) DeleteItem(i *onepassword.Item, s string) error {
  128. if mockClient.DeleteItemValidateFunc != nil {
  129. return mockClient.DeleteItemValidateFunc(i, s)
  130. }
  131. return nil
  132. }
  133. // DeleteItemByID unused fake.
  134. func (mockClient *OnePasswordMockClient) DeleteItemByID(_, _ string) error {
  135. return nil
  136. }
  137. // DeleteItemByTitle unused fake.
  138. func (mockClient *OnePasswordMockClient) DeleteItemByTitle(_, _ string) error {
  139. return nil
  140. }
  141. // GetFiles unused fake.
  142. func (mockClient *OnePasswordMockClient) GetFiles(_, _ string) ([]onepassword.File, error) {
  143. return []onepassword.File{}, nil
  144. }
  145. // GetFile unused fake.
  146. func (mockClient *OnePasswordMockClient) GetFile(_, _, _ string) (*onepassword.File, error) {
  147. return &onepassword.File{}, nil
  148. }
  149. // GetFileContent returns file data, you must preload.
  150. func (mockClient *OnePasswordMockClient) GetFileContent(file *onepassword.File) ([]byte, error) {
  151. value, ok := mockClient.MockFileContents[file.Name]
  152. if !ok {
  153. return []byte{}, errors.New("status 400: Invalid File Name")
  154. }
  155. return value, nil
  156. }
  157. // DownloadFile unused fake.
  158. func (mockClient *OnePasswordMockClient) DownloadFile(_ *onepassword.File, _ string, _ bool) (string, error) {
  159. return "", nil
  160. }
  161. // LoadStructFromItemByUUID unused fake.
  162. func (mockClient *OnePasswordMockClient) LoadStructFromItemByUUID(_ any, _, _ string) error {
  163. return nil
  164. }
  165. // LoadStructFromItemByTitle unused fake.
  166. func (mockClient *OnePasswordMockClient) LoadStructFromItemByTitle(_ any, _, _ string) error {
  167. return nil
  168. }
  169. // LoadStructFromItem unused fake.
  170. func (mockClient *OnePasswordMockClient) LoadStructFromItem(_ any, _, _ string) error {
  171. return nil
  172. }
  173. // LoadStructunused fake.
  174. func (mockClient *OnePasswordMockClient) LoadStruct(_ any) error {
  175. return nil
  176. }
  177. // // For rigging test cases
  178. // AddPredictableVault adds vaults to the mock client in a predictable way.
  179. func (mockClient *OnePasswordMockClient) AddPredictableVault(name string) *OnePasswordMockClient {
  180. mockClient.MockVaults[name] = append(mockClient.MockVaults[name], onepassword.Vault{
  181. ID: fmt.Sprintf("%s-id", name),
  182. Name: name,
  183. })
  184. return mockClient
  185. }
  186. // AddPredictableVaultUUID adds vaults to the mock client in a predictable way.
  187. func (mockClient *OnePasswordMockClient) AddPredictableVaultUUID(name string) *OnePasswordMockClient {
  188. mockClient.MockVaults[name] = append(mockClient.MockVaults[name], onepassword.Vault{
  189. ID: name,
  190. Name: name,
  191. })
  192. return mockClient
  193. }
  194. // AddPredictableItemWithField adds an item and it's fields to the mock client in a predictable way.
  195. func (mockClient *OnePasswordMockClient) AddPredictableItemWithField(vaultName, title, label, value string) *OnePasswordMockClient {
  196. itemID := fmt.Sprintf("%s-id", title)
  197. vaultID := fmt.Sprintf("%s-id", vaultName)
  198. mockClient.MockItems[vaultID] = append(mockClient.MockItems[vaultID], onepassword.Item{
  199. ID: itemID,
  200. Title: title,
  201. Vault: onepassword.ItemVault{ID: vaultID},
  202. })
  203. if mockClient.MockItemFields[vaultID] == nil {
  204. mockClient.MockItemFields[vaultID] = make(map[string][]*onepassword.ItemField)
  205. }
  206. mockClient.MockItemFields[vaultID][itemID] = append(mockClient.MockItemFields[vaultID][itemID], &onepassword.ItemField{
  207. Label: label,
  208. Value: value,
  209. })
  210. return mockClient
  211. }
  212. // AddPredictableItemWithFieldUUID adds an item and it's fields to the mock client in a predictable way.
  213. func (mockClient *OnePasswordMockClient) AddPredictableItemWithFieldUUID(vaultName, title, label, value string) *OnePasswordMockClient {
  214. mockClient.MockItems[vaultName] = append(mockClient.MockItems[vaultName], onepassword.Item{
  215. ID: title,
  216. Title: title,
  217. Vault: onepassword.ItemVault{ID: vaultName},
  218. })
  219. if mockClient.MockItemFields[vaultName] == nil {
  220. mockClient.MockItemFields[vaultName] = make(map[string][]*onepassword.ItemField)
  221. }
  222. mockClient.MockItemFields[vaultName][title] = append(mockClient.MockItemFields[vaultName][title], &onepassword.ItemField{
  223. Label: label,
  224. Value: value,
  225. })
  226. return mockClient
  227. }
  228. // AppendVault appends a onepassword.Vault to the mock client.
  229. func (mockClient *OnePasswordMockClient) AppendVault(name string, vault onepassword.Vault) *OnePasswordMockClient {
  230. mockClient.MockVaults[name] = append(mockClient.MockVaults[name], vault)
  231. return mockClient
  232. }
  233. // AppendItem appends a onepassword.Item to the mock client.
  234. func (mockClient *OnePasswordMockClient) AppendItem(vaultID string, item onepassword.Item) *OnePasswordMockClient {
  235. mockClient.MockItems[vaultID] = append(mockClient.MockItems[vaultID], item)
  236. return mockClient
  237. }
  238. // AppendItemField appends a onepassword.ItemField to the mock client.
  239. func (mockClient *OnePasswordMockClient) AppendItemField(vaultID, itemID string, itemField onepassword.ItemField) *OnePasswordMockClient {
  240. if mockClient.MockItemFields[vaultID] == nil {
  241. mockClient.MockItemFields[vaultID] = make(map[string][]*onepassword.ItemField)
  242. }
  243. mockClient.MockItemFields[vaultID][itemID] = append(mockClient.MockItemFields[vaultID][itemID], &itemField)
  244. return mockClient
  245. }
  246. // SetFileContents adds file contents to the mock client.
  247. func (mockClient *OnePasswordMockClient) SetFileContents(name string, contents []byte) *OnePasswordMockClient {
  248. // no need to test or mock same file names in different vaults, because we only GetFileContent after findItem, which already tests getting the right item from the right vault
  249. mockClient.MockFileContents[name] = contents
  250. return mockClient
  251. }