mirror of
https://github.com/1Password/onepassword-operator.git
synced 2025-10-24 08:20:45 +00:00
Update packages and add vendor directory
This commit is contained in:
21
vendor/github.com/1Password/connect-sdk-go/LICENSE
generated
vendored
Normal file
21
vendor/github.com/1Password/connect-sdk-go/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021 1Password
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
860
vendor/github.com/1Password/connect-sdk-go/connect/client.go
generated
vendored
Normal file
860
vendor/github.com/1Password/connect-sdk-go/connect/client.go
generated
vendored
Normal file
@@ -0,0 +1,860 @@
|
||||
package connect
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"regexp"
|
||||
|
||||
"github.com/opentracing/opentracing-go"
|
||||
"github.com/opentracing/opentracing-go/ext"
|
||||
jaegerClientConfig "github.com/uber/jaeger-client-go/config"
|
||||
"github.com/uber/jaeger-client-go/zipkin"
|
||||
|
||||
"github.com/1Password/connect-sdk-go/onepassword"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultUserAgent = "connect-sdk-go/%s"
|
||||
)
|
||||
|
||||
var (
|
||||
vaultUUIDError = fmt.Errorf("malformed vault uuid provided")
|
||||
itemUUIDError = fmt.Errorf("malformed item uuid provided")
|
||||
fileUUIDError = fmt.Errorf("malformed file uuid provided")
|
||||
)
|
||||
|
||||
// Client Represents an available 1Password Connect API to connect to
|
||||
type Client interface {
|
||||
GetVaults() ([]onepassword.Vault, error)
|
||||
GetVault(uuid string) (*onepassword.Vault, error)
|
||||
GetVaultByUUID(uuid string) (*onepassword.Vault, error)
|
||||
GetVaultByTitle(title string) (*onepassword.Vault, error)
|
||||
GetVaultsByTitle(uuid string) ([]onepassword.Vault, error)
|
||||
GetItems(vaultQuery string) ([]onepassword.Item, error)
|
||||
GetItem(itemQuery, vaultQuery string) (*onepassword.Item, error)
|
||||
GetItemByUUID(uuid string, vaultQuery string) (*onepassword.Item, error)
|
||||
GetItemByTitle(title string, vaultQuery string) (*onepassword.Item, error)
|
||||
GetItemsByTitle(title string, vaultQuery string) ([]onepassword.Item, error)
|
||||
CreateItem(item *onepassword.Item, vaultQuery string) (*onepassword.Item, error)
|
||||
UpdateItem(item *onepassword.Item, vaultQuery string) (*onepassword.Item, error)
|
||||
DeleteItem(item *onepassword.Item, vaultQuery string) error
|
||||
DeleteItemByID(itemUUID string, vaultQuery string) error
|
||||
DeleteItemByTitle(title string, vaultQuery string) error
|
||||
GetFiles(itemQuery string, vaultQuery string) ([]onepassword.File, error)
|
||||
GetFile(uuid string, itemQuery string, vaultQuery string) (*onepassword.File, error)
|
||||
GetFileContent(file *onepassword.File) ([]byte, error)
|
||||
DownloadFile(file *onepassword.File, targetDirectory string, overwrite bool) (string, error)
|
||||
LoadStructFromItemByUUID(config interface{}, itemUUID string, vaultQuery string) error
|
||||
LoadStructFromItemByTitle(config interface{}, itemTitle string, vaultQuery string) error
|
||||
LoadStructFromItem(config interface{}, itemQuery string, vaultQuery string) error
|
||||
LoadStruct(config interface{}) error
|
||||
}
|
||||
|
||||
type httpClient interface {
|
||||
Do(req *http.Request) (*http.Response, error)
|
||||
}
|
||||
|
||||
const (
|
||||
envHostVariable = "OP_CONNECT_HOST"
|
||||
envTokenVariable = "OP_CONNECT_TOKEN"
|
||||
)
|
||||
|
||||
// NewClientFromEnvironment Returns a Secret Service client assuming that your
|
||||
// jwt is set in the OP_TOKEN environment variable
|
||||
func NewClientFromEnvironment() (Client, error) {
|
||||
host, found := os.LookupEnv(envHostVariable)
|
||||
if !found {
|
||||
return nil, fmt.Errorf("There is no hostname available in the %q variable", envHostVariable)
|
||||
}
|
||||
|
||||
token, found := os.LookupEnv(envTokenVariable)
|
||||
if !found {
|
||||
return nil, fmt.Errorf("There is no token available in the %q variable", envTokenVariable)
|
||||
}
|
||||
|
||||
return NewClient(host, token), nil
|
||||
}
|
||||
|
||||
// NewClient Returns a Secret Service client for a given url and jwt
|
||||
func NewClient(url string, token string) Client {
|
||||
return NewClientWithUserAgent(url, token, fmt.Sprintf(defaultUserAgent, SDKVersion))
|
||||
}
|
||||
|
||||
// NewClientWithUserAgent Returns a Secret Service client for a given url and jwt and identifies with userAgent
|
||||
func NewClientWithUserAgent(url string, token string, userAgent string) Client {
|
||||
if !opentracing.IsGlobalTracerRegistered() {
|
||||
cfg := jaegerClientConfig.Configuration{}
|
||||
zipkinPropagator := zipkin.NewZipkinB3HTTPHeaderPropagator()
|
||||
cfg.InitGlobalTracer(
|
||||
userAgent,
|
||||
jaegerClientConfig.Injector(opentracing.HTTPHeaders, zipkinPropagator),
|
||||
jaegerClientConfig.Extractor(opentracing.HTTPHeaders, zipkinPropagator),
|
||||
jaegerClientConfig.ZipkinSharedRPCSpan(true),
|
||||
)
|
||||
}
|
||||
|
||||
return &restClient{
|
||||
URL: url,
|
||||
Token: token,
|
||||
|
||||
userAgent: userAgent,
|
||||
tracer: opentracing.GlobalTracer(),
|
||||
|
||||
client: http.DefaultClient,
|
||||
}
|
||||
}
|
||||
|
||||
type restClient struct {
|
||||
URL string
|
||||
Token string
|
||||
userAgent string
|
||||
tracer opentracing.Tracer
|
||||
client httpClient
|
||||
}
|
||||
|
||||
// GetVaults Get a list of all available vaults
|
||||
func (rs *restClient) GetVaults() ([]onepassword.Vault, error) {
|
||||
span := rs.tracer.StartSpan("GetVaults")
|
||||
defer span.Finish()
|
||||
|
||||
vaultURL := fmt.Sprintf("/v1/vaults")
|
||||
request, err := rs.buildRequest(http.MethodGet, vaultURL, http.NoBody, span)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
response, err := rs.client.Do(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var vaults []onepassword.Vault
|
||||
if err := parseResponse(response, http.StatusOK, &vaults); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return vaults, nil
|
||||
}
|
||||
|
||||
// GetVault Get a vault based on its name or ID
|
||||
func (rs *restClient) GetVault(vaultQuery string) (*onepassword.Vault, error) {
|
||||
span := rs.tracer.StartSpan("GetVault")
|
||||
defer span.Finish()
|
||||
|
||||
if vaultQuery == "" {
|
||||
return nil, fmt.Errorf("Please provide either the vault name or its ID.")
|
||||
}
|
||||
if !isValidUUID(vaultQuery) {
|
||||
return rs.GetVaultByTitle(vaultQuery)
|
||||
}
|
||||
return rs.GetVaultByUUID(vaultQuery)
|
||||
}
|
||||
|
||||
func (rs *restClient) GetVaultByUUID(uuid string) (*onepassword.Vault, error) {
|
||||
if !isValidUUID(uuid) {
|
||||
return nil, vaultUUIDError
|
||||
}
|
||||
|
||||
span := rs.tracer.StartSpan("GetVaultByUUID")
|
||||
defer span.Finish()
|
||||
|
||||
vaultURL := fmt.Sprintf("/v1/vaults/%s", uuid)
|
||||
request, err := rs.buildRequest(http.MethodGet, vaultURL, http.NoBody, span)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
response, err := rs.client.Do(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var vault onepassword.Vault
|
||||
if err := parseResponse(response, http.StatusOK, &vault); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &vault, nil
|
||||
}
|
||||
|
||||
func (rs *restClient) GetVaultByTitle(vaultName string) (*onepassword.Vault, error) {
|
||||
span := rs.tracer.StartSpan("GetVaultByTitle")
|
||||
defer span.Finish()
|
||||
|
||||
vaults, err := rs.GetVaultsByTitle(vaultName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(vaults) != 1 {
|
||||
return nil, fmt.Errorf("Found %d vaults with title %q", len(vaults), vaultName)
|
||||
}
|
||||
|
||||
return &vaults[0], nil
|
||||
}
|
||||
|
||||
func (rs *restClient) GetVaultsByTitle(title string) ([]onepassword.Vault, error) {
|
||||
span := rs.tracer.StartSpan("GetVaultsByTitle")
|
||||
defer span.Finish()
|
||||
|
||||
filter := url.QueryEscape(fmt.Sprintf("title eq \"%s\"", title))
|
||||
itemURL := fmt.Sprintf("/v1/vaults?filter=%s", filter)
|
||||
request, err := rs.buildRequest(http.MethodGet, itemURL, http.NoBody, span)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
response, err := rs.client.Do(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var vaults []onepassword.Vault
|
||||
if err := parseResponse(response, http.StatusOK, &vaults); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return vaults, nil
|
||||
}
|
||||
|
||||
func (rs *restClient) getVaultUUID(vaultQuery string) (string, error) {
|
||||
if vaultQuery == "" {
|
||||
return "", fmt.Errorf("Please provide either the vault name or its ID.")
|
||||
}
|
||||
if isValidUUID(vaultQuery) {
|
||||
return vaultQuery, nil
|
||||
}
|
||||
vault, err := rs.GetVaultByTitle(vaultQuery)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return vault.ID, nil
|
||||
}
|
||||
|
||||
// GetItem Get a specific Item from the 1Password Connect API by either title or UUID
|
||||
func (rs *restClient) GetItem(itemQuery string, vaultQuery string) (*onepassword.Item, error) {
|
||||
span := rs.tracer.StartSpan("GetItem")
|
||||
defer span.Finish()
|
||||
|
||||
if itemQuery == "" {
|
||||
return nil, fmt.Errorf("Please provide either the item name or its ID.")
|
||||
}
|
||||
if !isValidUUID(itemQuery) {
|
||||
return rs.GetItemByTitle(itemQuery, vaultQuery)
|
||||
}
|
||||
return rs.GetItemByUUID(itemQuery, vaultQuery)
|
||||
}
|
||||
|
||||
// GetItemByUUID Get a specific Item from the 1Password Connect API by its UUID
|
||||
func (rs *restClient) GetItemByUUID(uuid string, vaultQuery string) (*onepassword.Item, error) {
|
||||
if !isValidUUID(uuid) {
|
||||
return nil, itemUUIDError
|
||||
}
|
||||
|
||||
vaultUUID, err := rs.getVaultUUID(vaultQuery)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
span := rs.tracer.StartSpan("GetItemByUUID")
|
||||
defer span.Finish()
|
||||
|
||||
itemURL := fmt.Sprintf("/v1/vaults/%s/items/%s", vaultUUID, uuid)
|
||||
request, err := rs.buildRequest(http.MethodGet, itemURL, http.NoBody, span)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
response, err := rs.client.Do(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var item onepassword.Item
|
||||
if err := parseResponse(response, http.StatusOK, &item); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &item, nil
|
||||
}
|
||||
|
||||
func (rs *restClient) GetItemByTitle(title string, vaultQuery string) (*onepassword.Item, error) {
|
||||
vaultUUID, err := rs.getVaultUUID(vaultQuery)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
span := rs.tracer.StartSpan("GetItemByTitle")
|
||||
defer span.Finish()
|
||||
items, err := rs.GetItemsByTitle(title, vaultUUID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(items) != 1 {
|
||||
return nil, fmt.Errorf("Found %d item(s) in vault %q with title %q", len(items), vaultUUID, title)
|
||||
}
|
||||
|
||||
return &items[0], nil
|
||||
}
|
||||
|
||||
func (rs *restClient) GetItemsByTitle(title string, vaultQuery string) ([]onepassword.Item, error) {
|
||||
vaultUUID, err := rs.getVaultUUID(vaultQuery)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
span := rs.tracer.StartSpan("GetItemsByTitle")
|
||||
defer span.Finish()
|
||||
|
||||
filter := url.QueryEscape(fmt.Sprintf("title eq \"%s\"", title))
|
||||
itemURL := fmt.Sprintf("/v1/vaults/%s/items?filter=%s", vaultUUID, filter)
|
||||
request, err := rs.buildRequest(http.MethodGet, itemURL, http.NoBody, span)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
response, err := rs.client.Do(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var itemSummaries []onepassword.Item
|
||||
if err := parseResponse(response, http.StatusOK, &itemSummaries); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
items := make([]onepassword.Item, len(itemSummaries))
|
||||
for i, itemSummary := range itemSummaries {
|
||||
tempItem, err := rs.GetItem(itemSummary.ID, itemSummary.Vault.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
items[i] = *tempItem
|
||||
}
|
||||
|
||||
return items, nil
|
||||
}
|
||||
|
||||
func (rs *restClient) GetItems(vaultQuery string) ([]onepassword.Item, error) {
|
||||
vaultUUID, err := rs.getVaultUUID(vaultQuery)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
span := rs.tracer.StartSpan("GetItems")
|
||||
defer span.Finish()
|
||||
|
||||
itemURL := fmt.Sprintf("/v1/vaults/%s/items", vaultUUID)
|
||||
request, err := rs.buildRequest(http.MethodGet, itemURL, http.NoBody, span)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
response, err := rs.client.Do(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var items []onepassword.Item
|
||||
if err := parseResponse(response, http.StatusOK, &items); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return items, nil
|
||||
}
|
||||
|
||||
func (rs *restClient) getItemUUID(itemQuery, vaultQuery string) (string, error) {
|
||||
if itemQuery == "" {
|
||||
return "", fmt.Errorf("Please provide either the item name or its ID.")
|
||||
}
|
||||
if isValidUUID(itemQuery) {
|
||||
return itemQuery, nil
|
||||
}
|
||||
item, err := rs.GetItemByTitle(itemQuery, vaultQuery)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return item.ID, nil
|
||||
}
|
||||
|
||||
// CreateItem Create a new item in a specified vault
|
||||
func (rs *restClient) CreateItem(item *onepassword.Item, vaultQuery string) (*onepassword.Item, error) {
|
||||
vaultUUID, err := rs.getVaultUUID(vaultQuery)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
span := rs.tracer.StartSpan("CreateItem")
|
||||
defer span.Finish()
|
||||
|
||||
itemURL := fmt.Sprintf("/v1/vaults/%s/items", vaultUUID)
|
||||
itemBody, err := json.Marshal(item)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
request, err := rs.buildRequest(http.MethodPost, itemURL, bytes.NewBuffer(itemBody), span)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
response, err := rs.client.Do(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var newItem onepassword.Item
|
||||
if err := parseResponse(response, http.StatusOK, &newItem); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &newItem, nil
|
||||
}
|
||||
|
||||
// UpdateItem Update a new item in a specified vault
|
||||
func (rs *restClient) UpdateItem(item *onepassword.Item, vaultUUID string) (*onepassword.Item, error) {
|
||||
span := rs.tracer.StartSpan("UpdateItem")
|
||||
defer span.Finish()
|
||||
|
||||
itemURL := fmt.Sprintf("/v1/vaults/%s/items/%s", item.Vault.ID, item.ID)
|
||||
itemBody, err := json.Marshal(item)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
request, err := rs.buildRequest(http.MethodPut, itemURL, bytes.NewBuffer(itemBody), span)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
response, err := rs.client.Do(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var newItem onepassword.Item
|
||||
if err := parseResponse(response, http.StatusOK, &newItem); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &newItem, nil
|
||||
}
|
||||
|
||||
// DeleteItem Delete a new item in a specified vault
|
||||
func (rs *restClient) DeleteItem(item *onepassword.Item, vaultUUID string) error {
|
||||
span := rs.tracer.StartSpan("DeleteItem")
|
||||
defer span.Finish()
|
||||
|
||||
itemURL := fmt.Sprintf("/v1/vaults/%s/items/%s", item.Vault.ID, item.ID)
|
||||
request, err := rs.buildRequest(http.MethodDelete, itemURL, http.NoBody, span)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
response, err := rs.client.Do(request)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := parseResponse(response, http.StatusNoContent, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteItemByID Delete a new item in a specified vault, specifying the item's uuid
|
||||
func (rs *restClient) DeleteItemByID(itemUUID string, vaultQuery string) error {
|
||||
if !isValidUUID(itemUUID) {
|
||||
return itemUUIDError
|
||||
}
|
||||
vaultUUID, err := rs.getVaultUUID(vaultQuery)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
span := rs.tracer.StartSpan("DeleteItemByID")
|
||||
defer span.Finish()
|
||||
|
||||
itemURL := fmt.Sprintf("/v1/vaults/%s/items/%s", vaultUUID, itemUUID)
|
||||
request, err := rs.buildRequest(http.MethodDelete, itemURL, http.NoBody, span)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
response, err := rs.client.Do(request)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := parseResponse(response, http.StatusNoContent, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteItemByTitle Delete a new item in a specified vault, specifying the item's title
|
||||
func (rs *restClient) DeleteItemByTitle(title string, vaultQuery string) error {
|
||||
span := rs.tracer.StartSpan("DeleteItemByTitle")
|
||||
defer span.Finish()
|
||||
|
||||
item, err := rs.GetItemByTitle(title, vaultQuery)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return rs.DeleteItem(item, item.Vault.ID)
|
||||
}
|
||||
|
||||
func (rs *restClient) GetFiles(itemQuery string, vaultQuery string) ([]onepassword.File, error) {
|
||||
vaultUUID, err := rs.getVaultUUID(vaultQuery)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
itemUUID, err := rs.getItemUUID(itemQuery, vaultQuery)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
span := rs.tracer.StartSpan("GetFiles")
|
||||
defer span.Finish()
|
||||
|
||||
jsonURL := fmt.Sprintf("/v1/vaults/%s/items/%s/files", vaultUUID, itemUUID)
|
||||
request, err := rs.buildRequest(http.MethodGet, jsonURL, http.NoBody, span)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
response, err := rs.client.Do(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := expectMinimumConnectVersion(response, version{1, 3, 0}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var files []onepassword.File
|
||||
if err := parseResponse(response, http.StatusOK, &files); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return files, nil
|
||||
}
|
||||
|
||||
// GetFile Get a specific File in a specified item.
|
||||
// This does not include the file contents. Call GetFileContent() to load the file's content.
|
||||
func (rs *restClient) GetFile(uuid string, itemQuery string, vaultQuery string) (*onepassword.File, error) {
|
||||
if !isValidUUID(uuid) {
|
||||
return nil, fileUUIDError
|
||||
}
|
||||
vaultUUID, err := rs.getVaultUUID(vaultQuery)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
itemUUID, err := rs.getItemUUID(itemQuery, vaultQuery)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
span := rs.tracer.StartSpan("GetFile")
|
||||
defer span.Finish()
|
||||
|
||||
itemURL := fmt.Sprintf("/v1/vaults/%s/items/%s/files/%s", vaultUUID, itemUUID, uuid)
|
||||
request, err := rs.buildRequest(http.MethodGet, itemURL, http.NoBody, span)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
response, err := rs.client.Do(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := expectMinimumConnectVersion(response, version{1, 3, 0}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var file onepassword.File
|
||||
if err := parseResponse(response, http.StatusOK, &file); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &file, nil
|
||||
}
|
||||
|
||||
// GetFileContent retrieves the file's content.
|
||||
// If the file's content have previously been fetched, those contents are returned without making another request.
|
||||
func (rs *restClient) GetFileContent(file *onepassword.File) ([]byte, error) {
|
||||
if content, err := file.Content(); err == nil {
|
||||
return content, nil
|
||||
}
|
||||
response, err := rs.retrieveDocumentContent(file)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
content, err := readResponseBody(response, http.StatusOK)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
file.SetContent(content)
|
||||
return content, nil
|
||||
}
|
||||
|
||||
func (rs *restClient) DownloadFile(file *onepassword.File, targetDirectory string, overwriteIfExists bool) (string, error) {
|
||||
response, err := rs.retrieveDocumentContent(file)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
path := filepath.Join(targetDirectory, filepath.Base(file.Name))
|
||||
|
||||
var osFile *os.File
|
||||
|
||||
if overwriteIfExists {
|
||||
osFile, err = createFile(path)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
} else {
|
||||
_, err = os.Stat(path)
|
||||
if os.IsNotExist(err) {
|
||||
osFile, err = createFile(path)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
} else {
|
||||
return "", fmt.Errorf("a file already exists under the %s path. In order to overwrite it, set `overwriteIfExists` to true", path)
|
||||
}
|
||||
}
|
||||
defer osFile.Close()
|
||||
if _, err = io.Copy(osFile, response.Body); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return path, nil
|
||||
}
|
||||
|
||||
func (rs *restClient) retrieveDocumentContent(file *onepassword.File) (*http.Response, error) {
|
||||
span := rs.tracer.StartSpan("GetFileContent")
|
||||
defer span.Finish()
|
||||
|
||||
request, err := rs.buildRequest(http.MethodGet, file.ContentPath, http.NoBody, span)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
response, err := rs.client.Do(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := expectMinimumConnectVersion(response, version{1, 3, 0}); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return response, nil
|
||||
}
|
||||
|
||||
func createFile(path string) (*os.File, error) {
|
||||
osFile, err := os.Create(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = os.Chmod(path, 0600)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return osFile, nil
|
||||
}
|
||||
|
||||
func (rs *restClient) buildRequest(method string, path string, body io.Reader, span opentracing.Span) (*http.Request, error) {
|
||||
url := fmt.Sprintf("%s%s", rs.URL, path)
|
||||
|
||||
request, err := http.NewRequest(method, url, body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
request.Header.Set("Content-Type", "application/json")
|
||||
request.Header.Set("Authorization", fmt.Sprintf("Bearer %s", rs.Token))
|
||||
request.Header.Set("User-Agent", rs.userAgent)
|
||||
|
||||
ext.SpanKindRPCClient.Set(span)
|
||||
ext.HTTPUrl.Set(span, path)
|
||||
ext.HTTPMethod.Set(span, method)
|
||||
|
||||
rs.tracer.Inject(span.Context(), opentracing.HTTPHeaders, opentracing.HTTPHeadersCarrier(request.Header))
|
||||
|
||||
return request, nil
|
||||
}
|
||||
|
||||
func loadToStruct(item *parsedItem, config reflect.Value) error {
|
||||
t := config.Type()
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
value := config.Field(i)
|
||||
field := t.Field(i)
|
||||
|
||||
if !value.CanSet() {
|
||||
return fmt.Errorf("cannot load config into private fields")
|
||||
}
|
||||
|
||||
item.fields = append(item.fields, &field)
|
||||
item.values = append(item.values, &value)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// LoadStructFromItem Load configuration values based on struct tag from one 1P item.
|
||||
// It accepts as parameters item title/UUID and vault title/UUID.
|
||||
func (rs *restClient) LoadStructFromItem(i interface{}, itemQuery string, vaultQuery string) error {
|
||||
if itemQuery == "" {
|
||||
return fmt.Errorf("Please provide either the item name or its ID.")
|
||||
}
|
||||
if isValidUUID(itemQuery) {
|
||||
return rs.LoadStructFromItemByUUID(i, itemQuery, vaultQuery)
|
||||
}
|
||||
return rs.LoadStructFromItemByTitle(i, itemQuery, vaultQuery)
|
||||
}
|
||||
|
||||
// LoadStructFromItemByUUID Load configuration values based on struct tag from one 1P item.
|
||||
func (rs *restClient) LoadStructFromItemByUUID(i interface{}, itemUUID string, vaultQuery string) error {
|
||||
vaultUUID, err := rs.getVaultUUID(vaultQuery)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !isValidUUID(itemUUID) {
|
||||
return itemUUIDError
|
||||
}
|
||||
config, err := checkStruct(i)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
item := parsedItem{}
|
||||
item.itemUUID = itemUUID
|
||||
item.vaultUUID = vaultUUID
|
||||
|
||||
if err := loadToStruct(&item, config); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := setValuesForTag(rs, &item, false); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// LoadStructFromItemByTitle Load configuration values based on struct tag from one 1P item
|
||||
func (rs *restClient) LoadStructFromItemByTitle(i interface{}, itemTitle string, vaultQuery string) error {
|
||||
vaultUUID, err := rs.getVaultUUID(vaultQuery)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
config, err := checkStruct(i)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
item := parsedItem{}
|
||||
item.itemTitle = itemTitle
|
||||
item.vaultUUID = vaultUUID
|
||||
|
||||
if err := loadToStruct(&item, config); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := setValuesForTag(rs, &item, true); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// LoadStruct Load configuration values based on struct tag
|
||||
func (rs *restClient) LoadStruct(i interface{}) error {
|
||||
config, err := checkStruct(i)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t := config.Type()
|
||||
|
||||
// Multiple fields may be from a single item so we will collect them
|
||||
items := map[string]parsedItem{}
|
||||
|
||||
// Fetch the Vault from the environment
|
||||
vaultUUID, envVarFound := os.LookupEnv(envVaultVar)
|
||||
|
||||
for i := 0; i < t.NumField(); i++ {
|
||||
value := config.Field(i)
|
||||
field := t.Field(i)
|
||||
tag := field.Tag.Get(itemTag)
|
||||
|
||||
if tag == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
if !value.CanSet() {
|
||||
return fmt.Errorf("Cannot load config into private fields")
|
||||
}
|
||||
|
||||
itemVault, err := vaultUUIDForField(&field, vaultUUID, envVarFound)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !isValidUUID(itemVault) {
|
||||
return vaultUUIDError
|
||||
}
|
||||
|
||||
key := fmt.Sprintf("%s/%s", itemVault, tag)
|
||||
parsed := items[key]
|
||||
parsed.vaultUUID = itemVault
|
||||
parsed.itemTitle = tag
|
||||
parsed.fields = append(parsed.fields, &field)
|
||||
parsed.values = append(parsed.values, &value)
|
||||
items[key] = parsed
|
||||
}
|
||||
|
||||
for _, item := range items {
|
||||
if err := setValuesForTag(rs, &item, true); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseResponse(resp *http.Response, expectedStatusCode int, result interface{}) error {
|
||||
body, err := readResponseBody(resp, expectedStatusCode)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if result != nil {
|
||||
if err := json.Unmarshal(body, result); err != nil {
|
||||
return fmt.Errorf("decoding response: %s", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func readResponseBody(resp *http.Response, expectedStatusCode int) ([]byte, error) {
|
||||
defer resp.Body.Close()
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if resp.StatusCode != expectedStatusCode {
|
||||
var errResp *onepassword.Error
|
||||
if err := json.Unmarshal(body, &errResp); err != nil {
|
||||
return nil, fmt.Errorf("decoding error response: %s", err)
|
||||
}
|
||||
return nil, errResp
|
||||
}
|
||||
return body, nil
|
||||
}
|
||||
|
||||
func isValidUUID(u string) bool {
|
||||
r := regexp.MustCompile("^[a-z0-9]{26}$")
|
||||
return r.MatchString(u)
|
||||
}
|
||||
209
vendor/github.com/1Password/connect-sdk-go/connect/config_helper.go
generated
vendored
Normal file
209
vendor/github.com/1Password/connect-sdk-go/connect/config_helper.go
generated
vendored
Normal file
@@ -0,0 +1,209 @@
|
||||
package connect
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/1Password/connect-sdk-go/onepassword"
|
||||
)
|
||||
|
||||
const (
|
||||
vaultTag = "opvault"
|
||||
itemTag = "opitem"
|
||||
sectionTag = "opsection"
|
||||
fieldTag = "opfield"
|
||||
urlTag = "opurl"
|
||||
|
||||
envVaultVar = "OP_VAULT"
|
||||
)
|
||||
|
||||
type parsedItem struct {
|
||||
vaultUUID string
|
||||
itemUUID string
|
||||
itemTitle string
|
||||
fields []*reflect.StructField
|
||||
values []*reflect.Value
|
||||
}
|
||||
|
||||
func checkStruct(i interface{}) (reflect.Value, error) {
|
||||
configP := reflect.ValueOf(i)
|
||||
if configP.Kind() != reflect.Ptr {
|
||||
return reflect.Value{}, fmt.Errorf("you must pass a pointer to Config struct")
|
||||
}
|
||||
|
||||
config := configP.Elem()
|
||||
if config.Kind() != reflect.Struct {
|
||||
return reflect.Value{}, fmt.Errorf("config values can only be loaded into a struct")
|
||||
}
|
||||
return config, nil
|
||||
|
||||
}
|
||||
func vaultUUIDForField(field *reflect.StructField, vaultUUID string, envVaultFound bool) (string, error) {
|
||||
// Check to see if a specific vault has been specified on the field
|
||||
// If the env vault id has not been found and item doesn't have a vault
|
||||
// return an error
|
||||
if vaultUUIDTag := field.Tag.Get(vaultTag); vaultUUIDTag == "" {
|
||||
if !envVaultFound {
|
||||
return "", fmt.Errorf("There is no vault for %q field", field.Name)
|
||||
}
|
||||
} else {
|
||||
return vaultUUIDTag, nil
|
||||
}
|
||||
|
||||
return vaultUUID, nil
|
||||
}
|
||||
|
||||
func setValuesForTag(client Client, parsedItem *parsedItem, byTitle bool) error {
|
||||
var item *onepassword.Item
|
||||
var err error
|
||||
if byTitle {
|
||||
item, err = client.GetItemByTitle(parsedItem.itemTitle, parsedItem.vaultUUID)
|
||||
} else {
|
||||
item, err = client.GetItem(parsedItem.itemUUID, parsedItem.vaultUUID)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for i, field := range parsedItem.fields {
|
||||
value := parsedItem.values[i]
|
||||
|
||||
if field.Type == reflect.TypeOf(onepassword.ItemURL{}) {
|
||||
url := &onepassword.ItemURL{
|
||||
Primary: urlPrimaryForName(field.Tag.Get(urlTag), item.URLs),
|
||||
Label: urlLabelForName(field.Tag.Get(urlTag), item.URLs),
|
||||
URL: urlURLForName(field.Tag.Get(urlTag), item.URLs),
|
||||
}
|
||||
value.Set(reflect.ValueOf(*url))
|
||||
continue
|
||||
}
|
||||
|
||||
path := fmt.Sprintf("%s.%s", field.Tag.Get(sectionTag), field.Tag.Get(fieldTag))
|
||||
if path == "." {
|
||||
if field.Type == reflect.TypeOf(onepassword.Item{}) {
|
||||
value.Set(reflect.ValueOf(*item))
|
||||
continue
|
||||
}
|
||||
return fmt.Errorf("There is no %q specified for %q", fieldTag, field.Name)
|
||||
}
|
||||
|
||||
if strings.HasSuffix(path, ".") {
|
||||
if field.Type == reflect.TypeOf(onepassword.ItemSection{}) {
|
||||
section := &onepassword.ItemSection{
|
||||
ID: sectionIDForName(field.Tag.Get(sectionTag), item.Sections),
|
||||
Label: sectionLabelForName(field.Tag.Get(sectionTag), item.Sections),
|
||||
}
|
||||
value.Set(reflect.ValueOf(*section))
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
sectionID := sectionIDForName(field.Tag.Get(sectionTag), item.Sections)
|
||||
|
||||
for _, f := range item.Fields {
|
||||
fieldSectionID := ""
|
||||
if f.Section != nil {
|
||||
fieldSectionID = f.Section.ID
|
||||
}
|
||||
|
||||
if fieldSectionID == sectionID && f.Label == field.Tag.Get(fieldTag) {
|
||||
if err := setValue(value, f.Value); err != nil {
|
||||
return err
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func setValue(value *reflect.Value, toSet string) error {
|
||||
switch value.Kind() {
|
||||
case reflect.String:
|
||||
value.SetString(toSet)
|
||||
case reflect.Int:
|
||||
v, err := strconv.Atoi(toSet)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
value.SetInt(int64(v))
|
||||
default:
|
||||
return fmt.Errorf("Unsupported type %q. Only string, int64, and onepassword.Item are supported", value.Kind())
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func sectionIDForName(name string, sections []*onepassword.ItemSection) string {
|
||||
if sections == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
for _, s := range sections {
|
||||
if name == strings.ToLower(s.Label) {
|
||||
return s.ID
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func sectionLabelForName(name string, sections []*onepassword.ItemSection) string {
|
||||
if sections == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
for _, s := range sections {
|
||||
if name == strings.ToLower(s.Label) {
|
||||
return s.Label
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func urlPrimaryForName(name string, itemURLs []onepassword.ItemURL) bool {
|
||||
if itemURLs == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, url := range itemURLs {
|
||||
if url.Label == strings.ToLower(name) {
|
||||
return url.Primary
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func urlLabelForName(name string, itemURLs []onepassword.ItemURL) string {
|
||||
if itemURLs == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
for _, url := range itemURLs {
|
||||
if url.Label == strings.ToLower(name) {
|
||||
return url.Label
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func urlURLForName(name string, itemURLs []onepassword.ItemURL) string {
|
||||
if itemURLs == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
for _, url := range itemURLs {
|
||||
if url.Label == strings.ToLower(name) {
|
||||
return url.URL
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
|
||||
}
|
||||
104
vendor/github.com/1Password/connect-sdk-go/connect/version.go
generated
vendored
Normal file
104
vendor/github.com/1Password/connect-sdk-go/connect/version.go
generated
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
package connect
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// SDKVersion is the latest Semantic Version of the library
|
||||
// Do not rename this variable without changing the regex in the Makefile
|
||||
const SDKVersion = "1.5.0"
|
||||
|
||||
const VersionHeaderKey = "1Password-Connect-Version"
|
||||
|
||||
// expectMinimumConnectVersion returns an error if the provided minimum version for Connect is lower than the version
|
||||
// reported in the response from Connect.
|
||||
func expectMinimumConnectVersion(resp *http.Response, minimumVersion version) error {
|
||||
serverVersion, err := getServerVersion(resp)
|
||||
if err != nil {
|
||||
// Return gracefully if server version cannot be determined reliably
|
||||
return nil
|
||||
}
|
||||
if !serverVersion.IsGreaterOrEqualThan(minimumVersion) {
|
||||
return fmt.Errorf("need at least version %s of Connect for this function, detected version %s. Please update your Connect server", minimumVersion, serverVersion)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func getServerVersion(resp *http.Response) (serverVersion, error) {
|
||||
versionHeader := resp.Header.Get(VersionHeaderKey)
|
||||
if versionHeader == "" {
|
||||
// The last version without the version header was v1.2.0
|
||||
return serverVersion{
|
||||
version: version{1, 2, 0},
|
||||
orEarlier: true,
|
||||
}, nil
|
||||
}
|
||||
return parseServerVersion(versionHeader)
|
||||
}
|
||||
|
||||
type version struct {
|
||||
major int
|
||||
minor int
|
||||
patch int
|
||||
}
|
||||
|
||||
// serverVersion describes the version reported by the server.
|
||||
type serverVersion struct {
|
||||
version
|
||||
// orEarlier is true if the version is derived from the lack of a version header from the server.
|
||||
orEarlier bool
|
||||
}
|
||||
|
||||
func (v version) String() string {
|
||||
return fmt.Sprintf("%d.%d.%d", v.major, v.minor, v.patch)
|
||||
}
|
||||
|
||||
func (v serverVersion) String() string {
|
||||
if v.orEarlier {
|
||||
return v.version.String() + " (or earlier)"
|
||||
}
|
||||
return v.version.String()
|
||||
}
|
||||
|
||||
// IsGreaterOrEqualThan returns true if the lefthand-side version is equal to or or a higher version than the provided
|
||||
// minimum according to the semantic versioning rules.
|
||||
func (v version) IsGreaterOrEqualThan(min version) bool {
|
||||
if v.major != min.major {
|
||||
// Different major version
|
||||
return v.major > min.major
|
||||
}
|
||||
|
||||
if v.minor != min.minor {
|
||||
// Same major, but different minor version
|
||||
return v.minor > min.minor
|
||||
}
|
||||
|
||||
// Same major and minor version
|
||||
return v.patch >= min.patch
|
||||
}
|
||||
|
||||
func parseServerVersion(v string) (serverVersion, error) {
|
||||
spl := strings.Split(v, ".")
|
||||
if len(spl) != 3 {
|
||||
return serverVersion{}, errors.New("wrong length")
|
||||
}
|
||||
var res [3]int
|
||||
for i := range res {
|
||||
tmp, err := strconv.Atoi(spl[i])
|
||||
if err != nil {
|
||||
return serverVersion{}, err
|
||||
}
|
||||
res[i] = tmp
|
||||
}
|
||||
return serverVersion{
|
||||
version: version{
|
||||
major: res[0],
|
||||
minor: res[1],
|
||||
patch: res[2],
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
21
vendor/github.com/1Password/connect-sdk-go/onepassword/errors.go
generated
vendored
Normal file
21
vendor/github.com/1Password/connect-sdk-go/onepassword/errors.go
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
package onepassword
|
||||
|
||||
import "fmt"
|
||||
|
||||
// Error is an error returned by the Connect API.
|
||||
type Error struct {
|
||||
StatusCode int `json:"status"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
func (e *Error) Error() string {
|
||||
return fmt.Sprintf("status %d: %s", e.StatusCode, e.Message)
|
||||
}
|
||||
|
||||
func (e *Error) Is(target error) bool {
|
||||
t, ok := target.(*Error)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return t.Message == e.Message && t.StatusCode == e.StatusCode
|
||||
}
|
||||
49
vendor/github.com/1Password/connect-sdk-go/onepassword/files.go
generated
vendored
Normal file
49
vendor/github.com/1Password/connect-sdk-go/onepassword/files.go
generated
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
package onepassword
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
)
|
||||
|
||||
type File struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Section *ItemSection `json:"section,omitempty"`
|
||||
Size int `json:"size"`
|
||||
ContentPath string `json:"content_path"`
|
||||
content []byte
|
||||
}
|
||||
|
||||
func (f *File) UnmarshalJSON(data []byte) error {
|
||||
var jsonFile struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Section *ItemSection `json:"section,omitempty"`
|
||||
Size int `json:"size"`
|
||||
ContentPath string `json:"content_path"`
|
||||
Content []byte `json:"content,omitempty"`
|
||||
}
|
||||
if err := json.Unmarshal(data, &jsonFile); err != nil {
|
||||
return err
|
||||
}
|
||||
f.ID = jsonFile.ID
|
||||
f.Name = jsonFile.Name
|
||||
f.Section = jsonFile.Section
|
||||
f.Size = jsonFile.Size
|
||||
f.ContentPath = jsonFile.ContentPath
|
||||
f.content = jsonFile.Content
|
||||
return nil
|
||||
}
|
||||
|
||||
// Content returns the content of the file if they have been loaded and returns an error if they have not been loaded.
|
||||
// Use `client.GetFileContent(file *File)` instead to make sure the content is fetched automatically if not present.
|
||||
func (f *File) Content() ([]byte, error) {
|
||||
if f.content == nil {
|
||||
return nil, errors.New("file content not loaded")
|
||||
}
|
||||
return f.content, nil
|
||||
}
|
||||
|
||||
func (f *File) SetContent(content []byte) {
|
||||
f.content = content
|
||||
}
|
||||
167
vendor/github.com/1Password/connect-sdk-go/onepassword/items.go
generated
vendored
Normal file
167
vendor/github.com/1Password/connect-sdk-go/onepassword/items.go
generated
vendored
Normal file
@@ -0,0 +1,167 @@
|
||||
package onepassword
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// ItemCategory Represents the template of the Item
|
||||
type ItemCategory string
|
||||
|
||||
const (
|
||||
Login ItemCategory = "LOGIN"
|
||||
Password ItemCategory = "PASSWORD"
|
||||
ApiCredential ItemCategory = "API_CREDENTIAL"
|
||||
Server ItemCategory = "SERVER"
|
||||
Database ItemCategory = "DATABASE"
|
||||
CreditCard ItemCategory = "CREDIT_CARD"
|
||||
Membership ItemCategory = "MEMBERSHIP"
|
||||
Passport ItemCategory = "PASSPORT"
|
||||
SoftwareLicense ItemCategory = "SOFTWARE_LICENSE"
|
||||
OutdoorLicense ItemCategory = "OUTDOOR_LICENSE"
|
||||
SecureNote ItemCategory = "SECURE_NOTE"
|
||||
WirelessRouter ItemCategory = "WIRELESS_ROUTER"
|
||||
BankAccount ItemCategory = "BANK_ACCOUNT"
|
||||
DriverLicense ItemCategory = "DRIVER_LICENSE"
|
||||
Identity ItemCategory = "IDENTITY"
|
||||
RewardProgram ItemCategory = "REWARD_PROGRAM"
|
||||
Document ItemCategory = "DOCUMENT"
|
||||
EmailAccount ItemCategory = "EMAIL_ACCOUNT"
|
||||
SocialSecurityNumber ItemCategory = "SOCIAL_SECURITY_NUMBER"
|
||||
MedicalRecord ItemCategory = "MEDICAL_RECORD"
|
||||
SSHKey ItemCategory = "SSH_KEY"
|
||||
Custom ItemCategory = "CUSTOM"
|
||||
)
|
||||
|
||||
// UnmarshalJSON Unmarshall Item Category enum strings to Go string enums
|
||||
func (ic *ItemCategory) UnmarshalJSON(b []byte) error {
|
||||
var s string
|
||||
json.Unmarshal(b, &s)
|
||||
category := ItemCategory(s)
|
||||
switch category {
|
||||
case Login, Password, Server, Database, CreditCard, Membership, Passport, SoftwareLicense,
|
||||
OutdoorLicense, SecureNote, WirelessRouter, BankAccount, DriverLicense, Identity, RewardProgram,
|
||||
Document, EmailAccount, SocialSecurityNumber, ApiCredential, MedicalRecord, SSHKey:
|
||||
*ic = category
|
||||
default:
|
||||
*ic = Custom
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Item represents an item returned to the consumer
|
||||
type Item struct {
|
||||
ID string `json:"id"`
|
||||
Title string `json:"title"`
|
||||
|
||||
URLs []ItemURL `json:"urls,omitempty"`
|
||||
Favorite bool `json:"favorite,omitempty"`
|
||||
Tags []string `json:"tags,omitempty"`
|
||||
Version int `json:"version,omitempty"`
|
||||
|
||||
Vault ItemVault `json:"vault"`
|
||||
Category ItemCategory `json:"category,omitempty"` // TODO: switch this to `category`
|
||||
|
||||
Sections []*ItemSection `json:"sections,omitempty"`
|
||||
Fields []*ItemField `json:"fields,omitempty"`
|
||||
Files []*File `json:"files,omitempty"`
|
||||
|
||||
LastEditedBy string `json:"lastEditedBy,omitempty"`
|
||||
CreatedAt time.Time `json:"createdAt,omitempty"`
|
||||
UpdatedAt time.Time `json:"updatedAt,omitempty"`
|
||||
|
||||
// Deprecated: Connect does not return trashed items.
|
||||
Trashed bool `json:"trashed,omitempty"`
|
||||
}
|
||||
|
||||
// ItemVault represents the Vault the Item is found in
|
||||
type ItemVault struct {
|
||||
ID string `json:"id"`
|
||||
}
|
||||
|
||||
// ItemURL is a simplified item URL
|
||||
type ItemURL struct {
|
||||
Primary bool `json:"primary,omitempty"`
|
||||
Label string `json:"label,omitempty"`
|
||||
URL string `json:"href"`
|
||||
}
|
||||
|
||||
// ItemSection Representation of a Section on an item
|
||||
type ItemSection struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
Label string `json:"label,omitempty"`
|
||||
}
|
||||
|
||||
// GeneratorRecipe Representation of a "recipe" used to generate a field
|
||||
type GeneratorRecipe struct {
|
||||
Length int `json:"length,omitempty"`
|
||||
CharacterSets []string `json:"characterSets,omitempty"`
|
||||
ExcludeCharacters string `json:"excludeCharacters,omitempty"`
|
||||
}
|
||||
|
||||
// ItemField Representation of a single field on an Item
|
||||
type ItemField struct {
|
||||
ID string `json:"id"`
|
||||
Section *ItemSection `json:"section,omitempty"`
|
||||
Type string `json:"type"`
|
||||
Purpose string `json:"purpose,omitempty"`
|
||||
Label string `json:"label,omitempty"`
|
||||
Value string `json:"value,omitempty"`
|
||||
Generate bool `json:"generate,omitempty"`
|
||||
Recipe *GeneratorRecipe `json:"recipe,omitempty"`
|
||||
Entropy float64 `json:"entropy,omitempty"`
|
||||
TOTP string `json:"totp,omitempty"`
|
||||
}
|
||||
|
||||
// GetValue Retrieve the value of a field on the item by its label. To specify a
|
||||
// field from a specific section pass in <section label>.<field label>. If
|
||||
// no field matching the selector is found return "".
|
||||
func (i *Item) GetValue(field string) string {
|
||||
if i == nil || len(i.Fields) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
sectionFilter := false
|
||||
sectionLabel := ""
|
||||
fieldLabel := field
|
||||
if strings.Contains(field, ".") {
|
||||
parts := strings.Split(field, ".")
|
||||
|
||||
// Test to make sure the . isn't the last character
|
||||
if len(parts) == 2 {
|
||||
sectionFilter = true
|
||||
sectionLabel = parts[0]
|
||||
fieldLabel = parts[1]
|
||||
}
|
||||
}
|
||||
|
||||
for _, f := range i.Fields {
|
||||
if sectionFilter {
|
||||
if f.Section != nil {
|
||||
if sectionLabel != i.SectionLabelForID(f.Section.ID) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if fieldLabel == f.Label {
|
||||
return f.Value
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func (i *Item) SectionLabelForID(id string) string {
|
||||
if i != nil || len(i.Sections) > 0 {
|
||||
for _, s := range i.Sections {
|
||||
if s.ID == id {
|
||||
return s.Label
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
46
vendor/github.com/1Password/connect-sdk-go/onepassword/vaults.go
generated
vendored
Normal file
46
vendor/github.com/1Password/connect-sdk-go/onepassword/vaults.go
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
package onepassword
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Vault represents a 1password Vault
|
||||
type Vault struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Description string `json:"description,omitempty"`
|
||||
|
||||
AttrVersion int `json:"attributeVersion,omitempty"`
|
||||
ContentVersoin int `json:"contentVersion,omitempty"`
|
||||
Items int `json:"items,omitempty"`
|
||||
Type VaultType `json:"type,omitempty"`
|
||||
|
||||
CreatedAt time.Time `json:"createdAt,omitempty"`
|
||||
UpdatedAt time.Time `json:"updatedAt,omitempty"`
|
||||
}
|
||||
|
||||
// VaultType Representation of what the Vault Type is
|
||||
type VaultType string
|
||||
|
||||
const (
|
||||
PersonalVault VaultType = "PERSONAL"
|
||||
EveryoneVault VaultType = "EVERYONE"
|
||||
TransferVault VaultType = "TRANSFER"
|
||||
UserCreatedVault VaultType = "USER_CREATED"
|
||||
UnknownVault VaultType = "UNKNOWN"
|
||||
)
|
||||
|
||||
// UnmarshalJSON Unmarshall Vault Type enum strings to Go string enums
|
||||
func (vt *VaultType) UnmarshalJSON(b []byte) error {
|
||||
var s string
|
||||
json.Unmarshal(b, &s)
|
||||
vaultType := VaultType(s)
|
||||
switch vaultType {
|
||||
case PersonalVault, EveryoneVault, TransferVault, UserCreatedVault:
|
||||
*vt = vaultType
|
||||
default:
|
||||
*vt = UnknownVault
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user