fake.go 9.7 KB

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