From f60567f11305013b3927b0b23b9b8b0ada5b1dc6 Mon Sep 17 00:00:00 2001 From: iljaSL Date: Tue, 12 Nov 2024 14:41:38 +0200 Subject: [PATCH 1/5] refactor(v2): reafctor conn manager and db proxy --- api/connectionmanager/client.go | 460 ++++++++++++++++---------------- api/connectionmanager/model.go | 306 +++++++++++---------- api/dbproxy/client.go | 25 +- api/dbproxy/model.go | 6 +- 4 files changed, 392 insertions(+), 405 deletions(-) diff --git a/api/connectionmanager/client.go b/api/connectionmanager/client.go index a8e329d..2a6ec57 100644 --- a/api/connectionmanager/client.go +++ b/api/connectionmanager/client.go @@ -7,10 +7,10 @@ package connectionmanager import ( - "fmt" "net/url" - "github.com/SSHcom/privx-sdk-go/common" + "github.com/SSHcom/privx-sdk-go/api/filters" + "github.com/SSHcom/privx-sdk-go/api/response" "github.com/SSHcom/privx-sdk-go/restapi" ) @@ -19,403 +19,393 @@ type ConnectionManager struct { api restapi.Connector } -type connectionsResult struct { - Count int `json:"count"` - Items []Connection `json:"items"` -} - -type connectionsTagResult struct { - Count int `json:"count"` - Items []string `json:"items"` -} - -// New creates a new connection manager client instance, using the -// argument SDK API client. +// New connection manager client constructor. func New(api restapi.Connector) *ConnectionManager { return &ConnectionManager{api: api} } -// Connections get all connections -func (store *ConnectionManager) Connections(offset, limit int, sortkey, sortdir string, fuzzycount bool) ([]Connection, error) { - result := connectionsResult{} - filters := Params{ - Offset: offset, - Limit: limit, - Sortkey: sortkey, - Sortdir: sortdir, - FuzzyCount: fuzzycount, - } +// MARK: Status +// Status get connection manager microservice status. +func (c *ConnectionManager) Status() (*response.ServiceStatus, error) { + status := &response.ServiceStatus{} - _, err := store.api. - URL("/connection-manager/api/v1/connections"). - Query(&filters). - Get(&result) + _, err := c.api. + URL("/connection-manager/api/v1/status"). + Get(status) - return result.Items, err + return status, err } -// ConnectionTags get connection tags -func (store *ConnectionManager) ConnectionTags(offset, limit int, sortdir string, query string) (connectionsTagResult, error) { - result := connectionsTagResult{} - filters := Params{ - Offset: offset, - Limit: limit, - Sortdir: sortdir, - Query: query, +// MARK: Connections +// GetConnections get connections. +func (c *ConnectionManager) GetConnections(opts ...filters.Option) (*response.ResultSet[Connection], error) { + connections := &response.ResultSet[Connection]{} + params := url.Values{} + + for _, opt := range opts { + opt(¶ms) } - _, err := store.api. - URL("/connection-manager/api/v1/connections/tags"). - Query(&filters). - Get(&result) + _, err := c.api. + URL("/connection-manager/api/v1/connections"). + Query(params). + Get(&connections) - return result, err + return connections, err } -// UpdateConnectionTags update connection tags -func (store *ConnectionManager) UpdateConnectionTags(connectionTags []string, connectionID string) error { - _, err := store.api. - URL("/connection-manager/api/v1/connections/%s/tags", connectionID). - Put(&connectionTags) +// SearchConnections search for connections. +func (c *ConnectionManager) SearchConnections(search *ConnectionSearch, opts ...filters.Option) (*response.ResultSet[Connection], error) { + connections := &response.ResultSet[Connection]{} + params := url.Values{} - return err -} - -// SearchConnections search for connections -func (store *ConnectionManager) SearchConnections(offset, limit int, sortdir, sortkey string, fuzzycount bool, searchObject ConnectionSearch) ([]Connection, error) { - result := connectionsResult{} - filters := Params{ - Offset: offset, - Limit: limit, - Sortdir: sortdir, - Sortkey: sortkey, - FuzzyCount: fuzzycount, + for _, opt := range opts { + opt(¶ms) } - _, err := store.api. + _, err := c.api. URL("/connection-manager/api/v1/connections/search"). - Query(&filters). - Post(&searchObject, &result) + Query(params). + Post(&search, &connections) - return result.Items, err + return connections, err } -// Connection get a single connection -func (store *ConnectionManager) Connection(connID string) (*Connection, error) { - conn := &Connection{} +// GetConnection get connection by id. +func (c *ConnectionManager) GetConnection(connID string) (*Connection, error) { + connection := &Connection{} - _, err := store.api. - URL("/connection-manager/api/v1/connections/%s", url.PathEscape(connID)). - Get(conn) + _, err := c.api. + URL("/connection-manager/api/v1/connections/%s", connID). + Get(&connection) - return conn, err + return connection, err } -// CreateSessionIDFileDownload create session ID for trail stored file download -func (store *ConnectionManager) CreateSessionIDFileDownload(connID, chanID, fileID string) (string, error) { - var object struct { - SessionID string `json:"session_id"` - } +// CreateSessionForFileDownload create session id for trail stored file download. +func (c *ConnectionManager) CreateSessionForFileDownload(connID, chanID, fileID string) (DownloadSessionID, error) { + sessionID := DownloadSessionID{} - _, err := store.api. - URL("/connection-manager/api/v1/connections/%s/channel/%s/file/%s", - url.PathEscape(connID), url.PathEscape(chanID), url.PathEscape(fileID)). - Post(nil, &object) + _, err := c.api. + URL("/connection-manager/api/v1/connections/%s/channel/%s/file/%s", connID, chanID, fileID). + Post(nil, &sessionID) - return object.SessionID, err + return sessionID, err } -// DownloadStoredFile download trail stored file transferred within audited connection channel -func (store *ConnectionManager) DownloadStoredFile(connID, chanID, fileID, sessionID, filename string) error { - err := store.api. +// DownloadTrailStoredFile download trail stored file transferred within audited connection channel, +func (c *ConnectionManager) DownloadTrailStoredFile(connID, chanID, fileID, sessionID, filename string) error { + err := c.api. URL("/connection-manager/api/v1/connections/%s/channel/%s/file/%s/%s", - url.PathEscape(connID), url.PathEscape(chanID), url.PathEscape(fileID), url.PathEscape(sessionID)). + connID, chanID, fileID, sessionID). Download(filename) return err } -// CreateSessionIDTrailLog create session ID for trail log download -func (store *ConnectionManager) CreateSessionIDTrailLog(connID, chanID string) (string, error) { - var object struct { - SessionID string `json:"session_id"` - } +// CreateSessionForTrailLogDownload create session id for trail log download. +func (c *ConnectionManager) CreateSessionForTrailLogDownload(connID, chanID string) (DownloadSessionID, error) { + sessionID := DownloadSessionID{} - _, err := store.api. - URL("/connection-manager/api/v1/connections/%s/channel/%s/log", - url.PathEscape(connID), url.PathEscape(chanID)). - Post(nil, &object) + _, err := c.api. + URL("/connection-manager/api/v1/connections/%s/channel/%s/log", connID, chanID). + Post(nil, &sessionID) - return object.SessionID, err + return sessionID, err } -// DownloadTrailLog download trail log of audited connection channel -func (store *ConnectionManager) DownloadTrailLog(connID, chanID, sessionID, format, filter, filename string) error { - filters := Params{ - Format: format, - Filter: filter, +// DownloadTrailLog download trail log of audited connection channel. +func (c *ConnectionManager) DownloadTrailLog(connID, chanID, sessionID, filename string, opts ...filters.Option) error { + params := url.Values{} + + for _, opt := range opts { + opt(¶ms) } - err := store.api. - URL("/connection-manager/api/v1/connections/%s/channel/%s/log/%s", - url.PathEscape(connID), url.PathEscape(chanID), url.PathEscape(sessionID)). - Query(&filters). + err := c.api. + URL("/connection-manager/api/v1/connections/%s/channel/%s/log/%s", connID, chanID, sessionID). + Query(params). Download(filename) return err } -// AccessRoles get saved access roles for a connection -func (store *ConnectionManager) AccessRoles(connID string) ([]AccessRoles, error) { - var result []AccessRoles +// GetAccessRoles get access roles for connection by id. +// Note, the v1 endpoint doesn't return the count as part of the response body, +// this will change with v2. Until then, we will handle it internally within the SDK. +func (c *ConnectionManager) GetAccessRoles(connID string) (*response.ResultSet[ConnectionPermission], error) { + p := []ConnectionPermission{} - _, err := store.api. - URL("/connection-manager/api/v1/connections/%s/access_roles", url.PathEscape(connID)). - Get(&result) + _, err := c.api. + URL("/connection-manager/api/v1/connections/%s/access_roles", connID). + Get(&p) + + // v1 endpoint does not return count, + // return count internally in sdk until v2 is introduced + perms := &response.ResultSet[ConnectionPermission]{ + Count: len(p), + Items: p, + } - return result, err + return perms, err } -// GrantAccessRoleToConnection grant a role permission for a connection -func (store *ConnectionManager) GrantAccessRoleToConnection(connID, roleID string) error { - _, err := store.api. - URL("/connection-manager/api/v1/connections/%s/access_roles/%s", - url.PathEscape(connID), url.PathEscape(roleID)). +// GrantAccessRole grant a role permission for a connection. +func (c *ConnectionManager) GrantAccessRole(connID, roleID string) error { + _, err := c.api. + URL("/connection-manager/api/v1/connections/%s/access_roles/%s", connID, roleID). Post(nil) return err } -// RevokeAccessRoleFromConnection revoke a permission for a role from a connection -func (store *ConnectionManager) RevokeAccessRoleFromConnection(connID, roleID string) error { - _, err := store.api. - URL("/connection-manager/api/v1/connections/%s/access_roles/%s", - url.PathEscape(connID), url.PathEscape(roleID)). +// RevokeAccessRole revoke a permission for a role from a connection. +func (c *ConnectionManager) RevokeAccessRole(connID, roleID string) error { + _, err := c.api. + URL("/connection-manager/api/v1/connections/%s/access_roles/%s", connID, roleID). Delete() return err } -// RevokeAccessRoleFromAllConnections revoke permissions for a role from connections -func (store *ConnectionManager) RevokeAccessRoleFromAllConnections(roleID string) error { - _, err := store.api. - URL("/connection-manager/api/v1/connections/access_roles/%s", - url.PathEscape(roleID)). +// RevokeAccessRoleFromAllConnections revoke permissions for a role from all connections. +func (c *ConnectionManager) RevokeAccessRoleFromAllConnections(roleID string) error { + _, err := c.api. + URL("/connection-manager/api/v1/connections/access_roles/%s", roleID). Delete() return err } -// TerminateConnection terminate connection by ID. -func (store *ConnectionManager) TerminateConnection(connID string) error { - _, err := store.api. - URL("/connection-manager/api/v1/terminate/connection/%s", url.PathEscape(connID)). +// GetConnectionTags get connection tags. +func (c *ConnectionManager) GetConnectionTags(opts ...filters.Option) (*response.ResultSet[string], error) { + tags := &response.ResultSet[string]{} + params := url.Values{} + + for _, opt := range opts { + opt(¶ms) + } + + _, err := c.api. + URL("/connection-manager/api/v1/connections/tags"). + Query(params). + Get(&tags) + + return tags, err +} + +// UpdateConnectionTags update connection tags. +func (c *ConnectionManager) UpdateConnectionTags(tags []string, connectionID string) error { + _, err := c.api. + URL("/connection-manager/api/v1/connections/%s/tags", connectionID). + Put(&tags) + + return err +} + +// TerminateConnection terminate connection by id. +func (c *ConnectionManager) TerminateConnection(connID string) error { + _, err := c.api. + URL("/connection-manager/api/v1/terminate/connection/%s", connID). Post(nil) return err } -// TerminateConnectionsByTargetHost terminate connection(s) from host -func (store *ConnectionManager) TerminateConnectionsByTargetHost(hostID string) error { - _, err := store.api. - URL("/connection-manager/api/v1/terminate/host/%s", url.PathEscape(hostID)). +// MARK: Terminate +// TerminateConnectionsByHost terminate connections from host. +func (c *ConnectionManager) TerminateConnectionsByHost(hostID string) error { + _, err := c.api. + URL("/connection-manager/api/v1/terminate/host/%s", hostID). Post(nil) return err } // TerminateConnectionsByUser terminate connection(s) of a user -func (store *ConnectionManager) TerminateConnectionsByUser(userID string) error { - _, err := store.api. - URL("/connection-manager/api/v1/terminate/user/%s", url.PathEscape(userID)). +func (c *ConnectionManager) TerminateConnectionsByUser(userID string) error { + _, err := c.api. + URL("/connection-manager/api/v1/terminate/user/%s", userID). Post(nil) return err } -// UEBA - -// UebaConfigurations get ueba configurations -func (store *ConnectionManager) UebaConfigurations() (UebaConfigurations, error) { - configurations := UebaConfigurations{} - _, err := store.api. +// MARK: UEBA Management +// GetUebaConfigurations get ueba configurations. +func (c *ConnectionManager) GetUebaConfigurations() (*UebaConfigurations, error) { + configurations := &UebaConfigurations{} + _, err := c.api. URL("/connection-manager/api/v1/ueba/configure"). Get(&configurations) return configurations, err } -// SetUebaConfigurations set ueba configurations -func (store *ConnectionManager) SetUebaConfigurations(configurations *UebaConfigurations) error { - _, err := store.api. +// SetUebaConfigurations set ueba configurations. +func (c *ConnectionManager) SetUebaConfigurations(configurations *UebaConfigurations) error { + _, err := c.api. URL("/connection-manager/api/v1/ueba/configure"). Post(&configurations) return err } -// UebaAnomalySettings get ueba anomaly settings -func (store *ConnectionManager) UebaAnomalySettings() (UebaAnomalySettings, error) { +// GetUebaAnomalySettings get ueba anomaly settings. +func (c *ConnectionManager) GetUebaAnomalySettings() (UebaAnomalySettings, error) { settings := UebaAnomalySettings{} - _, err := store.api. + _, err := c.api. URL("/connection-manager/api/v1/ueba/anomaly-settings"). Get(&settings) return settings, err } -// CreateAnomalySettings create Ueba anomaly settings -func (store *ConnectionManager) CreateAnomalySettings(settings UebaAnomalySettings) error { - - _, err := store.api. +// CreateUebaAnomalySettings create Ueba anomaly settings. +func (c *ConnectionManager) CreateUebaAnomalySettings(settings UebaAnomalySettings) error { + _, err := c.api. URL("/connection-manager/api/v1/ueba/anomaly-settings"). Post(&settings) return err } -// StartAnalyzing start ueba analysis -func (store *ConnectionManager) StartAnalyzing(datasetID string) error { - _, err := store.api. - URL("/connection-manager/api/v1/ueba/start-analyzing/%s", url.PathEscape(datasetID)). +// StartAnalyzing start analyzing connections with a saved dataset. +func (c *ConnectionManager) StartAnalyzing(datasetID string) error { + _, err := c.api. + URL("/connection-manager/api/v1/ueba/start-analyzing/%s", datasetID). Post(nil) return err } -// StopAnalyzing stop ueba analysis -func (store *ConnectionManager) StopAnalyzing() error { - _, err := store.api. +// StopAnalyzing stop analyzing connection anomalies. +func (c *ConnectionManager) StopAnalyzing() error { + _, err := c.api. URL("/connection-manager/api/v1/ueba/stop-analyzing"). Post(nil) return err } -// CreateIdForUebaScript create session ID for Ueba setup script -func (store *ConnectionManager) CreateIdForUebaScript() (IDstruct, error) { - sessionId := IDstruct{} - _, err := store.api. - URL("/connection-manager/api/v1/ueba/setup-script"). - Post(nil, &sessionId) - - return sessionId, err -} - -// DownloadUebaScript download ueba setup script. -func (store *ConnectionManager) DownloadUebaScript(sessionID string) error { - filename := fmt.Sprintf("ueba-%s-startup.sh", sessionID) - err := store.api. - URL("/connection-manager/api/v1/ueba/setup-script/%s", url.PathEscape(sessionID)). - Download(filename) - return err -} - -// UebaDatasets get dataset object list for ueba. -func (store *ConnectionManager) UebaDatasets(logs bool, bin_count int) (uebaDatasetsResult, error) { - result := uebaDatasetsResult{} - filters := UebaDatasetQueryParams{ - Logs: logs, - BinCount: bin_count, - } +// MARK: UEBA Train +// GetUebaDatasets get dataset list for ueba. +func (c *ConnectionManager) GetUebaDatasets() (*response.ResultSet[Dataset], error) { + datasets := &response.ResultSet[Dataset]{} - _, err := store.api. + _, err := c.api. URL("/connection-manager/api/v1/ueba/datasets"). - Query(&filters). - Get(&result) + Get(&datasets) - return result, err + return datasets, err } -// CreateUebaDataset Save new dataset definition. -func (store *ConnectionManager) CreateUebaDataset(uebaDatasetParam DatasetBodyParam) (IDstruct, error) { - datasetID := IDstruct{} +// CreateUebaDataset create a new dataset. +func (c *ConnectionManager) CreateUebaDataset(dataset *Dataset) (response.Identifier, error) { + identifier := response.Identifier{} - _, err := store.api. + _, err := c.api. URL("/connection-manager/api/v1/ueba/datasets"). - Post(&uebaDatasetParam, &datasetID) + Post(&dataset, &identifier) - return datasetID, err + return identifier, err } -// UebaDataset Get dataset by id, possibility to filter training history. -func (store *ConnectionManager) UebaDataset(logs bool, bin_count int, datasetID string) (Dataset, error) { - result := Dataset{} - filters := UebaDatasetQueryParams{ - Logs: logs, - BinCount: bin_count, - } +// GetUebaDataset get ueba dataset by id. +func (c *ConnectionManager) GetUebaDataset(datasetID string) (*Dataset, error) { + dataset := &Dataset{} - _, err := store.api. + _, err := c.api. URL("/connection-manager/api/v1/ueba/datasets/%s", datasetID). - Query(&filters). - Get(&result) + Get(&dataset) - return result, err + return dataset, err } -// UpdateUebaDataset Update dataset. -func (store *ConnectionManager) UpdateUebaDataset(uebaDatasetParam DatasetBodyParam, datasetID string) error { - - _, err := store.api. +// UpdateUebaDataset update ueba dataset. +func (c *ConnectionManager) UpdateUebaDataset(dataset *Dataset, datasetID string) error { + _, err := c.api. URL("/connection-manager/api/v1/ueba/datasets/%s", datasetID). - Put(&uebaDatasetParam) + Put(&dataset) return err } -// DeleteUebaDataset Delete dataset. -func (store *ConnectionManager) DeleteUebaDataset(datasetID string) error { - _, err := store.api. +// DeleteUebaDataset delete ueba dataset. +func (c *ConnectionManager) DeleteUebaDataset(datasetID string) error { + _, err := c.api. URL("/connection-manager/api/v1/ueba/datasets/%s", datasetID). Delete() return err } -// TrainUebaDataset Train or retrain saved dataset. -func (store *ConnectionManager) TrainUebaDataset(datasetID string, set_active_after_training bool) (ConnectionCount, error) { +// TrainUebaDataset train or retrain ueba dataset. +func (c *ConnectionManager) TrainUebaDataset(datasetID string, opts ...filters.Option) (ConnectionCount, error) { count := ConnectionCount{} - filters := trainingQueryParams{ - SetActiveAfterTraining: set_active_after_training, + params := url.Values{} + + for _, opt := range opts { + opt(¶ms) } - _, err := store.api. - URL("/connection-manager/api/v1/ueba/train/%s", url.PathEscape(datasetID)). - Query(&filters). + _, err := c.api. + URL("/connection-manager/api/v1/ueba/train/%s", datasetID). + Query(params). Post(nil, &count) return count, err } -// ConnectionCounts Get number of connections for dataset with given parameters. -// All connections, if json empty in body. -func (store *ConnectionManager) ConnectionCounts(timerange TimeRange) (ConnectionCount, error) { +// GetConnectionCounts get number of connections for dataset. +func (c *ConnectionManager) GetConnectionCounts(timeRange TimeRange) (ConnectionCount, error) { count := ConnectionCount{} - _, err := store.api. + _, err := c.api. URL("/connection-manager/api/v1/ueba/query-connection-count"). - Post(&timerange, &count) + Post(&timeRange, &count) return count, err } -// UebaStatus Get Ueba service status -func (store *ConnectionManager) UebaStatus() (*common.ServiceStatus, error) { - uebaStatus := &common.ServiceStatus{} +// MARK: UEBA Setup +// CreateSessionForUebaScriptDownload create session id for ueba setup script download. +func (c *ConnectionManager) CreateSessionForUebaScriptDownload() (response.Identifier, error) { + identifier := response.Identifier{} + + _, err := c.api. + URL("/connection-manager/api/v1/ueba/setup-script"). + Post(nil, &identifier) + + return identifier, err +} + +// DownloadUebaScript download ueba setup script. +func (c *ConnectionManager) DownloadUebaScript(sessionID, filename string) error { + err := c.api. + URL("/connection-manager/api/v1/ueba/setup-script/%s", sessionID). + Download(filename) + + return err +} + +// MARK: UEBA Status +// GetUebaStatus get ueba service status. +func (c *ConnectionManager) GetUebaStatus() (*response.ServiceStatus, error) { + status := &response.ServiceStatus{} - _, err := store.api. + _, err := c.api. URL("/connection-manager/api/v1/ueba/status"). - Get(uebaStatus) + Get(&status) - return uebaStatus, err + return status, err } -// UebaInternalStatus Get Ueba microservice internal status -func (store *ConnectionManager) UebaInternalStatus() (UebaInternalStatus, error) { +// GetUebaInternalStatus get ueba internal status. +func (c *ConnectionManager) GetUebaInternalStatus() (UebaInternalStatus, error) { uebaInternalStatus := UebaInternalStatus{} - _, err := store.api. + _, err := c.api. URL("/connection-manager/api/v1/ueba/status/internal"). Get(&uebaInternalStatus) diff --git a/api/connectionmanager/model.go b/api/connectionmanager/model.go index 98f8dfa..26a459a 100644 --- a/api/connectionmanager/model.go +++ b/api/connectionmanager/model.go @@ -6,183 +6,172 @@ package connectionmanager -import "time" +import ( + "time" -// Params query params definition -type Params struct { - Offset int `json:"offset,omitempty"` - Limit int `json:"limit,omitempty"` - Sortdir string `json:"sortdir,omitempty"` - Sortkey string `json:"sortkey,omitempty"` - Format string `json:"format,omitempty"` - Filter string `json:"filter,omitempty"` - FuzzyCount bool `json:"fuzzycount,omitempty"` - Query string `json:"query,omitempty"` + "github.com/SSHcom/privx-sdk-go/api/hoststore" + "github.com/SSHcom/privx-sdk-go/api/networkaccessmanager" + "github.com/SSHcom/privx-sdk-go/api/rolestore" +) + +// DownloadTrailLogParams query parameter definition. +type DownloadTrailLogParams struct { + Format string `url:"format,omitempty"` +} + +// ConnectionTagsParams query parameter definition. +type ConnectionTagsParams struct { + Query string `url:"query,omitempty"` +} + +// UebaTrainingParams query parameter definition. +type UebaTrainingParams struct { + SetActiveAfterTraining bool `url:"set_active_after_training"` } -// ConnectionHost connection host struct definition +// Connection connection struct definition. +type Connection struct { + ID string `json:"id,omitempty"` + ProxyID string `json:"proxy_id,omitempty"` + Type string `json:"type,omitempty"` + Mode string `json:"mode,omitempty"` + UserAgent string `json:"user_agent,omitempty"` + AuthMethod []string `json:"authentication_method,omitempty"` + User ConnectionUser `json:"user,omitempty"` + UserRoles []ConnectionRole `json:"user_roles,omitempty"` + UserData *rolestore.User `json:"user_data,omitempty"` + TargetHost ConnectionHost `json:"target_host,omitempty"` + TargetHostAddress string `json:"target_host_address,omitempty"` + TargetHostAccount string `json:"target_host_account,omitempty"` + TargetHostRoles []ConnectionRole `json:"target_host_roles,omitempty"` + TargetHostData *hoststore.Host `json:"target_host_data,omitempty"` + TargetNetworkData *networkaccessmanager.NetworkTarget `json:"target_network_data,omitempty"` + RemoteAddress string `json:"remote_address,omitempty"` + Connected string `json:"connected,omitempty"` + Disconnected string `json:"disconnected,omitempty"` + Duration int32 `json:"duration,omitempty"` + Status string `json:"status,omitempty"` + LastActivity string `json:"last_activity,omitempty"` + BytesIn int64 `json:"bytes_in,omitempty"` + BytesOut int64 `json:"bytes_out,omitempty"` + ForceDisconnect string `json:"force_disconnect,omitempty"` + TerminationReason string `json:"termination_reason,omitempty"` + Created string `json:"created,omitempty"` + Updated string `json:"updated,omitempty"` + UpdatedBy string `json:"updated_by,omitempty"` + AuditEnabled bool `json:"audit_enabled,omitempty"` + TrailID string `json:"trail_id,omitempty"` + TrailRemoved bool `json:"trail_removed,omitempty"` + IndexStatus string `json:"index_status,omitempty"` + AccessGroupID string `json:"access_group_id,omitempty"` + Keywords string `json:"keywords,omitempty"` + SessionID string `json:"session_id,omitempty"` + AccessRoles []AccessRoles `json:"access_roles,omitempty"` + Tags []string `json:"tags,omitempty"` +} + +// AccessRoles access roles definition. +type AccessRoles struct { + ID string `json:"id"` + Name string `json:"name"` + Added time.Time `json:"added"` +} + +// ConnectionHost connection host definition. type ConnectionHost struct { ID string `json:"id,omitempty"` CommonName string `json:"common_name,omitempty"` } -// ConnectionRole connection role struct definition +// ConnectionUser connection user definition. +type ConnectionUser struct { + ID string `json:"id,omitempty"` + DisplayName string `json:"display_name,omitempty"` +} + +// ConnectionRole connection role definition. type ConnectionRole struct { ID string `json:"id,omitempty"` Name string `json:"name,omitempty"` } -// UserData user data struct definition -type UserData struct { - ID string `json:"id,omitempty"` - Username string `json:"display_name,omitempty"` -} - -// AccessRoles access roles struct definition -type AccessRoles struct { - ID string `json:"id"` - Name string `json:"name"` - Added string `json:"added"` -} - -// Connection connection struct definition -type Connection struct { - ID string `json:"id,omitempty"` - ProxyID string `json:"proxy_id,omitempty"` - Type string `json:"type,omitempty"` - UserAgent string `json:"user_agent,omitempty"` - TargetHostAddress string `json:"target_host_address,omitempty"` - TargetHostAccount string `json:"target_host_account,omitempty"` - RemoteAddress string `json:"remote_address,omitempty"` - Connected string `json:"connected,omitempty"` - Disconnected string `json:"disconnected,omitempty"` - Status string `json:"status,omitempty"` - LastActivity string `json:"last_activity,omitempty"` - ForceDisconnect string `json:"force_disconnect,omitempty"` - TerminationReason string `json:"termination_reason,omitempty"` - Created string `json:"created,omitempty"` - Updated string `json:"updated,omitempty"` - UpdatedBy string `json:"updated_by,omitempty"` - TrailID string `json:"trail_id,omitempty"` - IndexStatus string `json:"index_status,omitempty"` - AccessGroupID string `json:"access_group_id,omitempty"` - AuthMethod []string `json:"authentication_method,omitempty"` - BytesIn int `json:"bytes_in,omitempty"` - BytesOut int `json:"bytes_out,omitempty"` - Duration int `json:"duration,omitempty"` - TrailRemoved bool `json:"trail_removed,omitempty"` - AuditEnabled bool `json:"audit_enabled,omitempty"` - TargetHostData ConnectionHost `json:"target_host_data,omitempty"` - UserData UserData `json:"user,omitempty"` - UserRoles []ConnectionRole `json:"user_roles,omitempty"` - TargetHostRoles []ConnectionRole `json:"target_host_roles,omitempty"` - AccessRoles []AccessRoles `json:"access_roles,omitempty"` - Tags []string `json:"tags,omitempty"` -} - -// TimestampSearch timestamp search struct definition +// ConnectionSearch connection search request definition. +type ConnectionSearch struct { + ID []string `json:"id,omitempty"` + ProxyID []string `json:"proxy_id,omitempty"` + Type []string `json:"type,omitempty"` + Mode []string `json:"mode,omitempty"` + UserAgent []string `json:"user_agent,omitempty"` + AuthMethod []string `json:"authentication_method,omitempty"` + UserID []string `json:"user_id,omitempty"` + UserDisplayName []string `json:"user_display_name,omitempty"` + UserRoles []string `json:"user_roles,omitempty"` + TargetHost []string `json:"target_host_id,omitempty"` + TargetHostCommonName []string `json:"target_host_common_name,omitempty"` + TargetHostAddress []string `json:"target_host_address,omitempty"` + TargetHostAccount []string `json:"target_host_account,omitempty"` + TargetHostRoles []string `json:"target_host_roles,omitempty"` + RemoteAddress []string `json:"remote_address,omitempty"` + Connected *TimestampSearch `json:"connected,omitempty"` + Disconnected *TimestampSearch `json:"disconnected,omitempty"` + Status []string `json:"status,omitempty"` + LastActivity *TimestampSearch `json:"last_activity,omitempty"` + ForceDisconnect []string `json:"force_disconnect,omitempty"` + KeyWords string `json:"keywords,omitempty"` + AccessRoles []string `json:"access_roles,omitempty"` + HasAccessRoles *bool `json:"has_access_roles,omitempty"` + SessionID string `json:"session_id,omitempty"` + Tags []string `json:"tags,omitempty"` +} + +// TimestampSearch timestamp search request definition. type TimestampSearch struct { Start string End string } -// ConnectionSearch connection search struct definition -type ConnectionSearch struct { - ID []string `json:"id,omitempty"` - ProxyID []string `json:"proxy_id,omitempty"` - Type []string `json:"type,omitempty"` - Mode []string `json:"mode,omitempty"` - UserAgent []string `json:"user_agent,omitempty"` - AuthMethod []string `json:"authentication_method,omitempty"` - UserID []string `json:"user_id,omitempty"` - UserDisplayName []string `json:"user_display_name,omitempty"` - UserRoles []string `json:"user_roles,omitempty"` - TargetHost []string `json:"target_host_id,omitempty"` - TargetHostCommonName []string `json:"target_host_common_name,omitempty"` - TargetHostAddress []string `json:"target_host_address,omitempty"` - TargetHostAccount []string `json:"target_host_account,omitempty"` - TargetHostRoles []string `json:"target_host_roles,omitempty"` - RemoteAddress []string `json:"remote_address,omitempty"` - Status []string `json:"status,omitempty"` - ForceDisconnect []string `json:"force_disconnect,omitempty"` - AccessRoles []string `json:"access_roles,omitempty"` - KeyWords string `json:"keywords,omitempty"` - HasAccessRoles bool `json:"has_access_roles,omitempty"` - Connected TimestampSearch `json:"connected,omitempty"` - Disconnected TimestampSearch `json:"disconnected,omitempty"` - LastActivity TimestampSearch `json:"last_activity,omitempty"` - Tags []string `json:"tags,omitempty"` -} - -//UEBA - -// UebaConfigurations uebaconfigurations struct definition +// UebaConfigurations ueba configurations definition. type UebaConfigurations struct { - Address string `json:"address"` - TrustAnchors string `json:"trust_anchors"` + Address string `json:"address"` + TrustAnchors string `json:"trust_anchors"` + TrustAnchorsInfo []hoststore.HostCertificateInfo `json:"trust_anchors_info,omitempty"` } -// UebaAnomalySettings ueba anomaly settings struct definition +// UebaAnomalySettings ueba anomaly settings definition. type UebaAnomalySettings struct { Action string `json:"action"` Threshold float32 `json:"threshold"` } -// UebaDatasetQueryParams query params definition for Ueba DataSet -type UebaDatasetQueryParams struct { - Logs bool `json:"logs,omitempty"` - BinCount int `json:"bin_count,omitempty"` +// Dataset ueba dataset definition. +type Dataset struct { + ID string `json:"id"` + LastTraining *time.Time `json:"last_training"` + IsActive bool `json:"is_active"` + UseForInferenceOnceTrained bool `json:"use_for_inference_once_trained"` + TimeRangeSettings *TimeRange `json:"time_range_settings"` + TrainingResults []UebaTrainingResult `json:"training_results"` + Created *time.Time `json:"created,omitempty"` + CreatedBy string `json:"created_by,omitempty"` + Updated *time.Time `json:"updated,omitempty"` + UpdatedBy string `json:"updated_by,omitempty"` + Comment string `json:"comment,omitempty"` } -// TimeRange time range struct definition +// TimeRange time range definition. type TimeRange struct { Start *time.Time `json:"start,omitempty"` End *time.Time `json:"end,omitempty"` Exclude []ExcludeTimeRange `json:"exclude,omitempty"` } +// ExcludeTimeRange exclude time range definition. type ExcludeTimeRange struct { - Start time.Time `json:"start" validate:"required"` - End time.Time `json:"end" validate:"required"` -} - -// Dataset dataset struct definition for Ueba -type Dataset struct { - ID string `db:"id" json:"id" validate:"omitempty,uuid"` - LastTraining *time.Time `db:"last_training" json:"last_training"` - FeatureConfigName string `db:"feature_config_name" json:"-"` - IsActive bool `db:"is_active" json:"is_active"` - UseForInferenceOnceTrained bool `db:"use_for_inference_once_trained" json:"use_for_inference_once_trained"` - Quantile99 float32 `db:"quantile_99" json:"-"` - Quantile999 float32 `db:"quantile_999" json:"-"` - Std float32 `db:"std" json:"-"` - TimeRangeSettings *TimeRange `json:"time_range_settings" validate:"required"` - DBTimeRangeSettings string `db:"time_range_settings" json:"-"` - TrainingResults []UebaTrainingResult `json:"training_results"` - Created *time.Time `db:"created" json:"created,omitempty"` - CreatedBy string `db:"created_by" json:"created_by,omitempty"` - Updated *time.Time `db:"updated" json:"updated,omitempty"` - UpdatedBy string `db:"updated_by" json:"updated_by,omitempty"` - Comment string `db:"comment" json:"comment,omitempty"` -} - -// DatasetBodyParam struct definition for body params in ueba dataset api calls -type DatasetBodyParam struct { - ID string `db:"id" json:"id" validate:"omitempty"` - TimeRangeSettings *TimeRange `json:"time_range_settings" validate:"required"` - Created *time.Time `db:"created" json:"created,omitempty"` - CreatedBy string `db:"created_by" json:"created_by,omitempty"` - Updated *time.Time `db:"updated" json:"updated,omitempty"` - UpdatedBy string `db:"updated_by" json:"updated_by,omitempty"` - Comment string `db:"comment" json:"comment,omitempty"` -} - -type uebaDatasetsResult struct { - Items []Dataset `json:"items"` - Count int `json:"count"` + Start time.Time `json:"start"` + End time.Time `json:"end"` } -// UebaTrainingResult ueba training result struct definition +// UebaTrainingResult ueba training result definition. type UebaTrainingResult struct { DatasetID string `json:"dataset_id"` Created time.Time `json:"created"` @@ -201,34 +190,41 @@ type UebaTrainingResult struct { ValidationDatasetHistogram Histogram `json:"validation_dataset_histogram"` } +// Histogram ueba histogram definition. type Histogram struct { Hist []float32 `json:"hist"` BinEdges []float32 `json:"bin_edges"` } -// trainingQueryParams struct definition for ueba training query params -type trainingQueryParams struct { - SetActiveAfterTraining bool `json:"set_active_after_training"` -} - +// ConnectionCount ueba connection count response definition. type ConnectionCount struct { Count int `json:"count"` } -type IDstruct struct { - ID string `json:"id"` -} - -type UebaInternalModelInstance struct { - ID string `json:"id" validate:"uuid"` +// UebaModelInstance ueba model instance definition. +type UebaModelInstance struct { + ID string `json:"id"` FeatureConfigName string `json:"feature_config_name"` Status string `json:"status"` Created string `json:"created"` } +// UebaInternalStatus ueba internal status definition. type UebaInternalStatus struct { - TrainingStatus string `json:"training_status"` - InferenceStatus string `json:"inference_status"` - DatasetID string `json:"dataset_id" validate:"uuid,omitempty"` - ModelInstanceStatus []UebaInternalModelInstance `json:"model_instance_status"` + TrainingStatus string `json:"training_status"` + InferenceStatus string `json:"inference_status"` + DatasetID string `json:"dataset_id"` + Instances []UebaModelInstance `json:"instances"` +} + +// DownloadSessionID download sessions id response definition. +type DownloadSessionID struct { + SessionID string `json:"session_id"` +} + +// ConnectionPermission connection access permission definition. +type ConnectionPermission struct { + ID string `json:"id"` + Name string `json:"name"` + Added time.Time `json:"added"` } diff --git a/api/dbproxy/client.go b/api/dbproxy/client.go index f473855..90e640d 100644 --- a/api/dbproxy/client.go +++ b/api/dbproxy/client.go @@ -7,37 +7,38 @@ package dbproxy import ( - "github.com/SSHcom/privx-sdk-go/common" + "github.com/SSHcom/privx-sdk-go/api/response" "github.com/SSHcom/privx-sdk-go/restapi" ) -// DbProxy is a db proxy instance. +// DbProxy is a db proxy client instance. type DbProxy struct { api restapi.Connector } -// New creates a new db proxy client instance, using the -// argument SDK API client. +// New db proxy client constructor. func New(api restapi.Connector) *DbProxy { return &DbProxy{api: api} } -// DbProxyStatus get microservice status -func (store *DbProxy) DbProxyStatus() (*common.ServiceStatus, error) { - status := &common.ServiceStatus{} +// MARK: Status +// Status get db proxy microservice status. +func (c *DbProxy) Status() (*response.ServiceStatus, error) { + status := &response.ServiceStatus{} - _, err := store.api. + _, err := c.api. URL("/db-proxy/api/v1/status"). Get(status) return status, err } -// DbProxyConf get db proxy configuration -func (store *DbProxy) DbProxyConf() (*DBProxyConf, error) { - config := &DBProxyConf{} +// MARK: Config +// GetDbProxyConfig get db proxy configuration. +func (c *DbProxy) GetDbProxyConfig() (*DBProxyAPIConf, error) { + config := &DBProxyAPIConf{} - _, err := store.api. + _, err := c.api. URL("/db-proxy/api/v1/conf"). Get(config) diff --git a/api/dbproxy/model.go b/api/dbproxy/model.go index 4c3100f..81989b8 100644 --- a/api/dbproxy/model.go +++ b/api/dbproxy/model.go @@ -6,7 +6,7 @@ package dbproxy -// DBProxyCACertificateInfo DB proxy x509 CA certificate information +// DBProxyCACertificateInfo db proxy x509 CA certificate definition. type DBProxyCACertificateInfo struct { Subject string `json:"subject,omitempty"` Issuer string `json:"issuer,omitempty"` @@ -17,8 +17,8 @@ type DBProxyCACertificateInfo struct { FingerPrintSHA256 string `json:"fingerprint_sha256,omitempty"` } -// DBProxyConf DB proxy config definition -type DBProxyConf struct { +// DBProxyAPIConf db proxy configuration definition. +type DBProxyAPIConf struct { CACertificate *DBProxyCACertificateInfo `json:"ca_certificate,omitempty"` Chain string `json:"ca_certificate_chain,omitempty"` } From 99a4270db28bfce0a43a5cdf530fa42b20f571e6 Mon Sep 17 00:00:00 2001 From: iljaSL Date: Tue, 12 Nov 2024 14:47:55 +0200 Subject: [PATCH 2/5] refactor(v2): add network access manager refactored state --- api/networkaccessmanager/client.go | 150 +++++++++++++++-------------- api/networkaccessmanager/model.go | 123 ++++++++++++----------- 2 files changed, 139 insertions(+), 134 deletions(-) diff --git a/api/networkaccessmanager/client.go b/api/networkaccessmanager/client.go index b4b72aa..e014577 100644 --- a/api/networkaccessmanager/client.go +++ b/api/networkaccessmanager/client.go @@ -9,6 +9,8 @@ package networkaccessmanager import ( "net/url" + "github.com/SSHcom/privx-sdk-go/api/filters" + "github.com/SSHcom/privx-sdk-go/api/response" "github.com/SSHcom/privx-sdk-go/restapi" ) @@ -17,114 +19,120 @@ type NetworkAccessManager struct { api restapi.Connector } -// New creates a new network access manager client instance, using the -// argument SDK API client. +// New network access manager client constructor. func New(api restapi.Connector) *NetworkAccessManager { return &NetworkAccessManager{api: api} } -// nwtargets Get network targets -func (nam *NetworkAccessManager) GetNetworkTargets(offset, limit int, sortkey, sortdir, name, id string) (ApiNwtargetsResponse, error) { - result := ApiNwtargetsResponse{} - filters := Params{ - Offset: offset, - Limit: limit, - Sortkey: sortkey, - Sortdir: sortdir, - Name: name, - ID: id, +// MARK: Status +// Status get network access manager microservice status. +func (c *NetworkAccessManager) Status() (*response.ServiceStatus, error) { + status := &response.ServiceStatus{} + + _, err := c.api. + URL("/network-access-manager/api/v1/status"). + Get(status) + + return status, err +} + +// MARK: Network Targets +// GetNetworkTargets get network targets. +func (c *NetworkAccessManager) GetNetworkTargets(opts ...filters.Option) (*response.ResultSet[NetworkTarget], error) { + targets := &response.ResultSet[NetworkTarget]{} + params := url.Values{} + + for _, opt := range opts { + opt(¶ms) } - _, err := nam.api. + _, err := c.api. URL("/network-access-manager/api/v1/nwtargets"). - Query(&filters). - Get(&result) + Query(params). + Get(&targets) - return result, err + return targets, err } -// nwtargets Create network target -func (nam *NetworkAccessManager) CreateNetworkTargets(network Item) (ApiNwtargetsResponsePost, error) { - result := ApiNwtargetsResponsePost{} +// CreateNetworkTarget create network target. +func (c *NetworkAccessManager) CreateNetworkTarget(target *NetworkTarget) (response.Identifier, error) { + identifier := response.Identifier{} - _, err := nam.api. + _, err := c.api. URL("/network-access-manager/api/v1/nwtargets"). - Post(&network, &result) + Post(&target, &identifier) - return result, err + return identifier, err } -// nwtargets Search network target -func (nam *NetworkAccessManager) SearchNetworkTargets(offset, limit int, sortkey, sortdir, filter, keywords string) (ApiNwtargetsResponse, error) { - result := ApiNwtargetsResponse{} - filters := Params{ - Offset: offset, - Limit: limit, - Sortkey: sortkey, - Sortdir: sortdir, - Filter: filter, - } - body := KeywordsStruct{ - Keywords: keywords, +// SearchNetworkTargets search network target. +func (c *NetworkAccessManager) SearchNetworkTargets(search NetworkTargetSearch, opts ...filters.Option) (*response.ResultSet[NetworkTarget], error) { + targets := &response.ResultSet[NetworkTarget]{} + params := url.Values{} + + for _, opt := range opts { + opt(¶ms) } - _, err := nam.api. + + _, err := c.api. URL("/network-access-manager/api/v1/nwtargets/search"). - Query(&filters). - Post(body, &result) + Query(params). + Post(&search, &targets) - return result, err + return targets, err } -// Get microservice status -func (nam *NetworkAccessManager) NetworkAccessManagerStatus() (ApiNAMstatus, error) { - result := ApiNAMstatus{} +// GetNetworkTargetTags get network target tags. +func (c *NetworkAccessManager) GetNetworkTargetTags(opts ...filters.Option) (*response.ResultSet[string], error) { + tags := &response.ResultSet[string]{} + params := url.Values{} - _, err := nam.api. - URL("/network-access-manager/api/v1/status"). - Get(&result) + for _, opt := range opts { + opt(¶ms) + } + + _, err := c.api. + URL("/network-access-manager/api/v1/nwtargets/tags"). + Query(params). + Get(&tags) - return result, err + return tags, err } -// nwtarget Get network targets by ID -func (nam *NetworkAccessManager) GetNetworkTargetByID(NetworkTargetID string) (Item, error) { - result := Item{} +// GetNetworkTarget get network target by id. +func (c *NetworkAccessManager) GetNetworkTarget(targetID string) (*NetworkTarget, error) { + target := &NetworkTarget{} - _, err := nam.api. - URL("/network-access-manager/api/v1/nwtargets/%s", url.PathEscape(NetworkTargetID)). - Get(&result) + _, err := c.api. + URL("/network-access-manager/api/v1/nwtargets/%s", targetID). + Get(&target) - return result, err + return target, err } -//nwtarget Update a network target -func (nam *NetworkAccessManager) UpdateNetworkTarget(networkTarget *Item, NetworkTargetID string) error { - - _, err := nam.api. - URL("/network-access-manager/api/v1/nwtargets/%s", url.PathEscape(NetworkTargetID)). - Put(networkTarget) +// UpdateNetworkTarget update network target. +func (c *NetworkAccessManager) UpdateNetworkTarget(targetID string, target *NetworkTarget) error { + _, err := c.api. + URL("/network-access-manager/api/v1/nwtargets/%s", targetID). + Put(&target) return err } -// nwtarget Delete network target by ID -func (nam *NetworkAccessManager) DeleteNetworkTargetByID(NetworkTargetID string) error { - - _, err := nam.api. - URL("/network-access-manager/api/v1/nwtargets/%s", url.PathEscape(NetworkTargetID)). +// DeleteNetworkTarget delete network target by id. +func (c *NetworkAccessManager) DeleteNetworkTarget(targetID string) error { + _, err := c.api. + URL("/network-access-manager/api/v1/nwtargets/%s", targetID). Delete() return err } -//nwtarget disable a network target -func (nam *NetworkAccessManager) DisableNetworkTargetByID(DisabledVal bool, NetworkTargetID string) error { - dis := DisabledStruct{} - dis.Disabled = DisabledVal - - _, err := nam.api. - URL("/network-access-manager/api/v1/nwtargets/%s/disabled", url.PathEscape(NetworkTargetID)). - Put(dis) +// DisableNetworkTarget disable network target by id. +func (c *NetworkAccessManager) DisableNetworkTarget(targetID string, disable NetworkTargetDisable) error { + _, err := c.api. + URL("/network-access-manager/api/v1/nwtargets/%s/disabled", targetID). + Put(&disable) return err } diff --git a/api/networkaccessmanager/model.go b/api/networkaccessmanager/model.go index 5d9fa39..228daf5 100644 --- a/api/networkaccessmanager/model.go +++ b/api/networkaccessmanager/model.go @@ -6,77 +6,74 @@ package networkaccessmanager -type Nat struct { - Addr string `json:"addr,omitempty"` - Port int `json:"port,omitempty"` -} -type Port struct { - Start int `json:"start,omitempty"` - End int `json:"end,omitempty"` -} -type Ip struct { - Start string `json:"start,omitempty"` - End string `json:"end,omitempty"` -} -type Selector struct { - IP Ip `json:"ip,omitempty"` - Port Port `json:"port,omitempty"` - Proto string `json:"proto,omitempty"` +// NetworkTargetTagsParams network target tags query parameter definition. +type NetworkTargetTagsParams struct { + Query int `url:"query,omitempty"` } -type Dst struct { - Selector Selector `json:"selector,omitempty"` - Nat *Nat `json:"nat,omitempty"` -} -type Role struct { - ID string `json:"id,omitempty"` - Name string `json:"name,omitempty"` + +// NetworkTargetDisable network target disable request definition. +type NetworkTargetDisable struct { + Disabled bool `json:"disabled"` } -type Item struct { - ID string `json:"id,omitempty"` - Created string `json:"created,omitempty"` - Updated string `json:"updated,omitempty"` - UpdatedBy string `json:"updated_by,omitempty"` - Author string `json:"author,omitempty"` - Comment string `json:"comment,omitempty"` - Name string `json:"name,omitempty"` - UserInstructions string `json:"user_instructions,omitempty"` - SrcNat bool `json:"src_nat,omitempty"` - Roles []Role `json:"roles,omitempty"` - Dst []Dst `json:"dst,omitempty"` - ExclusiveAccess bool `json:"exclusive_access,omitempty"` - Disabled string `json:"disabled,omitempty"` + +// NetworkTarget network target definition. +type NetworkTarget struct { + ID string `json:"id"` + Name string `json:"name"` + Dst []Destination `json:"dst"` + SrcNAT bool `json:"src_nat,omitempty"` + Roles []RoleHandle `json:"roles"` + Tags []string `json:"tags"` + Comment string `json:"comment,omitempty"` + UserInstructions string `json:"user_instructions,omitempty"` + ExclusiveAccess bool `json:"exclusive_access,omitempty"` + Disabled string `json:"disabled,omitempty"` + Created string `json:"created"` + Author string `json:"author"` + Updated string `json:"updated"` + UpdatedBy string `json:"updated_by"` } -type ApiNwtargetsResponse struct { - Count int `json:"count"` - Items []Item `json:"items"` + +// RoleHandle is a handle to network target role definition. +type RoleHandle struct { + ID string `json:"id"` + Name string `json:"name,omitempty"` + Deleted bool `json:"deleted,omitempty"` } -type ApiNwtargetsResponsePost struct { - ID string `json:"id,omitempty"` + +// Destination network target destination definition. +type Destination struct { + Sel Selector `json:"selector"` + NAT *NATParameters `json:"nat,omitempty"` } -type Params struct { - Offset int `json:"offset,omitempty"` - Limit int `json:"limit,omitempty"` - Sortkey string `json:"sortkey,omitempty"` - Sortdir string `json:"sortdir,omitempty"` - Name string `json:"name,omitempty"` - ID string `json:"id,omitempty"` - Filter string `json:"filter,omitempty"` + +// Selector network target selector definition. +type Selector struct { + IP IPRange `json:"ip"` + Protocol string `json:"proto,omitempty"` + Port *PortRange `json:"port,omitempty"` } -type StatusDetails struct { - Key string `json:"k,omitempty"` - Value string `json:"v,omitempty"` +// PortRange port range definition +type PortRange struct { + Start int `json:"start"` + End int `json:"end"` } -type ApiNAMstatus struct { - Version string `json:"version"` - ApiVersion string `json:"api_version,omitempty"` - Status string `json:"status,omitempty"` - StatusMessage string `json:"status_message,omitempty"` - StatusDetails []StatusDetails `json:"status_details,omitempty"` + +// IPRange ip range definition. +type IPRange struct { + Start string `json:"start"` + End string `json:"end"` } -type KeywordsStruct struct { - Keywords string `json:"keywords,omitempty"` + +// NATParameters network target parameters. +type NATParameters struct { + Addr string `json:"addr"` + Port int `json:"port,omitempty"` } -type DisabledStruct struct { - Disabled bool `json:"disabled,omitempty"` + +// NetworkTargetSearch network target search request definition. +type NetworkTargetSearch struct { + Keywords string `json:"keywords,omitempty"` + Tags []string `json:"tags,omitempty"` } From bf5e96fe348ea46ca2eaae8c53b877ea9a0e94a3 Mon Sep 17 00:00:00 2001 From: iljaSL Date: Tue, 12 Nov 2024 14:55:50 +0200 Subject: [PATCH 3/5] refactor(v2): add refactored state rolestore, secretsmanager and hoststore --- api/hoststore/client.go | 273 ++++++---- api/hoststore/model.go | 448 ++++++++++------ api/rolestore/client.go | 979 +++++++++++++++++------------------ api/rolestore/model.go | 694 +++++++++++++++---------- api/secretsmanager/client.go | 522 ++++++++++--------- api/secretsmanager/model.go | 111 ++-- 6 files changed, 1710 insertions(+), 1317 deletions(-) diff --git a/api/hoststore/client.go b/api/hoststore/client.go index a44c284..30ff17c 100644 --- a/api/hoststore/client.go +++ b/api/hoststore/client.go @@ -9,172 +9,255 @@ package hoststore import ( "net/url" + "github.com/SSHcom/privx-sdk-go/api/filters" + "github.com/SSHcom/privx-sdk-go/api/response" "github.com/SSHcom/privx-sdk-go/restapi" ) -// HostStore is a role-store client instance. +// HostStore is a host store client instance. type HostStore struct { api restapi.Connector } -type hostResult struct { - Count int `json:"count"` - Items []Host `json:"items"` +// New host store client constructor. +func New(api restapi.Connector) *HostStore { + return &HostStore{api: api} } -type tagsResult struct { - Count int `json:"count"` - Items []string `json:"items"` -} +// MARK: Status +// Status get host store microservice status. +func (c *HostStore) Status() (*response.ServiceStatus, error) { + status := &response.ServiceStatus{} -// New creates a new host-store client instance -// See http://apispecs.ssh.com/#swagger-ui-4 for details about api -func New(api restapi.Connector) *HostStore { - return &HostStore{api: api} + _, err := c.api. + URL("/host-store/api/v1/status"). + Get(status) + + return status, err } -// SearchHost search for existing hosts -func (store *HostStore) SearchHost(sortkey, sortdir, filter string, offset, limit int, searchObject *HostSearchObject) ([]Host, error) { - result := hostResult{} - filters := Params{ - Offset: offset, - Limit: limit, - Sortkey: sortkey, - Sortdir: sortdir, - Filter: filter, +// MARK: Hosts +// SearchHosts search hosts. +func (c *HostStore) SearchHosts(search *HostSearch, opts ...filters.Option) (*response.ResultSet[Host], error) { + hosts := &response.ResultSet[Host]{} + params := url.Values{} + + for _, opt := range opts { + opt(¶ms) } - _, err := store.api. + _, err := c.api. URL("/host-store/api/v1/hosts/search"). - Query(&filters). - Post(&searchObject, &result) + Query(params). + Post(&search, &hosts) - return result.Items, err + return hosts, err } -// Hosts returns existing hosts -func (store *HostStore) Hosts(offset, limit int, sortkey, sortdir, filter string) ([]Host, error) { - result := hostResult{} - filters := Params{ - Offset: offset, - Limit: limit, - Sortkey: sortkey, - Sortdir: sortdir, - Filter: filter, +// GetHosts get hosts. +func (c *HostStore) GetHosts(opts ...filters.Option) (*response.ResultSet[Host], error) { + hosts := &response.ResultSet[Host]{} + params := url.Values{} + + for _, opt := range opts { + opt(¶ms) } - _, err := store.api. + _, err := c.api. URL("/host-store/api/v1/hosts"). - Query(&filters). - Get(&result) + Query(params). + Get(&hosts) - return result.Items, err + return hosts, err } -// CreateHost create a host to host store -func (store *HostStore) CreateHost(host Host) (string, error) { - var object struct { - ID string `json:"id"` - } +// CreateHost create a host. +func (c *HostStore) CreateHost(host *Host) (response.Identifier, error) { + identifier := response.Identifier{} - _, err := store.api. + _, err := c.api. URL("/host-store/api/v1/hosts"). - Post(&host, &object) + Post(&host, &identifier) - return object.ID, err + return identifier, err } -// ResolveHost resolve service and address to a single host in host store -func (store *HostStore) ResolveHost(service Service) (*Host, error) { +// ResolveHost resolve service to a single host. +func (c *HostStore) ResolveHost(resolve HostResolve) (*Host, error) { host := &Host{} - _, err := store.api. + _, err := c.api. URL("/host-store/api/v1/hosts/resolve"). - Post(&service, &host) + Post(&resolve, &host) return host, err } -// Host returns existing single host -func (store *HostStore) Host(hostID string) (*Host, error) { +// GetHost get host by id. +func (c *HostStore) GetHost(hostID string) (*Host, error) { host := &Host{} - _, err := store.api. - URL("/host-store/api/v1/hosts/%s", url.PathEscape(hostID)). + _, err := c.api. + URL("/host-store/api/v1/hosts/%s", hostID). Get(&host) return host, err } -// UpdateHost update existing host -func (store *HostStore) UpdateHost(hostID string, host *Host) error { - _, err := store.api. - URL("/host-store/api/v1/hosts/%s", url.PathEscape(hostID)). - Put(host) +// UpdateHost update host. +func (c *HostStore) UpdateHost(hostID string, host *Host) error { + _, err := c.api. + URL("/host-store/api/v1/hosts/%s", hostID). + Put(&host) return err } -// DeleteHost delete a host -func (store *HostStore) DeleteHost(hostID string) error { - _, err := store.api. +// DeleteHost delete host. +func (c *HostStore) DeleteHost(hostID string) error { + _, err := c.api. URL("/host-store/api/v1/hosts/%s", hostID). Delete() return err } -// UpdateDeployStatus update host to be deployable or undeployable -func (store *HostStore) UpdateDeployStatus(hostID string, status bool) error { - deployStatus := Host{ - Deployable: status, - } +// DeployHost deploy host. +func (c *HostStore) DeployHost(host *Host) (HostResponse, error) { + response := HostResponse{} - _, err := store.api. - URL("/host-store/api/v1/hosts/%s/deployable", url.PathEscape(hostID)). - Put(deployStatus) + _, err := c.api. + URL("/host-store/api/v1/hosts/deploy"). + Post(&host, &response) + + return response, err +} + +// UpdateDeployStatus update host to be deployable or undeployable. +func (c *HostStore) UpdateDeployStatus(hostID string, deployable HostDeployable) error { + _, err := c.api. + URL("/host-store/api/v1/hosts/%s/deployable", hostID). + Put(&deployable) return err } -// HostTags returns host tags -func (store *HostStore) HostTags(offset, limit int, sortdir, query string) ([]string, error) { - result := tagsResult{} - filters := Params{ - Offset: offset, - Limit: limit, - Sortdir: sortdir, - Query: query, +// GetHostTags get host tags. +func (c *HostStore) GetHostTags(opts ...filters.Option) (*response.ResultSet[string], error) { + tags := &response.ResultSet[string]{} + params := url.Values{} + + for _, opt := range opts { + opt(¶ms) } - _, err := store.api. + _, err := c.api. URL("/host-store/api/v1/hosts/tags"). - Query(&filters). - Get(&result) + Query(params). + Get(&tags) - return result.Items, err + return tags, err } -// UpdateDisabledHostStatus enable/disable host -func (store *HostStore) UpdateDisabledHostStatus(hostID string, status bool) error { - disabledStatus := HostDisabledRequest{ - Disabled: status, - } - - _, err := store.api. - URL("/host-store/api/v1/hosts/%s/disabled", url.PathEscape(hostID)). - Put(disabledStatus) +// UpdateHostStatus enable/disable host. +func (c *HostStore) UpdateHostStatus(hostID string, disabled HostDisabled) error { + _, err := c.api. + URL("/host-store/api/v1/hosts/%s/disabled", hostID). + Put(disabled) return err } -// ServiceOptions returns default service options -func (store *HostStore) ServiceOptions() (*DefaultServiceOptions, error) { - options := &DefaultServiceOptions{} +// MARK: Settings +// GetServiceOptions get default service options. +func (c *HostStore) GetServiceOptions() (*HostServiceOptions, error) { + options := &HostServiceOptions{} - _, err := store.api. + _, err := c.api. URL("/host-store/api/v1/settings/default_service_options"). Get(&options) return options, err } + +// MARK: WhiteLists +// GetWhitelists get whitelists. +func (c *HostStore) GetWhitelists(opts ...filters.Option) (*response.ResultSet[Whitelist], error) { + result := &response.ResultSet[Whitelist]{} + params := url.Values{} + + for _, opt := range opts { + opt(¶ms) + } + _, err := c.api. + URL("/host-store/api/v1/whitelists"). + Query(params). + Get(&result) + + return result, err +} + +// CreateWhitelist create whitelist. +func (c *HostStore) CreateWhitelist(whitelist *Whitelist) (response.Identifier, error) { + identifier := response.Identifier{} + _, err := c.api. + URL("/host-store/api/v1/whitelists"). + Post(&whitelist, &identifier) + + return identifier, err +} + +// GetWhitelist get whitelist by id. +func (c *HostStore) GetWhitelist(whitelistID string) (*Whitelist, error) { + whitelist := &Whitelist{} + _, err := c.api. + URL("/host-store/api/v1/whitelists/%s", whitelistID). + Get(&whitelist) + + return whitelist, err +} + +// UpdateWhitelist update whitelist +func (c *HostStore) UpdateWhitelist(whitelist Whitelist, whitelistID string) error { + _, err := c.api. + URL("/host-store/api/v1/whitelists/%s", whitelistID). + Put(&whitelist) + + return err +} + +// DeleteWhitelist delete whitelist. +func (c *HostStore) DeleteWhitelist(whitelistID string) error { + _, err := c.api. + URL("/host-store/api/v1/whitelists/%s", whitelistID). + Delete() + + return err +} + +// SearchWhitelists search whitelists. +func (c *HostStore) SearchWhitelists(search WhitelistSearch, opts ...filters.Option) (*response.ResultSet[Whitelist], error) { + whitelists := &response.ResultSet[Whitelist]{} + params := url.Values{} + + for _, opt := range opts { + opt(¶ms) + } + + _, err := c.api. + URL("/host-store/api/v1/whitelists/search"). + Query(params). + Post(&search, &whitelists) + + return whitelists, err +} + +// EvaluateWhitelist evaluate commands against whitelist patterns. +func (c *HostStore) EvaluateWhitelist(evaluate *WhitelistEvaluate) (*WhitelistEvaluateResponse, error) { + result := &WhitelistEvaluateResponse{} + _, err := c.api. + URL("/host-store/api/v1/whitelists/evaluate"). + Post(&evaluate, &result) + + return result, err +} diff --git a/api/hoststore/model.go b/api/hoststore/model.go index 240c16a..a5eafde 100644 --- a/api/hoststore/model.go +++ b/api/hoststore/model.go @@ -6,236 +6,348 @@ package hoststore -import "github.com/SSHcom/privx-sdk-go/api/rolestore" +import ( + "time" -// Source of host objects -type Source string - -// Source constants -const ( - UI = Source("UI") - SCAN = Source("SCAN") -) - -// Address is fully qualified domain names, IPv4 or IPv6 addresses of the host -type Address string - -// Scheme of protocols allowed by the host -type Scheme string - -// Scheme constants, all supported protocols -const ( - SSH = Scheme("SSH") - RDP = Scheme("RDP") - VNC = Scheme("VNC") - WEB = Scheme("WEB") - DB = Scheme("DB") -) - -// DB protocols allowed by the host -type HostServiceDBProtocol string - -// DB protocols constants, all supported protocols -const ( - DBProtocolPostgres = HostServiceDBProtocol("postgres") - DBProtocolMySQL = HostServiceDBProtocol("mysql") - DBProtocolPassthrough = HostServiceDBProtocol("passthrough") - DBProtocolTLS = HostServiceDBProtocol("tls") -) - -// DBCertificateValidation of HostServiceDBParameters objects -type HostServiceDBCertificateValidation string - -// DBCertificateValidation Constants -const ( - DBCertificateValidationEnabled = HostServiceDBCertificateValidation("ENABLED") - DBCertificateValidationDisabled = HostServiceDBCertificateValidation("DISABLED") + "github.com/SSHcom/privx-sdk-go/api/rolestore" + "github.com/SSHcom/privx-sdk-go/api/secretsmanager" ) -// Params struct for pagination queries -type Params struct { - Offset int `json:"offset,omitempty"` - Limit int `json:"limit,omitempty"` - Sortdir string `json:"sortdir,omitempty"` - Sortkey string `json:"sortkey,omitempty"` - Filter string `json:"filter,omitempty"` - Query string `json:"query,omitempty"` -} - -// HostSearchObject host search object definition -type HostSearchObject struct { +// HostSearch host search request definition. +type HostSearch struct { ID string `json:"id,omitempty"` Keywords string `json:"keywords,omitempty"` + DistinguishedName []string `json:"distinguished_name,omitempty"` ExternalID string `json:"external_id,omitempty"` InstanceID string `json:"instance_id,omitempty"` SourceID string `json:"source_id,omitempty"` - Disabled string `json:"disabled,omitempty"` - Deployable bool `json:"deployable,omitempty"` - IgnoreDisabledSources bool `json:"ignore_disabled_sources,omitempty"` - Port []int `json:"port,omitempty"` CommonName []string `json:"common_name,omitempty"` Organization []string `json:"organization,omitempty"` OrganizationalUnit []string `json:"organizational_unit,omitempty"` Address []string `json:"address,omitempty"` Service []string `json:"service,omitempty"` + Port []int `json:"port,omitempty"` Zone []string `json:"zone,omitempty"` HostType []string `json:"host_type,omitempty"` HostClassification []string `json:"host_classification,omitempty"` Role []string `json:"role,omitempty"` Scope []string `json:"scope,omitempty"` + IgnoreDisabledSources bool `json:"ignore_disabled_sources,omitempty"` Tags []string `json:"tags,omitempty"` AccessGroupIDs []string `json:"access_group_ids,omitempty"` CloudProviders []string `json:"cloud_providers,omitempty"` CloudProviderRegions []string `json:"cloud_provider_regions,omitempty"` + Deployable bool `json:"deployable,omitempty"` Statuses []string `json:"statuses,omitempty"` - DistinguishedName []string `json:"distinguished_name,omitempty"` -} - -// HostDisabledRequest host disabled request definition -type HostDisabledRequest struct { - Disabled bool `json:"disabled"` + Disabled string `json:"disabled,omitempty"` } -// SessionRecordingOptions optional host options to disable session recording per feature +// SessionRecordingOptions optional host options to disable session recording per feature. type SessionRecordingOptions struct { DisableClipboardRecording bool `json:"disable_clipboard_recording"` DisableFileTransferRecording bool `json:"disable_file_transfer_recording"` } -// Service specify the service available on target host -type Service struct { - Scheme Scheme `json:"service"` - Address Address `json:"address"` - Port int `json:"port"` - DB HostServiceDBParameters `json:"db"` - Source Source `json:"source"` +// HostResponse host response definition. +type HostResponse struct { + ID string `json:"id"` + Action string `json:"action"` } -// Principal of the target host -type Principal struct { - ID string `json:"principal"` - Roles []rolestore.RoleRef `json:"roles"` - Source Source `json:"source"` - UseUserAccount bool `json:"use_user_account"` - Passphrase string `json:"passphrase"` - Applications []string `json:"applications"` +// HostResolve host resolve request definition. +type HostResolve struct { + Service string `json:"service"` + Address string `json:"address"` + Port int `json:"port"` +} + +// HostDeployable host deployable request definition. +type HostDeployable struct { + Deployable bool `json:"deployable"` +} + +// HostDisabled host disabled request definition. +type HostDisabled struct { + Disabled bool `json:"disabled"` +} + +// Whitelist whitelist definition. +type Whitelist struct { + ID string `json:"id"` + Name string `json:"name"` + Comment string `json:"comment,omitempty"` + Type string `json:"type"` + WhiteListPatterns []string `json:"whitelist_patterns,omitempty"` + Author string `json:"author"` + Created string `json:"created"` + UpdatedBy string `json:"updated_by,omitempty"` + Updated string `json:"updated,omitempty"` +} + +// WhitelistSearch whitelist search request definition. +type WhitelistSearch struct { + Keywords string `json:"keywords"` +} + +// WhitelistEvaluate whitelist evaluate request definition. +type WhitelistEvaluate struct { + WhiteList Whitelist `json:"whitelist"` + RShellVariant string `json:"rshell_variant"` + Commands []string `json:"commands"` +} + +// WhitelistEvaluateResponse white list evaluate response definition. +type WhitelistEvaluateResponse struct { + WhiteListPatternResults []WhitelistPatternResult `json:"whitelist_pattern_results"` + CommandResults []CommandResult `json:"command_results"` +} + +// CommandResult command result definition. +type CommandResult struct { + Command string `json:"command"` + Allowed bool `json:"allowed"` } -// SSHPublicKey host public keys -type SSHPublicKey struct { - Key string `json:"key,omitempty"` - Fingerprint string `json:"fingerprint,omitempty"` +// WhitelistPatternResult whitelist pattern result definition. +type WhitelistPatternResult struct { + WhiteListPattern string `json:"whitelist_pattern"` + Status []string `json:"status"` } -// Status of the secret object -type Status struct { - K string `json:"k,omitempty"` - V string `json:"v,omitempty"` +// Principal of the target host +type Principal struct { + ID string `json:"principal"` + Roles []rolestore.RoleHandle `json:"roles"` + Source string `json:"source"` + UseUserAccount bool `json:"use_user_account"` + Passphrase string `json:"passphrase"` + Applications []string `json:"applications"` } // Host defines PrivX target type Host struct { - ID string `json:"id,omitempty"` - AccessGroupID string `json:"access_group_id,omitempty"` - ExternalID string `json:"external_id,omitempty"` - InstanceID string `json:"instance_id,omitempty"` - SourceID string `json:"source_id,omitempty"` - Name string `json:"common_name,omitempty"` - ContactAdress string `json:"contact_address,omitempty"` - CloudProvider string `json:"cloud_provider,omitempty"` - CloudProviderRegion string `json:"cloud_provider_region,omitempty"` - Created string `json:"created,omitempty"` - Updated string `json:"updated,omitempty"` - UpdatedBy string `json:"updated_by,omitempty"` - DistinguishedName string `json:"distinguished_name,omitempty"` - Organization string `json:"organization,omitempty"` - OrganizationUnit string `json:"organizational_unit,omitempty"` - Zone string `json:"zone,omitempty"` - HostType string `json:"host_type,omitempty"` - HostClassification string `json:"host_classification,omitempty"` - Comment string `json:"comment,omitempty"` - Disabled string `json:"disabled,omitempty"` - Deployable bool `json:"deployable,omitempty"` - Tofu bool `json:"tofu,omitempty"` - StandAlone bool `json:"stand_alone_host,omitempty"` - Audit bool `json:"audit_enabled,omitempty"` - Scope []string `json:"scope,omitempty"` - Tags []string `json:"tags,omitempty"` - Addresses []Address `json:"addresses,omitempty"` - Services []Service `json:"services,omitempty"` - Principals []Principal `json:"principals,omitempty"` - PublicKeys []SSHPublicKey `json:"ssh_host_public_keys,omitempty"` - Status []Status `json:"status,omitempty"` - SessionRecordingOptions *SessionRecordingOptions `json:"session_recording_options,omitempty"` + ID string `json:"id"` + Deployable *bool `json:"deployable"` + Tofu *bool `json:"tofu"` + StandAloneHost bool `json:"stand_alone_host"` + ExternalID string `json:"external_id"` + InstanceID string `json:"instance_id"` + SSHHostPubKeys []HostSSHPubKeys `json:"ssh_host_public_keys"` + HostCertificateRaw string `json:"host_certificate_raw"` + HostCertificate *HostCertificateInfo `json:"host_certificate"` + ContactAddress string `json:"contact_address"` + PasswordRotationEnabled bool `json:"password_rotation_enabled"` + Services []HostService `json:"services"` + Principals []HostPrincipals `json:"principals"` + PasswordRotation *RotationMetadata `json:"password_rotation,omitempty"` + SourceID string `json:"source_id"` + AccessGroupID string `json:"access_group_id"` + CloudProvider string `json:"cloud_provider"` + CloudProviderRegion string `json:"cloud_provider_region"` + Status []HostStatus `json:"status"` + Created string `json:"created"` + Updated string `json:"updated" diff:"-"` + UpdatedBy string `json:"updated_by"` + DistinguishedName string `json:"distinguished_name"` + CommonName string `json:"common_name"` + Organization string `json:"organization"` + OrganizationalUnit string `json:"organizational_unit"` + Zone string `json:"zone"` + Scope []string `json:"scope"` + HostType string `json:"host_type"` + HostClassification string `json:"host_classification"` + Comment string `json:"comment"` + Addresses []string `json:"addresses"` + AuditEnabled *bool `json:"audit_enabled"` + Tags []string `json:"tags"` + UserMessage string `json:"user_message"` + Disabled string `json:"disabled"` + SessionRecordingOptions *SessionRecordingOptions `json:"session_recording_options"` + Deleted bool `json:"deleted,omitempty"` } -type HostServiceDBParameters struct { - Protocol HostServiceDBProtocol `json:"protocol"` - TLSCertificateValidation HostServiceDBCertificateValidation `json:"tls_certificate_validation"` - TLSCertificateTrustAnchors string `json:"tls_certificate_trust_anchors"` - AuditSkipBytes int64 `json:"audit_skip_bytes"` +type HostStatus struct { + Key string `json:"k"` + Value string `json:"v"` } -// SSHService default options -type SSHService struct { - Shell bool `json:"shell"` +type RotationMetadata struct { + AccessGroupID string `json:"access_group_id"` + UseMainAccount bool `json:"use_main_account"` + OperatingSystem string `json:"operating_system"` + WinrmAddress string `json:"winrm_address"` + WinrmPort int `json:"winrm_port,omitempty"` + CertificateValidationOptions string `json:"certificate_validation_options"` + WinRMHostCertificateTrustAnchors string `json:"winrm_host_certificate_trust_anchors"` + Protocol string `json:"protocol"` + RotationStatus []RotationStatusItem `json:"rotation_status,omitempty"` + PasswordPolicyId string `json:"password_policy_id"` + ScriptTemplateId string `json:"script_template_id"` + Created *time.Time `json:"created,omitempty"` + Updated *time.Time `json:"updated,omitempty"` + CreatedBy string `json:"created_by,omitempty"` + UpdatedBy string `json:"updated_by,omitempty"` +} + +type RotationStatusItem struct { + Account string `json:"principal"` + LastRotated *time.Time `json:"last_rotated"` + LastError *time.Time `json:"last_error"` + LastErrorDetails string `json:"last_error_details"` +} + +type HostPrincipals struct { + Principal string `json:"principal"` + TargetDomain *secretsmanager.TargetDomainHandle `json:"target_domain,omitempty"` + Passphrase string `json:"passphrase"` + Rotate bool `json:"rotate"` + UseForPasswordRotation bool `json:"use_for_password_rotation"` + UsernameAttribute string `json:"username_attribute"` + UseUserAccount bool `json:"use_user_account"` + Source string `json:"source"` + Roles []HostRole `json:"roles"` + Applications []HostPrincipalApplications `json:"applications"` + ServiceOptions *HostServiceOptions `json:"service_options,omitempty"` + CommandRestrictions HostCommandRestrictions `json:"command_restrictions,omitempty"` +} + +type HostCommandRestrictions struct { + Enabled bool `json:"enabled"` + RShellVariant string `json:"rshell_variant,omitempty"` + DefaultWhiteList WhiteListHandle `json:"default_whitelist"` + WhiteLists []WhiteListGrant `json:"whitelists"` + AllowNoMatch bool `json:"allow_no_match,omitempty"` + AuditMatch bool `json:"audit_match,omitempty"` + AuditNoMatch bool `json:"audit_no_match,omitempty"` + Banner string `json:"banner,omitempty"` +} + +type WhiteListGrant struct { + WhiteList WhiteListHandle `json:"whitelist"` + Roles []HostRole `json:"roles"` +} + +type HostRole struct { + ID string `json:"id"` + Name string `json:"name"` + Deleted bool `json:"deleted,omitempty"` +} + +type WhiteListHandle struct { + ID string `json:"id,omitempty"` + Name string `json:"name,omitempty"` + Deleted bool `json:"deleted,omitempty"` +} + +type HostServiceOptions struct { + SSHServiceOptions *SSHServiceOptions `json:"ssh,omitempty"` + RDPServiceOptions *RDPServiceOptions `json:"rdp,omitempty"` + WebServiceOptions *WebServiceOptions `json:"web,omitempty"` + VNCServiceOptions *VNCServiceOptions `json:"vnc,omitempty"` + DBServiceOptions *DBServiceOptions `json:"db,omitempty"` +} + +type DBServiceOptions struct { + MaxBytesUpload int64 `json:"max_bytes_upload,omitempty"` + MaxBytesDownload int64 `json:"max_bytes_download,omitempty"` +} + +type VNCServiceOptions struct { FileTransfer bool `json:"file_transfer"` - Exec bool `json:"exec"` - Tunnels bool `json:"tunnels"` - Xeleven bool `json:"x11"` - Other bool `json:"other"` + Clipboard bool `json:"clipboard"` } -// RDPService default options -type RDPService struct { +type WebServiceOptions struct { FileTransfer bool `json:"file_transfer"` Audio bool `json:"audio"` Clipboard bool `json:"clipboard"` } -// WebService default options -type WebService struct { +type RDPServiceOptions struct { FileTransfer bool `json:"file_transfer"` Audio bool `json:"audio"` Clipboard bool `json:"clipboard"` } -type VNCService struct { +type SSHServiceOptions struct { + Shell bool `json:"shell"` FileTransfer bool `json:"file_transfer"` - Clipboard bool `json:"clipboard"` + Exec bool `json:"exec"` + Tunnels bool `json:"tunnels"` + X11 bool `json:"x11"` + Other bool `json:"other"` } -type DBService struct { - MaxBytesUpload int64 `json:"max_bytes_upload"` - MaxBytesDownload int64 `json:"max_bytes_download"` +type HostPrincipalApplications struct { + Name string `json:"name,omitempty"` + Application string `json:"application,omitempty"` + Arguments string `json:"arguments,omitempty"` + WorkingDirectory string `json:"working_directory,omitempty"` } -// DefaultServiceOptions default service options -type DefaultServiceOptions struct { - SSH SSHService `json:"ssh"` - RDP RDPService `json:"rdp"` - Web WebService `json:"web"` - VNC VNCService `json:"vnc"` - DB DBService `json:"db"` +type HostService struct { + Service string `json:"service"` + Address string `json:"address"` + Port int `json:"port"` + UseForPasswordRotation bool `json:"use_for_password_rotation"` + TunnelPort int `json:"ssh_tunnel_port"` + UsePlainTextVNC bool `json:"use_plaintext_vnc"` + Source string `json:"source"` + Realm string `json:"realm,omitempty"` + LoginPageURL string `json:"login_page_url"` + UsernameFieldName string `json:"username_field_name"` + PasswordFieldName string `json:"password_field_name"` + LoginRequestUrl string `json:"login_request_url"` + LoginRequestPasswordProperty string `json:"login_request_password_property"` + AuthType string `json:"auth_type"` + HealthCheckStatus string `json:"status"` + HealthCheckStatusUpdated string `json:"status_updated"` + AllowedDomains []string `json:"allowed_domains"` + Browser string `json:"browser"` + BrowserKioskMode bool `json:"kiosk_mode"` + BrowserUrlBar bool `json:"enable_urlbar"` + BrowserNaviBar bool `json:"enable_navibar"` + BrowserNaviBarAutoHide bool `json:"autohide_navibar"` + BrowserDevTools bool `json:"enable_devtools"` + BrowserPopups bool `json:"enable_popups"` + BrowserWebCompatibleMode bool `json:"enable_web_compatibility_mode"` + BrowserTimeZone string `json:"timezone"` + WebIdleTimeLimit int `json:"idle_time_limit"` + ServiceVersion string `json:"service_version"` + Created time.Time `json:"created"` + Updated time.Time `json:"updated"` + CertificateTemplate string `json:"certificate_template"` + AllowModifiedWebParams bool `json:"allow_modified_web_params"` + ProtocolVersion string `json:"protocol_version,omitempty"` + Latency int `json:"latency_in_microseconds,omitempty"` + DB HostServiceDBParameters `json:"db"` + UseLegacyCipherSuites bool `json:"use_legacy_cipher_suites"` + TLSMinVersion string `json:"tls_min_version"` + TLSMaxVersion string `json:"tls_max_version"` } -// Service creates a corresponding service definition -// -// hosts.SSH.Service(...) -func (scheme Scheme) Service(addr Address, port int) Service { - return Service{ - Scheme: scheme, - Address: addr, - Port: port, - Source: UI, - } -} - -// NewPrincipal creates a corresponding definition from roles -func NewPrincipal(id string, role ...rolestore.RoleRef) Principal { - return Principal{ - ID: id, - Roles: role, - Source: UI, - } +type HostSSHPubKeys struct { + Key string `json:"key"` + FingerPrint string `json:"fingerprint"` +} + +type HostServiceDBParameters struct { + Protocol string `json:"protocol"` + TLSCertificateValidation string `json:"tls_certificate_validation"` + TLSCertificateTrustAnchors string `json:"tls_certificate_trust_anchors"` + AuditSkipBytes int64 `json:"audit_skip_bytes"` +} + +type HostCertificateInfo struct { + Subject string `json:"subject,omitempty"` + Issuer string `json:"issuer,omitempty"` + Serial string `json:"serial,omitempty"` + NotBefore string `json:"not_before,omitempty"` + NotAfter string `json:"not_after,omitempty"` + DNSNames []string `json:"dns_names,omitempty"` + EmailAddresses []string `json:"email_addresses,omitempty"` + IPAddresses []string `json:"ip_addresses,omitempty"` + URIs []string `json:"uris,omitempty"` + FingerPrintSHA1 string `json:"fingerprint_sha1,omitempty"` + FingerPrintSHA256 string `json:"fingerprint_sha256,omitempty"` } diff --git a/api/rolestore/client.go b/api/rolestore/client.go index 15d35d4..dcf9fd7 100644 --- a/api/rolestore/client.go +++ b/api/rolestore/client.go @@ -9,8 +9,9 @@ package rolestore import ( "encoding/json" "net/url" - "strings" + "github.com/SSHcom/privx-sdk-go/api/filters" + "github.com/SSHcom/privx-sdk-go/api/response" "github.com/SSHcom/privx-sdk-go/restapi" ) @@ -19,734 +20,732 @@ type RoleStore struct { api restapi.Connector } -type usersResult struct { - Count int `json:"count"` - Items []User `json:"items"` -} - -type rolesResult struct { - Count int `json:"count"` - Items []Role `json:"items"` -} - -type sourcesResult struct { - Count int `json:"count"` - Items []Source `json:"items"` -} - -type awsrolesResult struct { - Count int `json:"count"` - Items []AWSRoleLink `json:"items"` +// New role store client constructor. +func New(api restapi.Connector) *RoleStore { + return &RoleStore{api: api} } -type awsTokenResult struct { - Count int `json:"count"` - Items []AWSToken `json:"items"` -} +// MARK: Status +// Status get role store microservice status. +func (c *RoleStore) Status() (*response.ServiceStatus, error) { + status := &response.ServiceStatus{} -type principalkeysResult struct { - Count int `json:"count"` - Items []PrincipalKey `json:"items"` -} + _, err := c.api. + URL("/role-store/api/v1/status"). + Get(status) -type authorizedkeysResult struct { - Count int `json:"count"` - Items []AuthorizedKey `json:"items"` + return status, err } -type collectorsResult struct { - Count int `json:"count"` - Items []LogconfCollector `json:"items"` -} +// MARK: Sources +// GetSources get sources. +func (c *RoleStore) GetSources() (*response.ResultSet[Source], error) { + sources := &response.ResultSet[Source]{} -// New creates a new role-store client instance, using the -// argument SDK API client. -func New(api restapi.Connector) *RoleStore { - return &RoleStore{api: api} -} - -// Sources get all sources. -func (store *RoleStore) Sources() ([]Source, error) { - result := sourcesResult{} - - _, err := store.api. + _, err := c.api. URL("/role-store/api/v1/sources"). - Get(&result) + Get(&sources) - return result.Items, err + return sources, err } -// CreateSource create a new source -func (store *RoleStore) CreateSource(source Source) (string, error) { - var object struct { - ID string `json:"id"` - } +// CreateSource create source. +func (c *RoleStore) CreateSource(source *Source) (response.Identifier, error) { + identifier := response.Identifier{} - _, err := store.api. + _, err := c.api. URL("/role-store/api/v1/sources"). - Post(&source, &object) + Post(&source, &identifier) - return object.ID, err + return identifier, err } -// Source returns a source -func (store *RoleStore) Source(sourceID string) (*Source, error) { +// GetSource get source by id. +func (c *RoleStore) GetSource(sourceID string) (*Source, error) { source := &Source{} - _, err := store.api. - URL("/role-store/api/v1/sources/%s", url.PathEscape(sourceID)). - Get(source) + _, err := c.api. + URL("/role-store/api/v1/sources/%s", sourceID). + Get(&source) return source, err } -// DeleteSource delete a source -func (store *RoleStore) DeleteSource(sourceID string) error { - _, err := store.api. +// UpdateSource update source. +func (c *RoleStore) UpdateSource(sourceID string, source *Source) error { + _, err := c.api. URL("/role-store/api/v1/sources/%s", sourceID). - Delete() + Put(&source) return err } -// UpdateSource update existing source -func (store *RoleStore) UpdateSource(sourceID string, source *Source) error { - _, err := store.api. - URL("/role-store/api/v1/sources/%s", url.PathEscape(sourceID)). - Put(source) +// DeleteSource delete source. +func (c *RoleStore) DeleteSource(sourceID string) error { + _, err := c.api. + URL("/role-store/api/v1/sources/%s", sourceID). + Delete() return err } -// RefreshSources refresh all host and user sources -func (store *RoleStore) RefreshSources(sourceIDs []string) error { - _, err := store.api. +// RefreshSources refresh sources. +func (c *RoleStore) RefreshSources(sourceIDs []string) error { + _, err := c.api. URL("/role-store/api/v1/sources/refresh"). Post(&sourceIDs) return err } -// AWSRoleLinks returns all aws roles. -func (store *RoleStore) AWSRoleLinks(refresh bool) ([]AWSRoleLink, error) { - result := awsrolesResult{} - filters := Params{ - Refresh: refresh, +// MARK: AWS Roles +// GetAWSRoles get AWS roles. +func (c *RoleStore) GetAWSRoles(opts ...filters.Option) (*response.ResultSet[AWSRole], error) { + roles := &response.ResultSet[AWSRole]{} + params := url.Values{} + + for _, opt := range opts { + opt(¶ms) } - _, err := store.api. + _, err := c.api. URL("/role-store/api/v1/awsroles"). - Query(&filters). - Get(&result) + Query(params). + Get(&roles) - return result.Items, err + return roles, err } -// AWSRoleLink returns existing single aws role -func (store *RoleStore) AWSRoleLink(awsroleID string) (*AWSRoleLink, error) { - role := &AWSRoleLink{} +// GetAWSRole get AWS role by id. +func (c *RoleStore) GetAWSRole(awsRoleID string) (*AWSRole, error) { + role := &AWSRole{} - _, err := store.api. - URL("/role-store/api/v1/awsroles/%s", url.PathEscape(awsroleID)). + _, err := c.api. + URL("/role-store/api/v1/awsroles/%s", awsRoleID). Get(role) return role, err } -// DeleteAWSRoleLInk delete a aws role -func (store *RoleStore) DeleteAWSRoleLInk(awsroleID string) error { - _, err := store.api. - URL("/role-store/api/v1/awsroles/%s", awsroleID). +// DeleteAWSRole delete AWS role. +func (c *RoleStore) DeleteAWSRole(awsRoleID string) error { + _, err := c.api. + URL("/role-store/api/v1/awsroles/%s", awsRoleID). Delete() return err } -// UpdateAWSRoleLink update existing aws role -func (store *RoleStore) UpdateAWSRoleLink(awsRoleID string, roles []RoleRef) error { - _, err := store.api. - URL("/role-store/api/v1/awsroles/%s/roles", url.PathEscape(awsRoleID)). +// GetLinkedRoles get AWS role granting PrivX roles. +func (c *RoleStore) GetLinkedRoles(awsRoleID string) (*response.ResultSet[AWSRole], error) { + roles := &response.ResultSet[AWSRole]{} + + _, err := c.api. + URL("/role-store/api/v1/awsroles/%s/roles", awsRoleID). + Get(&roles) + + return roles, err +} + +// UpdateAWSRole update AWS role granting PrivX roles. +func (c *RoleStore) UpdateAWSRole(awsRoleID string, roles []LinkedPrivXRole) error { + _, err := c.api. + URL("/role-store/api/v1/awsroles/%s/roles", awsRoleID). Put(&roles) return err } -// LinkedRoles return AWS role granting PrivX roles -func (store *RoleStore) LinkedRoles(awsroleID string) ([]AWSRoleLink, error) { - result := awsrolesResult{} +// MARK: Users +// GetUser get user by id. +func (c *RoleStore) GetUser(userID string) (*User, error) { + user := &User{} - _, err := store.api. - URL("/role-store/api/v1/awsroles/%s/roles", url.PathEscape(awsroleID)). - Get(&result) + _, err := c.api. + URL("/role-store/api/v1/users/%s", userID). + Get(user) - return result.Items, err + return user, err } -// Roles gets all configured roles. -func (store *RoleStore) Roles(offset, limit int, sortkey, sortdir string) ([]Role, error) { - result := rolesResult{} - - filters := Params{ - Offset: offset, - Limit: limit, - Sortkey: sortkey, - Sortdir: sortdir, - } +// GetUserSettings get user settings. +func (c *RoleStore) GetUserSettings(userID string) (*json.RawMessage, error) { + settings := &json.RawMessage{} - _, err := store.api. - URL("/role-store/api/v1/roles").Query(filters).Get(&result) + _, err := c.api. + URL("/role-store/api/v1/users/%s/settings", userID). + Get(&settings) - return result.Items, err + return settings, err } -// CreateRole creates new role -func (store *RoleStore) CreateRole(role Role) (string, error) { - var object struct { - ID string `json:"id"` - } +// UpdateUserSettings update specific user's settings +func (c *RoleStore) UpdateUserSettings(userID string, settings *UserSettings) error { + _, err := c.api. + URL("/role-store/api/v1/users/%s/settings", userID). + Put(&settings) - _, err := store.api. - URL("/role-store/api/v1/roles"). - Post(&role, &object) + return err +} + +// GetUserRoles get roles of user by id. +func (c *RoleStore) GetUserRoles(userID string) (*response.ResultSet[Role], error) { + roles := &response.ResultSet[Role]{} + _, err := c.api. + URL("/role-store/api/v1/users/%s/roles", userID). + Get(&roles) - return object.ID, err + return roles, err } -// ResolveRoles searches give role name and returns corresponding ids -func (store *RoleStore) ResolveRoles(names []string) ([]RoleRef, error) { - var result struct { - Count int `json:"count"` - Items []RoleRef `json:"items"` - } +// UpdateUserRoles update user roles by id. +func (c *RoleStore) UpdateUserRoles(userID string, roles []Role) error { + _, err := c.api. + URL("/role-store/api/v1/users/%s/roles", userID). + Put(roles) - _, err := store.api. - URL("/role-store/api/v1/roles/resolve"). - Post(&names, &result) + return err +} - return result.Items, err +// SetMFA enable, disable or reset mfa authentication. +func (c *RoleStore) SetMFA(userIDs []string, action string) error { + _, err := c.api. + URL("/role-store/api/v1/users/mfa/%s", action). + Post(&userIDs) + + return err } -// EvaluateRole evaluate a new role definition -func (store *RoleStore) EvaluateRole(role *Role) ([]User, error) { - var result struct { - Count int `json:"count"` - Items []User `json:"items"` - } +// GetCurrentUserAndSettings get current user and user settings. +func (c *RoleStore) GetCurrentUserAndSettings() (*json.RawMessage, error) { + current := &json.RawMessage{} - _, err := store.api. - URL("/role-store/api/v1/roles/evaluate"). - Post(role, &result) + _, err := c.api. + URL("/role-store/api/v1/users/current"). + Get(¤t) - return result.Items, err + return current, err } -// Role gets information about the argument role ID. -func (store *RoleStore) Role(roleID string) (*Role, error) { - role := &Role{} +// GetCurrentUserSettings get current user AWS roles. +func (c *RoleStore) GetCurrentAWSRoles() (*response.ResultSet[AWSRole], error) { + roles := &response.ResultSet[AWSRole]{} - _, err := store.api. - URL("/role-store/api/v1/roles/%s", url.PathEscape(roleID)). - Get(role) + _, err := c.api. + URL("/role-store/api/v1/users/current/awsroles"). + Get(&roles) - return role, err + return roles, err } -// DeleteRole delete a role -func (store *RoleStore) DeleteRole(roleID string) error { - _, err := store.api. - URL("/role-store/api/v1/roles/%s", roleID). - Delete() +// GetCurrentUserAndSettings get current user settings. +func (c *RoleStore) GetCurrentUserSettings() (*json.RawMessage, error) { + settings := &json.RawMessage{} - return err + _, err := c.api. + URL("/role-store/api/v1/users/current/settings"). + Get(&settings) + + return settings, err } -// UpdateRole update existing role -func (store *RoleStore) UpdateRole(roleID string, role *Role) error { - _, err := store.api. - URL("/role-store/api/v1/roles/%s", url.PathEscape(roleID)). - Put(role) +// UpdateCurrentUserSettings update current user settings. +func (c *RoleStore) UpdateCurrentUserSettings(settings *UserSettings) error { + _, err := c.api. + URL("/role-store/api/v1/users/current/settings"). + Put(&settings) return err } -// GetRoleMembers gets all members (users) of the argument role ID. -func (store *RoleStore) GetRoleMembers(roleID string, offset, limit int, sortkey, sortdir string) ([]User, error) { - result := usersResult{} - filters := Params{ - Offset: offset, - Limit: limit, - Sortkey: sortkey, - Sortdir: sortdir, - } +// ResolveUserRoles resolve user roles. +func (c *RoleStore) ResolveUserRoles(userID string) (*User, error) { + user := &User{} - _, err := store.api. - URL("/role-store/api/v1/roles/%s/members", url.PathEscape(roleID)). - Query(&filters). - Get(&result) + _, err := c.api. + URL("/role-store/api/v1/users/%s/resolve", userID). + Get(&user) - return result.Items, err + return user, err } -// AWSToken returns AWS token for a specified role -func (store *RoleStore) AWSToken(roleID, tokencode string, ttl int) ([]AWSToken, error) { - result := awsTokenResult{} - filters := Params{ - Tokencode: tokencode, - TTL: ttl, +// SearchUsers search users. +func (c *RoleStore) SearchUsers(search UserSearch, opts ...filters.Option) (*response.ResultSet[User], error) { + users := &response.ResultSet[User]{} + params := url.Values{} + + for _, opt := range opts { + opt(¶ms) } - _, err := store.api. - URL("/role-store/api/v1/roles/%s/awstoken", url.PathEscape(roleID)). - Query(&filters). - Get(&result) + _, err := c.api. + URL("/role-store/api/v1/users/search"). + Query(params). + Post(&search, &users) - return result.Items, err + return users, err } -// PrincipalKeys returns all principal keys -func (store *RoleStore) PrincipalKeys(roleID string) ([]PrincipalKey, error) { - result := principalkeysResult{} +// SearchExternalUsers search external users. +func (c *RoleStore) SearchExternalUsers(search UserSearch) (*response.ResultSet[User], error) { + users := &response.ResultSet[User]{} - _, err := store.api. - URL("/role-store/api/v1/roles/%s/principalkeys", url.PathEscape(roleID)). - Get(&result) + _, err := c.api. + URL("/role-store/api/v1/users/search/external"). + Post(&search, &users) - return result.Items, err + return users, err } -// GeneratePrincipalKey generate new principal key for existing role -func (store *RoleStore) GeneratePrincipalKey(roleID string) (string, error) { - var object struct { - ID string `json:"id"` +// GetUsersAuthorizedKeys get users authorized keys. +func (c *RoleStore) GetUsersAuthorizedKeys(userID string, opts ...filters.Option) (*response.ResultSet[AuthorizedKey], error) { + keys := &response.ResultSet[AuthorizedKey]{} + params := url.Values{} + + for _, opt := range opts { + opt(¶ms) } - _, err := store.api. - URL("/role-store/api/v1/roles/%s/principalkeys/generate", url.PathEscape(roleID)). - Post(nil, &object) + _, err := c.api. + URL("/role-store/api/v1/users/%s/authorizedkeys", userID). + Query(params). + Get(&keys) - return object.ID, err + return keys, err } -// ImportPrincipalKey import new principal key for existing role -func (store *RoleStore) ImportPrincipalKey(key PrivateKey, roleID string) (string, error) { - var object struct { - ID string `json:"id"` - } +// CreateAuthorizedKey create authorized key for user. +func (c *RoleStore) CreateAuthorizedKey(userID string, key *AuthorizedKey) (response.Identifier, error) { + identifier := response.Identifier{} - _, err := store.api. - URL("/role-store/api/v1/roles/%s/principalkeys/import", url.PathEscape(roleID)). - Post(&key, &object) + _, err := c.api. + URL("/role-store/api/v1/users/%s/authorizedkeys", userID). + Post(&key, &identifier) - return object.ID, err + return identifier, err } -// PrincipalKey returns a role's principal key object. -func (store *RoleStore) PrincipalKey(roleID, keyID string) (*PrincipalKey, error) { - key := &PrincipalKey{} +// GetUsersAuthorizedKey get users authorized key by id. +func (c *RoleStore) GetUsersAuthorizedKey(userID, keyID string) (*AuthorizedKey, error) { + key := &AuthorizedKey{} - _, err := store.api. - URL("/role-store/api/v1/roles/%s/principalkeys/%s", url.PathEscape(roleID), url.PathEscape(keyID)). - Get(key) + _, err := c.api. + URL("/role-store/api/v1/users/%s/authorizedkeys/%s", userID, keyID). + Get(&key) return key, err } -// DeletePrincipalKey delete a role's principal key -func (store *RoleStore) DeletePrincipalKey(roleID, keyID string) error { - _, err := store.api. - URL("/role-store/api/v1/roles/%s/principalkeys/%s", roleID, keyID). +// UpdateUsersAuthorizedKey update users authorized key. +func (c *RoleStore) UpdateUsersAuthorizedKey(userID, keyID string, key *AuthorizedKey) error { + _, err := c.api. + URL("/role-store/api/v1/users/%s/authorizedkeys/%s", userID, keyID). + Put(&key) + + return err +} + +// DeleteUsersAuthorizedKey delete a users authorized key. +func (c *RoleStore) DeleteUsersAuthorizedKey(userID, keyID string) error { + _, err := c.api. + URL("/role-store/api/v1/users/%s/authorizedkeys/%s", userID, keyID). Delete() return err } -// User gets information about the argument user ID. -func (store *RoleStore) User(userID string) (*User, error) { - user := &User{} +// GetCurrentUsersAuthorizedKeys get current users authorized keys. +func (c *RoleStore) GetCurrentUsersAuthorizedKeys(opts ...filters.Option) (*response.ResultSet[AuthorizedKey], error) { + keys := &response.ResultSet[AuthorizedKey]{} + params := url.Values{} - _, err := store.api. - URL("/role-store/api/v1/users/%s", url.PathEscape(userID)). - Get(user) + for _, opt := range opts { + opt(¶ms) + } - return user, err + _, err := c.api. + URL("/role-store/api/v1/users/current/authorizedkeys"). + Query(params). + Get(&keys) + + return keys, err } -// UserSettings get specific user settings -func (store *RoleStore) UserSettings(userID string) (*json.RawMessage, error) { - settings := &json.RawMessage{} +// CreateAuthorizedKeyCurrentUser create authorized key for current user. +func (c *RoleStore) CreateAuthorizedKeyCurrentUser(key *AuthorizedKey) (response.Identifier, error) { + identifier := response.Identifier{} - _, err := store.api. - URL("/role-store/api/v1/users/%s/settings", url.PathEscape(userID)). - Get(&settings) + _, err := c.api. + URL("/role-store/api/v1/users/current/authorizedkeys"). + Post(&key, &identifier) - return settings, err + return identifier, err } -// UpdateUserSettings update specific user's settings -func (store *RoleStore) UpdateUserSettings(settings *json.RawMessage, userID string) error { - _, err := store.api. - URL("/role-store/api/v1/users/%s/settings", url.PathEscape(userID)). - Put(settings) +// GetCurrentUsersAuthorizedKey get current users authorized key by id. +func (c *RoleStore) GetCurrentUsersAuthorizedKey(keyID string) (*AuthorizedKey, error) { + key := &AuthorizedKey{} + + _, err := c.api. + URL("/role-store/api/v1/users/current/authorizedkeys/%s", keyID). + Get(&key) + + return key, err +} + +// UpdateCurrentUsersAuthorizedKey update current users authorized key. +func (c *RoleStore) UpdateCurrentUsersAuthorizedKey(keyID string, key *AuthorizedKey) error { + _, err := c.api. + URL("/role-store/api/v1/users/current/authorizedkeys/%s", keyID). + Put(&key) return err } -// UserRoles gets the roles of the argument user ID. -func (store *RoleStore) UserRoles(userID string) ([]Role, error) { - result := rolesResult{} - _, err := store.api. - URL("/role-store/api/v1/users/%s/roles", url.PathEscape(userID)). - Get(&result) +// DeleteCurrentUsersAuthorizedKey delete current a users authorized key. +func (c *RoleStore) DeleteCurrentUsersAuthorizedKey(keyID string) error { + _, err := c.api. + URL("/role-store/api/v1/users/current/authorizedkeys/%s", keyID). + Delete() - return result.Items, err + return err } -// GrantUserRole adds the specified role for the user. If the user -// already has the role, this function does nothing. -func (store *RoleStore) GrantUserRole(userID, roleID string) error { - // Get user's current roles. - roles, err := store.UserRoles(userID) - if err != nil { - return err - } - // Does user already have the specified role? - for _, role := range roles { - if role.ID == roleID { - // Already granted. - return nil - } - } +// GetRoles get roles. +func (c *RoleStore) GetRoles(opts ...filters.Option) (*response.ResultSet[Role], error) { + roles := &response.ResultSet[Role]{} + params := url.Values{} - // Get new role. - role, err := store.Role(roleID) - if err != nil { - return err + for _, opt := range opts { + opt(¶ms) } - // Add an explicit role grant request. - roles = append(roles, Role{ - ID: role.ID, - Explicit: true, - }) + _, err := c.api. + URL("/role-store/api/v1/roles"). + Query(params). + Get(&roles) - return store.setUserRoles(userID, roles) + return roles, err } -// RevokeUserRole removes the specified role from the user. If the -// user does not have the role, this function does nothing. -func (store *RoleStore) RevokeUserRole(userID, roleID string) error { - // Get user's current roles. - roles, err := store.UserRoles(userID) - if err != nil { - return err - } - // Remove role from user's roles. - var newRoles []Role - for _, role := range roles { - if role.ID != roleID { - newRoles = append(newRoles, role) - } - } - if len(newRoles) == len(roles) { - // User did not have the specified role. - return nil +// CreateRole creates role. +func (c *RoleStore) CreateRole(role *Role) (response.Identifier, error) { + identifier := response.Identifier{} + + _, err := c.api. + URL("/role-store/api/v1/roles"). + Post(&role, &identifier) + + return identifier, err +} + +// ResolveRoles resolve role names to role. +func (c *RoleStore) ResolveRoles(names []string) (*response.ResultSet[Role], error) { + roles := &response.ResultSet[Role]{} + + _, err := c.api. + URL("/role-store/api/v1/roles/resolve"). + Post(&names, &roles) + + return roles, err +} + +// SearchRoles search roles. +func (c *RoleStore) SearchRoles(search RoleSearch, opts ...filters.Option) (*response.ResultSet[Role], error) { + roles := &response.ResultSet[Role]{} + params := url.Values{} + + for _, opt := range opts { + opt(¶ms) } - // Set new roles. - return store.setUserRoles(userID, newRoles) + _, err := c.api. + URL("/role-store/api/v1/roles/search"). + Query(params). + Post(&search, &roles) + + return roles, err } -func (store *RoleStore) setUserRoles(userID string, roles []Role) error { - _, err := store.api. - URL("/role-store/api/v1/users/%s/roles", url.PathEscape(userID)). - Put(roles) +// EvaluateRole evaluate role definition. +func (c *RoleStore) EvaluateRole(role *Role) (*response.ResultSet[User], error) { + users := &response.ResultSet[User]{} - return err + _, err := c.api. + URL("/role-store/api/v1/roles/evaluate"). + Post(role, &users) + + return users, err } -// EnableMFA enable multifactor authentication -func (store *RoleStore) EnableMFA(userIDs []string) error { - _, err := store.api. - URL("/role-store/api/v1/users/mfa/enable"). - Post(&userIDs) +// GetRole get role by id. +func (c *RoleStore) GetRole(roleID string) (*Role, error) { + role := &Role{} - return err + _, err := c.api. + URL("/role-store/api/v1/roles/%s", roleID). + Get(&role) + + return role, err } -// DisableMFA disable multifactor authentication -func (store *RoleStore) DisableMFA(userIDs []string) error { - _, err := store.api. - URL("/role-store/api/v1/users/mfa/disable"). - Post(&userIDs) +// UpdateRole update role. +func (c *RoleStore) UpdateRole(roleID string, role *Role) error { + _, err := c.api. + URL("/role-store/api/v1/roles/%s", roleID). + Put(&role) return err } -// ResetMFA reset multifactor authentication -func (store *RoleStore) ResetMFA(userIDs []string) error { - _, err := store.api. - URL("/role-store/api/v1/users/mfa/reset"). - Post(&userIDs) +// DeleteRole delete role. +func (c *RoleStore) DeleteRole(roleID string) error { + _, err := c.api. + URL("/role-store/api/v1/roles/%s", roleID). + Delete() return err } -// ResolveUser resolve users role -func (store *RoleStore) ResolveUser(userID string) (*User, error) { - user := &User{} +// GetRoleMembers gets users of the role. +func (c *RoleStore) GetRoleMembers(roleID string, opts ...filters.Option) (*response.ResultSet[User], error) { + users := &response.ResultSet[User]{} + params := url.Values{} - _, err := store.api. - URL("/role-store/api/v1/users/%s/resolve", url.PathEscape(userID)). - Get(user) + for _, opt := range opts { + opt(¶ms) + } - return user, err + _, err := c.api. + URL("/role-store/api/v1/roles/%s/members", roleID). + Query(params). + Get(&users) + + return users, err } -// SearchUsers searches for users, matching the keywords and source -// criteria. -func (store *RoleStore) SearchUsers(offset, limit int, sortkey, sortdir string, searchBody UserSearchObject) ([]User, error) { - result := usersResult{} - filters := Params{ - Offset: offset, - Limit: limit, - Sortkey: sortkey, - Sortdir: sortdir, - } - _, err := store.api. - URL("/role-store/api/v1/users/search"). - Query(&filters). - Post(searchBody, &result) +// GetAWSToken get AWS token for role. +func (c *RoleStore) GetAWSToken(roleID string, opts ...filters.Option) (*json.RawMessage, error) { + token := &json.RawMessage{} + params := url.Values{} - return result.Items, err -} + for _, opt := range opts { + opt(¶ms) + } -// SearchUsersExternal searches users with user search parameters. -func (store *RoleStore) SearchUsersExternal(keywords, sourceID string) ([]User, error) { - result := usersResult{} - _, err := store.api. - URL("/role-store/api/v1/users/search/external"). - Post(map[string]string{ - "keywords": keywords, - "source": sourceID, - }, &result) + _, err := c.api. + URL("/role-store/api/v1/roles/%s/awstoken", roleID). + Query(params). + Get(&token) - return result.Items, err + return token, err } -// AuthorizedKeys return user's authorized keys -func (store *RoleStore) AuthorizedKeys(userID string) ([]AuthorizedKey, error) { - result := authorizedkeysResult{} +// GetPrincipalKeys get roles principal keys. +func (c *RoleStore) GetPrincipalKeys(roleID string) (*response.ResultSet[RolePrincipalKey], error) { + keys := &response.ResultSet[RolePrincipalKey]{} - _, err := store.api. - URL("/role-store/api/v1/users/%s/authorizedkeys", url.PathEscape(userID)). - Get(&result) + _, err := c.api. + URL("/role-store/api/v1/roles/%s/principalkeys", roleID). + Get(&keys) - return result.Items, err + return keys, err } -// CreateAuthorizedKey register an authorized key for user -func (store *RoleStore) CreateAuthorizedKey(key AuthorizedKey, userID string) (string, error) { - var object struct { - ID string `json:"id"` - } +// CreatePrincipalKey create principal key for role. +func (c *RoleStore) CreatePrincipalKey(roleID string) (response.Identifier, error) { + identifier := response.Identifier{} - _, err := store.api. - URL("/role-store/api/v1/users/%s/authorizedkeys", url.PathEscape(userID)). - Post(&key, &object) + _, err := c.api. + URL("/role-store/api/v1/roles/%s/principalkeys/generate", roleID). + Post(nil, &identifier) - return object.ID, err + return identifier, err } -// AuthorizedKey return user's authorized key -func (store *RoleStore) AuthorizedKey(userID, keyID string) (*AuthorizedKey, error) { - key := &AuthorizedKey{} +// ImportPrincipalKey import principal key for role. +func (c *RoleStore) ImportPrincipalKey(roleID string, key RolePrincipalKeyImport) (response.Identifier, error) { + identifier := response.Identifier{} - _, err := store.api. - URL("/role-store/api/v1/users/%s/authorizedkeys/%s", url.PathEscape(userID), url.PathEscape(keyID)). - Get(key) + _, err := c.api. + URL("/role-store/api/v1/roles/%s/principalkeys/import", roleID). + Post(&key, &identifier) - return key, err + return identifier, err } -// UpdateAuthorizedKey update authorized key for user -func (store *RoleStore) UpdateAuthorizedKey(key *AuthorizedKey, userID, keyID string) error { - _, err := store.api. - URL("/role-store/api/v1/users/%s/authorizedkeys/%s", url.PathEscape(userID), url.PathEscape(keyID)). - Put(key) +// GetPrincipalKey get roles principal key. +func (c *RoleStore) GetPrincipalKey(roleID, keyID string) (RolePrincipalKey, error) { + key := RolePrincipalKey{} - return err + _, err := c.api. + URL("/role-store/api/v1/roles/%s/principalkeys/%s", roleID, keyID). + Get(&key) + + return key, err } -// DeleteAuthorizedKey delete a user's authorized key -func (store *RoleStore) DeleteAuthorizedKey(userID, keyID string) error { - _, err := store.api. - URL("/role-store/api/v1/users/%s/authorizedkeys/%s", userID, keyID). +// DeletePrincipalKey delete roles principal key. +func (c *RoleStore) DeletePrincipalKey(roleID, keyID string) error { + _, err := c.api. + URL("/role-store/api/v1/roles/%s/principalkeys/%s", roleID, keyID). Delete() return err } -// LogconfCollectors returns all logconf collectors -func (store *RoleStore) LogconfCollectors() ([]LogconfCollector, error) { - result := collectorsResult{} +// MARK: Identity Providers +// GetIdentityProviders get identity providers. +func (c *RoleStore) GetIdentityProviders(opts ...filters.Option) (*response.ResultSet[IdentityProvider], error) { + providers := &response.ResultSet[IdentityProvider]{} + params := url.Values{} - _, err := store.api. - URL("/role-store/api/v1/logconf/collectors"). - Get(&result) + for _, opt := range opts { + opt(¶ms) + } - return result.Items, err + _, err := c.api. + URL("/role-store/api/v1/identity-providers"). + Query(params). + Get(&providers) + + return providers, err } -// CreateLogconfCollector create a logconf collector -func (store *RoleStore) CreateLogconfCollector(conf LogconfCollector) (string, error) { - var object struct { - ID string `json:"id"` - } +// CreateIdentityProvider create a identity provider. +func (c *RoleStore) CreateIdentityProvider(provider *IdentityProvider) (response.Identifier, error) { + identifier := response.Identifier{} - _, err := store.api. - URL("/role-store/api/v1/logconf/collectors"). - Post(&conf, &object) + _, err := c.api. + URL("/role-store/api/v1/identity-providers"). + Post(&provider, &identifier) - return object.ID, err + return identifier, err } -// LogconfCollector returns existing single logconf collector -func (store *RoleStore) LogconfCollector(collectorID string) (*LogconfCollector, error) { - conf := &LogconfCollector{} +// GetIdentityProvider get identity provider by id. +func (c *RoleStore) GetIdentityProvider(providerID string) (*IdentityProvider, error) { + provider := &IdentityProvider{} - _, err := store.api. - URL("/role-store/api/v1/logconf/collectors/%s", url.PathEscape(collectorID)). - Get(conf) + _, err := c.api. + URL("/role-store/api/v1/identity-providers/%s", providerID). + Get(&provider) - return conf, err + return provider, err } -// UpdateLogconfCollector update existing logconf collector -func (store *RoleStore) UpdateLogconfCollector(collectorID string, conf *LogconfCollector) error { - _, err := store.api. - URL("/role-store/api/v1/logconf/collectors/%s", url.PathEscape(collectorID)). - Put(conf) +// UpdateIdentityProvider update identity provider. +func (c *RoleStore) UpdateIdentityProvider(providerID string, provider *IdentityProvider) error { + _, err := c.api. + URL("/role-store/api/v1/identity-providers/%s", providerID). + Put(&provider) return err } -// DeleteLogconfCollector delete a logconf collector -func (store *RoleStore) DeleteLogconfCollector(collectorID string) error { - _, err := store.api. - URL("/role-store/api/v1/logconf/collectors/%s", collectorID). +// DeleteIdentityProvider delete identity provider by id. +func (c *RoleStore) DeleteIdentityProvider(providerID string) error { + _, err := c.api. + URL("/role-store/api/v1/identity-providers/%s", providerID). Delete() return err } -// AllAuthorizedKeys returns all authorized keys -func (store *RoleStore) AllAuthorizedKeys(offset, limit int, sortdir, sortkey string) ([]AuthorizedKey, error) { - result := authorizedkeysResult{} - filters := Params{ - Offset: offset, - Limit: limit, - Sortdir: sortdir, - Sortkey: sortkey, +// SearchIdentityProviders search identity providers. +func (c *RoleStore) SearchIdentityProviders(search IdentityProviderSearch, opts ...filters.Option) (*response.ResultSet[IdentityProvider], error) { + providers := &response.ResultSet[IdentityProvider]{} + params := url.Values{} + + for _, opt := range opts { + opt(¶ms) } - _, err := store.api. - URL("/role-store/api/v1/authorizedkeys"). - Query(&filters). - Get(&result) + _, err := c.api. + URL("/role-store/api/v1/identity-providers/search"). + Query(params). + Post(&search, &providers) - return result.Items, err + return providers, err } -// ResolveAuthorizedKey resolve authorized keys -func (store *RoleStore) ResolveAuthorizedKey(resolve ResolveAuthorizedKey) ([]AuthorizedKey, error) { - result := authorizedkeysResult{} +// MARK: Authorized Keys +// GetAuthorizedKeys get authorized keys. +func (c *RoleStore) GetAuthorizedKeys(opts ...filters.Option) (*response.ResultSet[AuthorizedKey], error) { + keys := &response.ResultSet[AuthorizedKey]{} + params := url.Values{} - _, err := store.api. - URL("/role-store/api/v1/authorizedkeys/resolve"). - Post(&resolve, &result) + for _, opt := range opts { + opt(¶ms) + } - return result.Items, err -} + _, err := c.api. + URL("/role-store/api/v1/authorizedkeys"). + Query(params). + Get(&keys) -///////////////////////////// -//// Identity providers //// -/////////////////////////// + return keys, err +} -// List all identity providers. -func (store *RoleStore) GetAllIdentityProviders(offset, limit int) (IdentityProviderResponse, error) { - result := IdentityProviderResponse{} +// ResolveAuthorizedKey resolve authorized key. +func (c *RoleStore) ResolveAuthorizedKey(resolve AuthorizedKeyResolve) (*AuthorizedKey, error) { + key := &AuthorizedKey{} - filters := Params{ - Offset: offset, - Limit: limit, - } + _, err := c.api. + URL("/role-store/api/v1/authorizedkeys/resolve"). + Post(&resolve, &key) - _, err := store.api. - URL("/role-store/api/v1/identity-providers"). - Query(&filters). - Get(&result) - return result, err + return key, err } -// Create a new Identity Provider. -func (store *RoleStore) CreateIdentityProvider(newIP IdentityProvider) (IdentityProviderCreateResponse, error) { - result := IdentityProviderCreateResponse{} +// MARK: Logconf +// GetLogConfCollectors get logconf collectors. +func (c *RoleStore) GetLogConfCollectors() (*response.ResultSet[LogConfCollector], error) { + collectors := &response.ResultSet[LogConfCollector]{} - _, err := store.api. - URL("/role-store/api/v1/identity-providers"). - Post(newIP, &result) + _, err := c.api. + URL("/role-store/api/v1/logconf/collectors"). + Get(&collectors) - return result, err + return collectors, err } -// Get Identity Provider by ID. -func (store *RoleStore) GetIdentityProviderByID(ID string) (IdentityProvider, error) { - result := IdentityProvider{} +// CreateLogConfCollector create logconf collector. +func (c *RoleStore) CreateLogConfCollector(collector *LogConfCollector) (response.Identifier, error) { + identifier := response.Identifier{} - _, err := store.api. - URL("/role-store/api/v1/identity-providers/%s", url.PathEscape(ID)). - Get(&result) + _, err := c.api. + URL("/role-store/api/v1/logconf/collectors"). + Post(&collector, &identifier) - return result, err + return identifier, err } -// Delete Identity Provider by ID. -func (store *RoleStore) DeleteIdentityProviderByID(ID string) error { +// GetLogConfCollector get logconf collector by id. +func (c *RoleStore) GetLogConfCollector(collectorID string) (*LogConfCollector, error) { + collector := &LogConfCollector{} - _, err := store.api. - URL("/role-store/api/v1/identity-providers/%s", url.PathEscape(ID)). - Delete() + _, err := c.api. + URL("/role-store/api/v1/logconf/collectors/%s", collectorID). + Get(&collector) - return err + return collector, err } -// Update a Identity Provider. -func (store *RoleStore) UpdateIdentityProvider(UpdatedIP IdentityProvider, ID string) error { - - _, err := store.api. - URL("/role-store/api/v1/identity-providers/%s", url.PathEscape(ID)). - Put(UpdatedIP) +// UpdateLogConfCollector update logconf collector. +func (c *RoleStore) UpdateLogConfCollector(collectorID string, collector *LogConfCollector) error { + _, err := c.api. + URL("/role-store/api/v1/logconf/collectors/%s", collectorID). + Put(&collector) return err } -// Search Identity Providers. -func (store *RoleStore) SearchIdentityProviders(offset, limit int, sortkey, sortdir, keywords string) (IdentityProviderResponse, error) { - result := IdentityProviderResponse{} - - filters := Params{ - Offset: offset, - Limit: limit, - Sortkey: sortkey, - Sortdir: strings.ToUpper(sortdir), - } - body := IdentityProviderSearch{ - Keywords: keywords, - } - _, err := store.api. - URL("/role-store/api/v1/identity-providers/search"). - Query(filters). - Post(body, &result) +// DeleteLogConfCollector delete logconf collector. +func (c *RoleStore) DeleteLogConfCollector(collectorID string) error { + _, err := c.api. + URL("/role-store/api/v1/logconf/collectors/%s", collectorID). + Delete() - return result, err + return err } diff --git a/api/rolestore/model.go b/api/rolestore/model.go index 312b2c3..70b2ab4 100644 --- a/api/rolestore/model.go +++ b/api/rolestore/model.go @@ -7,339 +7,483 @@ package rolestore import ( - authmodel "github.com/SSHcom/privx-sdk-go/api/auth" + "encoding/json" + + "github.com/SSHcom/privx-sdk-go/api/auth" ) -// Params struct for pagination queries. -type Params struct { - Sortdir string `json:"sortdir,omitempty"` - Sortkey string `json:"sortkey,omitempty"` - Tokencode string `json:"tokencode,omitempty"` - Refresh bool `json:"refresh,omitempty"` - Offset int `json:"offset,omitempty"` - Limit int `json:"limit,omitempty"` - TTL int `json:"ttl,omitempty"` +// AWSRoleParams aws role query parameter definition. +type AWSRoleParams struct { + Refresh string `url:"refresh,omitempty"` } -// ResolveAuthorizedKey struct for resolving authorized key. -type ResolveAuthorizedKey struct { +// AuthorizedKeyResolve authorized key resolve request definition. +type AuthorizedKeyResolve struct { Username string `json:"username,omitempty"` PublicKey string `json:"public_key,omitempty"` } -// PrivateKey principal private key definition -type PrivateKey struct { - ID string `json:"id,omitempty"` +// RolePrincipalKeyImport role principal key import request definition. +type RolePrincipalKeyImport struct { PrivateKey string `json:"private_key,omitempty"` } -// PrincipalKey principal key definition -type PrincipalKey struct { +// RolePrincipalKey role principal key definition. +type RolePrincipalKey struct { ID string `json:"id,omitempty"` PublicKey string `json:"public_key,omitempty"` } -// LogconfCollector logconf collectors definition -type LogconfCollector struct { - ID string `json:"id,omitempty"` - Name string `json:"name,omitempty"` - Type string `json:"type,omitempty"` - Updated string `json:"updated,omitempty"` - StatusCode string `json:"status_code,omitempty"` - StatusText string `json:"status_text,omitempty"` - AWSLogRegion string `json:"aws_log_region,omitempty"` - IAMAccessKeyID string `json:"iam_access_key_id,omitempty"` - IAMSecretAccessKey string `json:"iam_secret_access_key,omitempty"` - IAMSessionToken string `json:"iam_session_token,omitempty"` - AzureEventHubsNamespace string `json:"azure_event_hubs_namespace,omitempty"` - AzureResourceGroupName string `json:"azure_resource_group_name,omitempty"` - AzureSubscriptionID string `json:"azure_subscription_id,omitempty"` - AzureEventHubName string `json:"azure_event_hub_name,omitempty"` - AzureTenantID string `json:"azure_tenant_id,omitempty"` - AzureClientID string `json:"azure_client_id,omitempty"` - AzureClientSecret string `json:"azure_client_secret,omitempty"` - AzureSasConnectionString string `json:"azure_sas_connection_string,omitempty"` - Enabled bool `json:"enabled,omitempty"` -} - -// AWSToken aws token definition -type AWSToken struct { - AccessKeyID string `json:"access_key_id,omitempty"` - SecretAccessKey string `json:"secret_access_key,omitempty"` - SessionToken string `json:"session_token,omitempty"` - Expires string `json:"expires,omitempty"` - Descriptions []string `json:"descriptions,omitempty"` -} - -// AWSRoleLink aws role definition. -type AWSRoleLink struct { - ID string `json:"id,omitempty"` - Name string `json:"name,omitempty"` - ARN string `json:"arn,omitempty"` - Updated string `json:"updated,omitempty"` - Description string `json:"description,omitempty"` - Source string `json:"source,omitempty"` - Status string `json:"status,omitempty"` - Roles []RoleRef `json:"roles,omitempty"` -} - -// Connection source connection definition -type Connection struct { - Type string `json:"type,omitempty"` - Address string `json:"address,omitempty"` - AccessKeyID string `json:"iam_access_key_id,omitempty"` - SecretKey string `json:"iam_secret_access_key,omitempty"` - SessionToken string `json:"iam_session_token,omitempty"` - FetchRolePathPrefix string `json:"iam_fetch_role_path_prefix,omitempty"` - GCConfig string `json:"google_cloud_config_json,omitempty"` - OpenstackVersion string `json:"openstack_version,omitempty"` - OpenStackEndpoint string `json:"openstack_endpoint,omitempty"` - OpenStackUsername string `json:"openstack_username,omitempty"` - OpenStackUserID string `json:"openstack_user_id,omitempty"` - OpenStackPassword string `json:"openstack_password,omitempty"` - OpenStackAPIkey string `json:"openstack_apikey,omitempty"` - OpenStackDomainName string `json:"openstack_domainname,omitempty"` - OpenStackDomainID string `json:"openstack_domainid,omitempty"` - OpenStackTokenID string `json:"openstack_token_id,omitempty"` - AzureBaseURL string `json:"azure_base_url,omitempty"` - AzureSubscriptionID string `json:"azure_subscription_id,omitempty"` - AzureTenantID string `json:"azure_tenant_id,omitempty"` - AzureClientID string `json:"azure_client_id,omitempty"` - AzureClientSecret string `json:"azure_client_secret,omitempty"` - LDAPProtocol string `json:"ldap_protocol,omitempty"` - LDAPBase string `json:"ldap_base,omitempty"` - LDAPUserFilter string `json:"ldap_user_filter,omitempty"` - LDAPBindDN string `json:"ldap_bind_dn,omitempty"` - LDAPBindPassword string `json:"ldap_bind_password,omitempty"` - LDAPUserDNPattern string `json:"ldap_user_dn_pattern,omitempty"` - GoogleGsuiteDomain string `json:"google_gsuite_domain,omitempty"` - GoogleGsuiteAdminEmail string `json:"google_gsuite_domain_admin_email,omitempty"` - OIDCIssuer string `json:"oidc_issuer,omitempty"` - OIDCButtonTitle string `json:"oidc_button_title,omitempty"` - OIDCClientID string `json:"oidc_client_id,omitempty"` - OIDCClientSecret string `json:"oidc_client_secret,omitempty"` - OIDCTagsAttributeName string `json:"oidc_tags_attribute_name,omitempty"` - MFAType string `json:"mfa_type,omitempty"` - MFAAddress string `json:"mfa_address,omitempty"` - MFABaseDN string `json:"mfa_base_dn,omitempty"` - DomainControllerFQDN string `json:"domain_controller_fqdn,omitempty"` - KerberosTicket string `json:"kerberos_ticket,omitempty"` - DomainControllerPort int `json:"domain_controller_port,omitempty"` - MFAPort int `json:"mfa_port,omitempty"` - Port int `json:"port,omitempty"` - EnableMachineAuth bool `json:"enable_machine_authentication,omitempty"` - EnableUserAuth bool `json:"enable_user_authentication,omitempty"` - OIDCEnabled bool `json:"oidc_enabled,omitempty"` - FetchRoles bool `json:"iam_fetch_roles,omitempty"` - AutoUpdate bool `json:"service_address_auto_update,omitempty"` - OIDCScopesSecret []string `json:"oidc_additional_scopes_secret,omitempty"` - GCProjectIDs []string `json:"google_cloud_project_ids,omitempty"` - OpenStackTenantIDs []string `json:"openstack_tenant_ids,omitempty"` - OpenStackTenantNames []string `json:"openstack_tenant_names,omitempty"` -} - -// EUM external user mapping definition -type EUM struct { - SourceID string `json:"source_id,omitempty"` - SourceSeaerchField string `json:"source_search_field,omitempty"` -} - -// Source definitions - user and host directories +// LogConfCollector logconf collectors definition. +type LogConfCollector struct { + ID string `json:"id,omitempty"` + Name string `json:"name,omitempty"` + Type string `json:"type,omitempty"` + Enabled bool `json:"enabled"` + Updated string `json:"updated,omitempty"` + StatusCode string `json:"status_code,omitempty"` + StatusText string `json:"status_text,omitempty"` + AWSLogRegion string `json:"aws_log_region,omitempty"` + IAMAccessKeyID string `json:"iam_access_key_id,omitempty"` + IAMSecretAccessKey string `json:"iam_secret_access_key,omitempty"` + IAMSessionToken string `json:"iam_session_token,omitempty"` + Namespace string `json:"azure_event_hubs_namespace,omitempty"` + EventHubName string `json:"azure_event_hub_name,omitempty"` + TenantID string `json:"azure_tenant_id,omitempty"` + ClientID string `json:"azure_client_id,omitempty"` + ClientSecret string `json:"azure_client_secret,omitempty"` + SASConnectionString string `json:"azure_sas_connection_string,omitempty"` +} + +// AWSRole aws role definition. +type AWSRole struct { + ID string `json:"id,omitempty"` + DisplayName string `json:"name,omitempty"` + ARN string `json:"arn,omitempty"` + Description string `json:"description,omitempty"` + Source string `json:"source,omitempty"` + Status string `json:"status,omitempty"` + Roles []LinkedPrivXRole `json:"roles,omitempty"` + Updated string `json:"updated,omitempty"` +} + +type LinkedPrivXRole struct { + ID string `json:"id,omitempty"` + DisplayName string `json:"name,omitempty"` +} + +// Source source definitions. type Source struct { - ID string `json:"id,omitempty"` - Created string `json:"created,omitempty"` - Updated string `json:"updated,omitempty"` - UpdatedBy string `json:"updated_by,omitempty"` - Author string `json:"author,omitempty"` - Name string `json:"name,omitempty"` - StatusCode string `json:"status_code,omitempty"` - StatusText string `json:"status_text,omitempty"` - Comment string `json:"comment,omitempty"` - TTL int `json:"ttl,omitempty"` - Enabled bool `json:"enabled,omitempty"` - Tags []string `json:"tags,omitempty"` - UsernamePattern []string `json:"username_pattern,omitempty"` - ExternalUserMapping []EUM `json:"external_user_mapping,omitempty"` - Connection Connection `json:"connection,omitempty"` - SessionPasswordEnabled bool `json:"session_password_enabled,omitempty"` - SessionPasswordPolicy *authmodel.SessionPasswordPolicy `json:"session_password_policy,omitempty"` - ChildSessionAutoLogoutDelay int `json:"child_session_auto_logout_delay,omitempty"` -} - -// User contains PrivX user information. + ID string `json:"id,omitempty"` + Name string `json:"name,omitempty"` + Created string `json:"created,omitempty"` + Updated string `json:"updated,omitempty"` + Author string `json:"author,omitempty"` + UpdatedBy string `json:"updatedby,omitempty"` + TTL int `json:"ttl,omitempty"` + RegionFilter []string `json:"region_filter,omitempty"` + Comment string `json:"comment,omitempty"` + Tags []string `json:"tags,omitempty"` + StatusCode string `json:"status_code"` + StatusText string `json:"status_text"` + Connection SourceConnection `json:"connection,omitempty"` + UsernamePattern []string `json:"username_pattern,omitempty"` + ExternalUserMapping []UserMapping `json:"external_user_mapping,omitempty"` + Enabled bool `json:"enabled"` + SessionPasswordEnabled bool `json:"session_password_enabled,omitempty"` + SessionPasswordPolicy *auth.SessionPasswordPolicy `json:"session_password_policy,omitempty"` + ChildSessionAutoLogoutDelay int `json:"child_session_auto_logout_delay,omitempty"` +} + +// UserMapping user mapping definition +type UserMapping struct { + SourceID string `json:"source_id,omitempty"` + SourceSearchField string `json:"source_search_field,omitempty"` +} + +// SourceConnection source connection definition. +type SourceConnection struct { + Type string `json:"type,omitempty"` + AttributeMapping map[string]string `json:"attribute_mapping"` + MFAType string `json:"mfa_type"` + MFAAddress string `json:"mfa_address"` + MFAPort int `json:"mfa_port"` + ServiceAddressAutoUpdate bool `json:"service_address_auto_update"` + UseInstanceTags bool `json:"use_instance_tags"` + HostFilterTag string `json:"host_filter_tag,omitempty"` + AWSRoleFilterName string `json:"aws_role_filter_name,omitempty"` + EnableUserAuthentication bool `json:"enable_user_authentication,omitempty"` + EnableMachineAuthentication bool `json:"enable_machine_authentication,omitempty"` + + // AWS + IAMAccessKeyID string `json:"iam_access_key_id"` + IAMSecretAccessKey string `json:"iam_secret_access_key"` + IAMSessionToken string `json:"iam_session_token"` + IAMRoleARN string `json:"iam_role_arn"` + + IAMFetchRoles bool `json:"iam_fetch_roles"` + IAMFetchRolePathPrefix string `json:"iam_fetch_role_path_prefix"` + IAMExternalID string `json:"iam_external_id"` + + // Google Cloud + GoogleCloudProjectIDs []string `json:"google_cloud_project_ids"` + GoogleCloudConfigJSON string `json:"google_cloud_config_json"` + + // Google GSuite + GoogleGSuiteDomainAdminEmail string `json:"google_gsuite_domain_admin_email"` + GoogleGSuiteDomain string `json:"google_gsuite_domain"` + + // OpenStack + OpenStackIdentityEndpoint string `json:"openstack_endpoint"` + OpenStackUsername string `json:"openstack_username"` + OpenStackUserID string `json:"openstack_user_id"` + OpenStackPassword string `json:"openstack_password"` + OpenStackDomainName string `json:"openstack_domainname"` + OpenStackDomainID string `json:"openstack_domain_id"` + OpenStackTokenID string `json:"openstack_token_id"` + OpenStackTenantIDs []string `json:"openstack_tenant_ids"` + OpenStackTenantNames []string `json:"openstack_tenant_names"` + OpenStackVersion string `json:"openstack_version"` + OpenStackRegion string `json:"openstack_region"` + + // Azure + AzureEndpoint string `json:"azure_base_url"` + AzureSubscriptionID string `json:"azure_subscription_id"` + AzureTenantID string `json:"azure_tenant_id"` + AzureClientID string `json:"azure_client_id"` + AzureClientSecret string `json:"azure_client_secret"` + + // Microsoft Graph API + MsGraphEndpoint string `json:"msgraph_base_url"` + MsGraphTenantID string `json:"msgraph_tenant_id"` + MsGraphClientID string `json:"msgraph_client_id"` + MsGraphClientSecret string `json:"msgraph_client_secret"` + MSGraphBatchSize int `json:"msgraph_batch_size"` + MSGraphPageSize int `json:"msgraph_page_size"` + + // AD/LDAP + Address string `json:"address"` + Port int `json:"port"` + LdapBaseDN string `json:"ldap_base_dn"` + LdapUserDNPattern string `json:"ldap_user_dn_pattern"` + LdapUserFilter string `json:"ldap_user_filter"` + LdapBindDN string `json:"ldap_bind_dn"` + LdapBindPassword string `json:"ldap_bind_password"` + LdapProtocol string `json:"ldap_protocol"` + Certificates string `json:"root_certificates"` + PasswordChangeEnabled bool `json:"password_change_enabled"` + ClientCertificateAuthenticationEnabled bool `json:"client_certificate_authentication_enabled"` + ClientCAPEM string `json:"client_ca_pem"` + ClientCertificateAuthenticationRequired bool `json:"client_certificate_authentication_required"` + + // AD/LDAP/UKM + SkipStrictCertCheck bool `json:"skip_strict_cert_check"` + + // OpenID Connect + OIDCEnabled bool `json:"oidc_enabled"` + OIDCIssuer string `json:"oidc_issuer"` + OIDCClientID string `json:"oidc_client_id"` + OIDCClientSecret string `json:"oidc_client_secret"` + OIDCButtonTitle string `json:"oidc_button_title"` + OIDCTagsAttributeName string `json:"oidc_tags_attribute_name"` + OIDCAllowLoginTag string `json:"oidc_allow_login_tag"` + OIDCAdditionalScopes []string `json:"oidc_additional_scopes"` + OIDCUseUserInfoEndpoint bool `json:"oidc_use_userinfo_endpoint"` + + // User directory group filter + GroupFilter []string `json:"group_filter"` + + // SCIM + SCIMAuthenticationType string `json:"scim_authentication_type"` + SCIMCreateRoles bool `json:"scim_create_roles"` + SCIMUpdateSSHHostKeys bool `json:"scim_update_ssh_host_keys"` + SCIMBasicUsername string `json:"scim_username"` + SCIMBasicPassword string `json:"scim_password"` + SCIMUserFilter string `json:"scim_user_filter"` + + // VMWare ESXi/vCenter + VMWareEndpoint string `json:"vmware_url"` + VMWareUsername string `json:"vmware_username"` + VMWarePassword string `json:"vmware_password"` + VMWareDataCenter string `json:"vmware_datacenter"` + + // UKM + UKMEndpoint string `json:"ukm_endpoint"` + UKMToken string `json:"ukm_token"` + UKMTrustAnchor string `json:"um_ca_pem"` +} + +// User user definition. type User struct { - ID string `json:"id,omitempty"` - SourceUserID string `json:"source_user_id,omitempty"` - Principal string `json:"principal,omitempty"` - Source string `json:"source,omitempty"` - FullName string `json:"full_name,omitempty"` - Email string `json:"email,omitempty"` - DistinguishedName string `json:"distinguished_name,omitempty"` - Created string `json:"created,omitempty"` - Updated string `json:"updated,omitempty"` - UpdatedBy string `json:"updated_by,omitempty"` - Author string `json:"author,omitempty"` - Comment string `json:"comment,omitempty"` - GivenName string `json:"given_name,omitempty"` - Job string `json:"job_title,omitempty"` - Company string `json:"company,omitempty"` - Department string `json:"department,omitempty"` - Telephone string `json:"telephone,omitempty"` - Locale string `json:"locale,omitempty"` - StaleAccessToken bool `json:"stale_access_token,omitempty"` - Permissions []string `json:"permissions,omitempty"` - Tags []string `json:"tags"` - MFA MFA `json:"mfa"` - Roles []Role `json:"roles"` - AuthorizedKeys []AuthorizedKey `json:"authorized_keys,omitempty"` -} - -// AuthorizedKey authorizednal key definition + ID string `json:"id,omitempty"` + SourceUserID string `json:"source_user_id,omitempty"` + Created string `json:"created,omitempty"` + Updated string `json:"updated,omitempty"` + Author string `json:"author,omitempty"` + UpdatedBy string `json:"updatedby,omitempty"` + Principal string `json:"principal,omitempty"` + Source string `json:"source,omitempty"` + SourceType string `json:"source_type,omitempty"` + Comment string `json:"comment,omitempty"` + Tags []string `json:"tags,omitempty"` + Roles []Role `json:"roles"` + Attributes []Attributes `json:"attributes"` + Permissions []string `json:"permissions"` + FirstName string `json:"first_name,omitempty"` + LastName string `json:"last_name,omitempty"` + FullName string `json:"full_name,omitempty"` + JobTitle string `json:"job_title,omitempty"` + Company string `json:"company,omitempty"` + Department string `json:"department,omitempty"` + Email string `json:"email,omitempty"` + Telephone string `json:"telephone,omitempty"` + DistinguishedName string `json:"distinguished_name,omitempty"` + Locale string `json:"locale,omitempty"` + SamAccountName string `json:"samaccountname,omitempty"` + WindowsAccount string `json:"windows_account,omitempty"` + UnixAccount string `json:"unix_account,omitempty"` + Password string `json:"password,omitempty"` + MFA MFAStatus `json:"mfa,omitempty"` + Settings json.RawMessage `json:"settings,omitempty"` + ExternalID string `json:"external_id,omitempty"` + AuthorizedKeys []AuthorizedKey `json:"authorized_keys,omitempty"` + WebAuthnCredentials []Credential `json:"webauthn_credentials,omitempty"` + SessionPasswordEnabled bool `json:"session_password_enabled,omitempty"` + StaleAccessToken bool `json:"stale_access_token,omitempty"` + CurrentSessionID string `json:"current_session_id,omitempty"` + RefreshTimestamp string +} + +// Credential webauthn credential definition. +type Credential struct { + ID string `json:"id"` + CredentialID string `json:"credential_id"` + Name string `json:"name,omitempty" diff:"name"` + Comment string `json:"comment,omitempty" diff:"comment"` + LastUsed string `json:"last_used,omitempty"` + Created string `json:"created,omitempty"` + Author string `json:"author,omitempty"` + Updated string `json:"updated,omitempty"` + UpdatedBy string `json:"updated_by,omitempty"` +} + +// MFAStatus mfa status definition. +type MFAStatus struct { + Status string `json:"user_mfa_status,omitempty"` + TotpStatus string `json:"status,omitempty"` + TotpMFASeed MFASeed `json:"seed,omitempty"` + MobileMfaStatus string `json:"mobile_mfa_status"` +} + +type MFASeed struct { + Seed_string string `json:"seed_string,omitempty"` + Seed_qr_code string `json:"seed_qr_code,omitempty"` +} + +// Attributes user attributes definition. +type Attributes struct { + Key string `json:"key"` + Value string `json:"value"` +} + +// AuthorizedKey authorized key definition. type AuthorizedKey struct { - ID string `json:"id,omitempty"` - Username string `json:"username,omitempty"` + ID string `json:"id"` UserID string `json:"user_id,omitempty"` - Name string `json:"name,omitempty"` - Comment string `json:"comment,omitempty"` + Username string `json:"username,omitempty"` + Source string `json:"source,omitempty"` PublicKey string `json:"public_key,omitempty"` NotBefore string `json:"not_before,omitempty"` NotAfter string `json:"not_after,omitempty"` - SourceAddress []string `json:"source_address,omitempty"` + ExpiresIn int64 `json:"expires_in,omitempty"` + SourceAddress []string `json:"source_address"` + Fingerprints []string `json:"fingerprints,omitempty"` + Name string `json:"name,omitempty"` + Comment string `json:"comment,omitempty"` + Created string `json:"created,omitempty"` + Updated string `json:"updated,omitempty"` + UpdatedBy string `json:"updated_by,omitempty"` + Author string `json:"author,omitempty"` } -// MFA multifactor authentication definition -type MFA struct { - Status string `json:"status,omitempty"` - Seed Seed `json:"seed,omitempty"` +// UserSettings user settings update request definition. +type UserSettings struct { + Locale UserLocale `json:"locale,omitempty"` + RDPClient UserRDPClient `json:"rdpClient,omitempty"` + SSHClient UserSSHClient `json:"sshClient,omitempty"` + ConnectionHistory []UserConnectionHistory `json:"connectionHistory,omitempty"` + Bookmarks UserBookmarks `json:"bookmarks,omitempty"` } -// Seed seed definition -type Seed struct { - SeedString string `json:"seed_string,omitempty"` - SeedQRCode string `json:"seed_qr_code,omitempty"` +// Bookmark bookmark user settings definition. +type Bookmark struct { + Id string `json:"id"` + URL string `json:"url"` + Title string `json:"title"` + Icon string `json:"icon"` } -// Role contains PrivX role information. -type Role struct { - ID string `json:"id"` - Name string `json:"name"` - GrantType string `json:"grant_type"` - Comment string `json:"comment"` - AccessGroupID string `json:"access_group_id"` - GrantStart string `json:"grant_start"` - GrantEnd string `json:"grant_end"` - GrantValidityPeriods []ValidityPeriod `json:"grant_validity_periods,omitempty"` - Permissions []string `json:"permissions"` - PublicKey []string `json:"principal_public_key_strings"` - MemberCount int `json:"member_count"` - FloatingLength int `json:"floating_length"` - Explicit bool `json:"explicit" tabulate:"@userCtx"` - Implicit bool `json:"implicit" tabulate:"@userCtx"` - System bool `json:"system"` - PermitAgent bool `json:"permit_agent"` - Context *Context `json:"context"` - SourceRule SourceRule `json:"source_rules"` +// UserBookmarks user bookmarks settings definition. +type UserBookmarks struct { + HostsBookmarks []Bookmark `json:"available-hosts,omitempty"` + NetworkTargetsBookmarks []Bookmark `json:"available-network-targets,omitempty"` + SecretsBookmarks []Bookmark `json:"secrets,omitempty"` + UserRequestsBookmarks []Bookmark `json:"requests,omitempty"` + ApprovalsBookmarks []Bookmark `json:"approvals,omitempty"` + ConnectionsBookmarks []Bookmark `json:"connections,omitempty"` + AuditEventBookmarks []Bookmark `json:"audit-events,omitempty"` + CertificatesBookmarks []Bookmark `json:"certificates,omitempty"` + AdminRolesBookmarks []Bookmark `json:"roles,omitempty"` + AdminUsersBookmarks []Bookmark `json:"users,omitempty"` + AdminHostsBookmarks []Bookmark `json:"hosts,omitempty"` + AdminNetworkTargetsBookmarks []Bookmark `json:"network-targets,omitempty"` + AdminDirectoriesBookmarks []Bookmark `json:"sources,omitempty"` + AdminAccessGroupsBookmarks []Bookmark `json:"access-groups,omitempty"` + AdminWorkflowsBookmarks []Bookmark `json:"workflows,omitempty"` + SessionsBookmarks []Bookmark `json:"sessions,omitempty"` + IdentityProviderClientsBookmarks []Bookmark `json:"identity-provider-clients,omitempty"` + ExternalTokenProvidersBookmarks []Bookmark `json:"external-token-providers,omitempty"` + AWSRolesBookmarks []Bookmark `json:"aws-roles,omitempty"` + APIClientsBookmarks []Bookmark `json:"api-clients,omitempty"` + CommandWhitelistsBookmarks []Bookmark `json:"command-whitelists,omitempty"` } -type ValidityPeriod struct { - GrantStart string `json:"grant_start,omitempty"` - GrantEnd string `json:"grant_end,omitempty"` +// UserConnectionHistory user connection history settings definition. +type UserConnectionHistory struct { + Id string `json:"id"` + Time string `json:"time"` + Type string `json:"type"` + Target string `json:"target"` + TargetID string `json:"targetId,omitempty"` + Account string `json:"account,omitempty"` + Name string `json:"name,omitempty"` + Application string `json:"application,omitempty"` } -// RoleRef is a reference to role object -type RoleRef struct { - ID string `json:"id"` - Name string `json:"name"` +// UserSSHClient user ssh client settings definition. +type UserSSHClient struct { + FontSize int `json:"fontSize,omitempty"` + Encoding string `json:"encoding,omitempty"` + Locale string `json:"locale,omitempty"` + Theme string `json:"theme,omitempty"` + CopyOnSelect bool `json:"copyOnSelect,omitempty"` + PasteOnRightClick bool `json:"pasteOnRightClick,omitempty"` + SendCtrlV bool `json:"sendCtrlV,omitempty"` + AltAsMeta bool `json:"altAsMeta,omitempty"` + ClickableLinks bool `json:"clickableLinks,omitempty"` + ScrollbackLength int `json:"scrollbackLength,omitempty"` } -// Context defines the context information for a role. -type Context struct { - Enabled bool `json:"enabled"` - BlockRole bool `json:"block_role"` - StartTime string `json:"start_time"` - EndTime string `json:"end_time"` - Timezone string `json:"timezone"` +// UserLocale user locale settings definition. +type UserLocale struct { + Locale string `json:"locale,omitempty"` } -// SourceRule defines a mapping of role to object objects in directory -type SourceRule struct { - Type string `json:"type"` - Match string `json:"match"` - Source string `json:"source,omitempty"` - Pattern string `json:"search_string,omitempty"` - Rules []SourceRule `json:"rules"` +// UserRDPClient user rdp client settings definition. +type UserRDPClient struct { + KeyboardLayout string `json:"keyboardLayout,omitempty"` + Scale float32 `json:"scale,omitempty"` + ScalingMode string `json:"scalingMode,omitempty"` + ImageScalingAlgorithm string `json:"imageScalingAlgorithm,omitempty"` + ClipboardSync bool `json:"clipboardSync,omitempty"` + ClipboardSyncStartsPaused bool `json:"clipboardSyncStartsPaused,omitempty"` } -// SourceRuleNone creates an empty mapping source for the role -func SourceRuleNone() SourceRule { - return SourceRule{ - Type: "GROUP", - Match: "ANY", - } +// RoleSearch role search request definition. +type RoleSearch struct { + Name []string `json:"name"` } -// UserSearchObject user search parameters -type UserSearchObject struct { - Keywords string `json:"keywords,omitempty"` - Source string `json:"source,omitempty"` - UserIDs []string `json:"user_id,omitempty"` +// Role PrivX role definition. +type Role struct { + ID string `json:"id"` + Name string `json:"name,omitempty"` + Explicit bool `json:"explicit"` + Implicit bool `json:"implicit"` + System bool `json:"system"` + GrantType string `json:"grant_type,omitempty"` + GrantStart string `json:"grant_start,omitempty"` + GrantEnd string `json:"grant_end,omitempty"` + GrantValidityPeriods []ValidityPeriod `json:"grant_validity_periods,omitempty"` + FloatingLength int64 `json:"floating_length,omitempty"` + Comment string `json:"comment,omitempty"` + Permissions []string `json:"permissions"` + AccessGroupID string `json:"access_group_id"` + PrincipalPublicKeys []string `json:"principal_public_key_strings,omitempty"` + PermitAgent bool `json:"permit_agent,omitempty"` + Context ContextualLimit `json:"context"` } -type IdentityProvider struct { - ID string `json:"id"` - Name string `json:"name"` - TokenType string `json:"token_type"` - JWTIssuer string `json:"jwt_issuer"` - JWTAudience string `json:"jwt_audience"` - JWTSubjectType string `json:"jwt_subject_type"` - JWTSubjectDNUsernameAttribute string `json:"jwt_subject_dn_username_attribute,omitempty"` +type ContextualLimit struct { + Enabled bool `json:"enabled"` + BlockRole bool `json:"block_role,omitempty"` + Validity []string `json:"validity"` + StartTime string `json:"start_time"` + EndTime string `json:"end_time"` + TimeZone string `json:"timezone"` + IPMasks []string `json:"ip_masks"` +} - CustomAttributes []CustomAttributeValidation `json:"custom_attributes,omitempty"` +// ValidityPeriod validity period definition. +type ValidityPeriod struct { + GrantStart string `json:"grant_start,omitempty"` + GrantEnd string `json:"grant_end,omitempty"` +} - PublicKey []PublicKey `json:"public_key,omitempty"` - PublicKeyMethod string `json:"public_key_method"` +// RoleHandle role handle definition. +type RoleHandle struct { + ID string `json:"id"` + Name string `json:"name"` + Deleted bool `json:"deleted,omitempty"` +} - // Used for validating certs fetched from x5u urls - X5uTrustAnchor string `json:"x5u_trust_anchor,omitempty"` - // Optional TLS trust anchor cert used when doing x5u https requests - X5uTLSTrustAnchor string `json:"x5u_tls_trust_anchor,omitempty"` +// UserSearch user search request definition. +type UserSearch struct { + Keywords string `json:"keywords,omitempty"` + Source string `json:"source,omitempty"` + UserIDs []string `json:"user_id,omitempty"` +} - X5uPrefix string `json:"x5u_prefix,omitempty"` - UsersDirectory string `json:"users_directory"` +// IdentityProviderSearch identity provider search request definition. +type IdentityProviderSearch struct { + Keywords string `json:"keywords,omitempty"` +} - Enabled bool `json:"enabled"` - Author string `json:"author"` - Created string `json:"created"` - Updated string `json:"updated,omitempty"` - UpdatedBy string `json:"updated_by,omitempty"` +// IdentityProvider identity provider definition. +type IdentityProvider struct { + ID string `json:"id"` + Name string `json:"name"` + TokenType string `json:"token_type"` + JWTIssuer string `json:"jwt_issuer"` + JWTAudience string `json:"jwt_audience"` + JWTSubjectType string `json:"jwt_subject_type"` + JWTSubjectDNUsernameAttribute string `json:"jwt_subject_dn_username_attribute,omitempty"` + CustomAttributes []CustomAttributeValidation `json:"custom_attributes,omitempty"` + PublicKeys []PublicKey `json:"public_keys,omitempty"` + PublicKeyMethod string `json:"public_key_method"` + X5uTrustAnchor string `json:"x5u_trust_anchor,omitempty"` + X5uTLSTrustAnchor string `json:"x5u_tls_trust_anchor,omitempty"` + X5uPrefix string `json:"x5u_prefix,omitempty"` + UsersDirectory string `json:"users_directory"` + Enabled bool `json:"enabled"` + Author string `json:"author"` + Created string `json:"created"` + Updated string `json:"updated,omitempty"` + UpdatedBy string `json:"updated_by,omitempty"` } +// CustomAttributeValidation identity provider custom attribute definition. type CustomAttributeValidation struct { - FieldName string `json:"field_name" validate:"required"` + FieldName string `json:"field_name"` Type string `json:"type"` ExpectedValue string `json:"expected_value"` Start string `json:"start"` End string `json:"end"` } +// PublicKey identity provider public key definition. type PublicKey struct { KeyID string `json:"key_id"` Comment string `json:"comment,omitempty"` PublicKey string `json:"public_key,omitempty"` } - -type IdentityProviderResponse struct { - Count int `json:"count"` - Items []IdentityProvider `json:"items"` -} - -type IdentityProviderSearch struct { - Keywords string `json:"keywords,omitempty"` -} - -type IdentityProviderResolveUserRequest struct { - Principal string `json:"principal"` -} -type IdentityProviderCreateResponse struct { - ID string `json:"id"` -} diff --git a/api/secretsmanager/client.go b/api/secretsmanager/client.go index a4ab671..21450aa 100644 --- a/api/secretsmanager/client.go +++ b/api/secretsmanager/client.go @@ -3,25 +3,27 @@ package secretsmanager import ( "net/url" - "github.com/SSHcom/privx-sdk-go/common" + "github.com/SSHcom/privx-sdk-go/api/filters" + "github.com/SSHcom/privx-sdk-go/api/response" "github.com/SSHcom/privx-sdk-go/restapi" ) -// Client is a secrets-manager client instance. -type Client struct { +// SecretsManager is a secrets-manager client instance. +type SecretsManager struct { api restapi.Connector } -// New creates a new secrets-manager client instance -func New(api restapi.Connector) *Client { - return &Client{api: api} +// New secrets manager client constructor. +func New(api restapi.Connector) *SecretsManager { + return &SecretsManager{api: api} } -// SecretsManagerStatus get microservice status -func (s *Client) SecretsManagerStatus() (*common.ServiceStatus, error) { - status := &common.ServiceStatus{} +// MARK: STATUS +// Status get secrets manager microservice status. +func (c *SecretsManager) Status() (*response.ServiceStatus, error) { + status := &response.ServiceStatus{} - _, err := s.api. + _, err := c.api. URL("/secrets-manager/api/v1/status"). Get(status) @@ -29,426 +31,436 @@ func (s *Client) SecretsManagerStatus() (*common.ServiceStatus, error) { } // MARK: Password Policies -// PasswordPolicies lists all password policies -func (s *Client) PasswordPolicies() (PwPolicyResult, error) { - result := PwPolicyResult{} +// GetPasswordPolicies get password policies. +func (c *SecretsManager) GetPasswordPolicies() (*response.ResultSet[PasswordPolicy], error) { + policies := &response.ResultSet[PasswordPolicy]{} - _, err := s.api. + _, err := c.api. URL("/secrets-manager/api/v1/password-policies"). - Get(&result) + Get(&policies) - return result, err + return policies, err } -// CreatePasswordPolicy create a password policy -func (s *Client) CreatePasswordPolicy(p PasswordPolicy) (string, error) { - var object struct { - ID string `json:"id"` - } +// CreatePasswordPolicy create password policy. +func (c *SecretsManager) CreatePasswordPolicy(policy *PasswordPolicy) (response.Identifier, error) { + identifier := response.Identifier{} - _, err := s.api. + _, err := c.api. URL("/secrets-manager/api/v1/password-policy"). - Post(&p, &object) + Post(&policy, &identifier) - return object.ID, err + return identifier, err } -// PasswordPolicy get password policy by id -func (s *Client) PasswordPolicy(policyId string) (*PasswordPolicy, error) { - p := &PasswordPolicy{} +// GetPasswordPolicy get password policy by id. +func (c *SecretsManager) GetPasswordPolicy(policyID string) (*PasswordPolicy, error) { + policy := &PasswordPolicy{} - _, err := s.api. - URL("/secrets-manager/api/v1/password-policy/%s", url.PathEscape(policyId)). - Get(&p) + _, err := c.api. + URL("/secrets-manager/api/v1/password-policy/%s", policyID). + Get(&policy) - return p, err + return policy, err } -// UpdatePasswordPolicy update existing password policy -func (s *Client) UpdatePasswordPolicy(policyId string, p PasswordPolicy) error { - _, err := s.api. - URL("/secrets-manager/api/v1/password-policy/%s", url.PathEscape(policyId)). - Put(p) +// UpdatePasswordPolicy update password policy. +func (c *SecretsManager) UpdatePasswordPolicy(policyID string, policy *PasswordPolicy) error { + _, err := c.api. + URL("/secrets-manager/api/v1/password-policy/%s", policyID). + Put(&policy) return err } -// DeletePasswordPolicy delete a password policy -func (s *Client) DeletePasswordPolicy(policyId string) error { - _, err := s.api. - URL("/secrets-manager/api/v1/password-policy/%s", url.PathEscape(policyId)). +// DeletePasswordPolicy delete password policy. +func (c *SecretsManager) DeletePasswordPolicy(policyID string) error { + _, err := c.api. + URL("/secrets-manager/api/v1/password-policy/%s", policyID). Delete() return err } -// MARK: Manage passwords -// RotatePassword initiate password rotation -func (s *Client) RotatePassword(hostId, account string) error { - _, err := s.api. - URL("/secrets-manager/api/v1/rotate/%s/%s", url.PathEscape(hostId), url.PathEscape(account)). +// MARK: Manage Passwords +// RotatePassword initiate password rotation. +func (c *SecretsManager) RotatePassword(hostID, account string) error { + _, err := c.api. + URL("/secrets-manager/api/v1/rotate/%s/%s", hostID, account). Post(nil) return err } -// MARK: Manage rotation scripts -// ScriptTemplates lists all script templates -func (s *Client) ScriptTemplates() (ScriptTemplateResult, error) { - result := ScriptTemplateResult{} +// MARK: Manage Rotation Scripts +// GetScriptTemplates get script templates. +func (c *SecretsManager) GetScriptTemplates() (*response.ResultSet[ScriptTemplate], error) { + templates := &response.ResultSet[ScriptTemplate]{} - _, err := s.api. + _, err := c.api. URL("/secrets-manager/api/v1/script-templates"). - Get(&result) + Get(&templates) - return result, err + return templates, err } -// CreateScriptTemplate create a script template -func (s *Client) CreateScriptTemplate(t ScriptTemplate) (string, error) { - var object struct { - ID string `json:"id"` - } +// CreateScriptTemplate create script template. +func (c *SecretsManager) CreateScriptTemplate(template *ScriptTemplate) (response.Identifier, error) { + identifier := response.Identifier{} - _, err := s.api. + _, err := c.api. URL("/secrets-manager/api/v1/script-template"). - Post(&t, &object) + Post(&template, &identifier) - return object.ID, err + return identifier, err } -// ScriptTemplate get script template by id -func (s *Client) ScriptTemplate(templateId string) (*ScriptTemplate, error) { +// GetScriptTemplate get script template by id. +func (c *SecretsManager) GetScriptTemplate(templateID string) (*ScriptTemplate, error) { p := &ScriptTemplate{} - _, err := s.api. - URL("/secrets-manager/api/v1/script-template/%s", url.PathEscape(templateId)). + _, err := c.api. + URL("/secrets-manager/api/v1/script-template/%s", templateID). Get(&p) return p, err } -// UpdateScriptTemplate update existing script template -func (s *Client) UpdateScriptTemplate(templateId string, t ScriptTemplate) error { - _, err := s.api. - URL("/secrets-manager/api/v1/script-template/%s", url.PathEscape(templateId)). - Put(t) +// UpdateScriptTemplate update script template. +func (c *SecretsManager) UpdateScriptTemplate(templateID string, template *ScriptTemplate) error { + _, err := c.api. + URL("/secrets-manager/api/v1/script-template/%s", templateID). + Put(&template) return err } -// DeleteScriptTemplate delete a script template -func (s *Client) DeleteScriptTemplate(templateId string) error { - _, err := s.api. - URL("/secrets-manager/api/v1/password-policy/%s", url.PathEscape(templateId)). +// DeleteScriptTemplate delete script template. +func (c *SecretsManager) DeleteScriptTemplate(templateID string) error { + _, err := c.api. + URL("/secrets-manager/api/v1/password-policy/%s", templateID). Delete() return err } -// CompileScript compile script with test data -func (s *Client) CompileScript(r CompileScriptRequest) (string, error) { - var object struct { - Script string `json:"script"` - } +// CompileScript compile script with test data. +func (c *SecretsManager) CompileScript(compile CompileScript) (CompileScriptResponse, error) { + compiled := CompileScriptResponse{} - _, err := s.api. + _, err := c.api. URL("/secrets-manager/api/v1/script-template/compile"). - Post(&r, &object) + Post(&compile, &compiled) - return object.Script, err + return compiled, err } -// MARK: Target domains -// TargetDomains lists all target domains -func (s *Client) TargetDomains(offset, limit int, sortkey, sortdir string) (TdResult, error) { - result := TdResult{} - filters := Params{ - Offset: offset, - Limit: limit, - Sortkey: sortkey, - Sortdir: sortdir, +// MARK: Manage Secrets +// GetHostSecretMetadata get host secret metadata for all accounts. +func (c *SecretsManager) GetHostSecretMetadata(hostID string) (*PostHostSecret, error) { + secret := &PostHostSecret{} + + _, err := c.api. + URL("/secrets-manager/api/v1/host-secret/%s", hostID). + Get(&secret) + + return secret, err +} + +// CreateHostSecret create host secret. +func (c *SecretsManager) CreateHostSecret(hostID string, secret *PostHostSecret) (*PostHostSecret, error) { + hostSecret := &PostHostSecret{} + + _, err := c.api. + URL("/secrets-manager/api/v1/host-secret/%s", hostID). + Post(&secret, &hostSecret) + + return hostSecret, err +} + +// DeleteHostSecret delete host secret. +func (c *SecretsManager) DeleteHostSecret(hostID string) error { + _, err := c.api. + URL("/secrets-manager/api/v1/host-secret/%s", hostID). + Delete() + + return err +} + +// MARK: Target Domains +// GetTargetDomains get target domains. +func (c *SecretsManager) GetTargetDomains(opts ...filters.Option) (*response.ResultSet[TargetDomain], error) { + tds := &response.ResultSet[TargetDomain]{} + params := url.Values{} + + for _, opt := range opts { + opt(¶ms) } - _, err := s.api. + _, err := c.api. URL("/secrets-manager/api/v1/targetdomains"). - Query(&filters). - Get(&result) + Query(params). + Get(&tds) - return result, err + return tds, err } -// CreateTargetDomain create a target domain -func (s *Client) CreateTargetDomain(td TargetDomain) (string, error) { - var object struct { - ID string `json:"id"` - } +// CreateTargetDomain create target domain. +func (c *SecretsManager) CreateTargetDomain(td *TargetDomain) (response.Identifier, error) { + identifier := response.Identifier{} - _, err := s.api. + _, err := c.api. URL("/secrets-manager/api/v1/targetdomains"). - Post(&td, &object) + Post(&td, &identifier) - return object.ID, err + return identifier, err } -// SearchTargetDomain search for existing target domain -func (s *Client) SearchTargetDomain(sortkey, sortdir string, offset, limit int, searchObject TargetDomainsSearch) (TdResult, error) { - result := TdResult{} - filters := Params{ - Offset: offset, - Limit: limit, - Sortkey: sortkey, - Sortdir: sortdir, +// SearchTargetDomain search target domains. +func (c *SecretsManager) SearchTargetDomain(search TargetDomainsSearch, opts ...filters.Option) (*response.ResultSet[TargetDomain], error) { + tds := &response.ResultSet[TargetDomain]{} + params := url.Values{} + + for _, opt := range opts { + opt(¶ms) } - _, err := s.api. + _, err := c.api. URL("/secrets-manager/api/v1/targetdomains/search"). - Query(&filters). - Post(&searchObject, &result) + Query(params). + Post(&search, &tds) - return result, err + return tds, err } -// TargetDomain get target domain by id -func (s *Client) TargetDomain(tdId string) (*TargetDomain, error) { +// GetTargetDomain get target domain by id. +func (c *SecretsManager) GetTargetDomain(tdID string) (*TargetDomain, error) { td := &TargetDomain{} - _, err := s.api. - URL("/secrets-manager/api/v1/targetdomains/%s", url.PathEscape(tdId)). + _, err := c.api. + URL("/secrets-manager/api/v1/targetdomains/%s", tdID). Get(&td) return td, err } -// UpdateTargetDomain update existing target domain -func (s *Client) UpdateTargetDomain(tdId string, td TargetDomain) error { - _, err := s.api. - URL("/secrets-manager/api/v1/targetdomains/%s", url.PathEscape(tdId)). - Put(td) +// UpdateTargetDomain update target domain. +func (c *SecretsManager) UpdateTargetDomain(tdID string, td *TargetDomain) error { + _, err := c.api. + URL("/secrets-manager/api/v1/targetdomains/%s", tdID). + Put(&td) return err } -// DeleteTargetDomain delete a target domain -func (s *Client) DeleteTargetDomain(tdId string) error { - _, err := s.api. - URL("/secrets-manager/api/v1/targetdomains/%s", url.PathEscape(tdId)). +// DeleteTargetDomain delete target domain. +func (c *SecretsManager) DeleteTargetDomain(tdID string) error { + _, err := c.api. + URL("/secrets-manager/api/v1/targetdomains/%s", tdID). Delete() return err } -// RefreshTargetDomain trigger target domain account scan -func (s *Client) RefreshTargetDomain(tdId string) error { - _, err := s.api. - URL("/secrets-manager/api/v1/targetdomains/%s/refresh", url.PathEscape(tdId)). +// RefreshTargetDomain trigger target domain account scan. +func (c *SecretsManager) RefreshTargetDomain(tdID string) error { + _, err := c.api. + URL("/secrets-manager/api/v1/targetdomains/%s/refresh", tdID). Post(nil) return err } // MARK: Target domain accounts -// TargetDomainAccounts lists all accounts in target domain -func (s *Client) TargetDomainAccounts(offset, limit int, sortkey, sortdir, tdId string) (ScannedAccountResult, error) { - result := ScannedAccountResult{} - filters := Params{ - Offset: offset, - Limit: limit, - Sortkey: sortkey, - Sortdir: sortdir, +// GetTargetDomainAccounts get accounts in target domain. +func (c *SecretsManager) GetTargetDomainAccounts(tdID string, opts ...filters.Option) (*response.ResultSet[ScannedAccount], error) { + accounts := &response.ResultSet[ScannedAccount]{} + params := url.Values{} + + for _, opt := range opts { + opt(¶ms) } - _, err := s.api. - URL("/secrets-manager/api/v1/targetdomains/%s/accounts", url.PathEscape(tdId)). - Query(&filters). - Get(&result) + _, err := c.api. + URL("/secrets-manager/api/v1/targetdomains/%s/accounts", tdID). + Query(params). + Get(&accounts) - return result, err + return accounts, err } -// SearchTargetDomainAccounts search accounts in target domain -func (s *Client) SearchTargetDomainAccounts(sortkey, sortdir, tdId string, offset, limit int, searchObject ScannedAccountsSearch) (ScannedAccountResult, error) { - result := ScannedAccountResult{} - filters := Params{ - Offset: offset, - Limit: limit, - Sortkey: sortkey, - Sortdir: sortdir, +// SearchTargetDomainAccounts search accounts in target domain. +func (c *SecretsManager) SearchTargetDomainAccounts(tdID string, search ScannedAccountsSearch, opts ...filters.Option) (*response.ResultSet[ScannedAccount], error) { + accounts := &response.ResultSet[ScannedAccount]{} + params := url.Values{} + + for _, opt := range opts { + opt(¶ms) } - _, err := s.api. - URL("/secrets-manager/api/v1/targetdomains/%s/accounts/search", url.PathEscape(tdId)). - Query(&filters). - Post(&searchObject, &result) + _, err := c.api. + URL("/secrets-manager/api/v1/targetdomains/%s/accounts/search", tdID). + Query(params). + Post(&search, &accounts) - return result, err + return accounts, err } -// TargetDomainAccount get target domain account -func (s *Client) TargetDomainAccount(tdId, accountId string) (ScannedAccount, error) { - account := ScannedAccount{} +// GetTargetDomainAccount get target domain account by id. +func (c *SecretsManager) GetTargetDomainAccount(tdID, accountID string) (*ScannedAccount, error) { + account := &ScannedAccount{} - _, err := s.api. - URL("/secrets-manager/api/v1/targetdomains/%s/accounts/%s", url.PathEscape(tdId), url.PathEscape(accountId)). + _, err := c.api. + URL("/secrets-manager/api/v1/targetdomains/%s/accounts/%s", tdID, accountID). Get(&account) return account, err } -// UpdateTargetDomainAccount update target domain account -func (s *Client) UpdateTargetDomainAccount(tdId, accountId string, change ScannedAccountChangeSet) error { - _, err := s.api. - URL("/secrets-manager/api/v1/targetdomains/%s/accounts/%s", url.PathEscape(tdId), url.PathEscape(accountId)). - Put(change) +// UpdateTargetDomainAccount update target domain account. +func (c *SecretsManager) UpdateTargetDomainAccount(tdID, accountID string, change ScannedAccountChangeSet) error { + _, err := c.api. + URL("/secrets-manager/api/v1/targetdomains/%s/accounts/%s", tdID, accountID). + Put(&change) return err } -// BatchUpdateTargetDomain update target domain in batch -func (s *Client) BatchUpdateTargetDomain(tdId string, change ScannedAccountEditBatch) error { - _, err := s.api. - URL("/secrets-manager/api/v1/targetdomains/%s/accounts/batch/edit", url.PathEscape(tdId)). - Post(change) +// BatchUpdateTargetDomain update target domain in batch. +func (c *SecretsManager) BatchUpdateTargetDomain(tdID string, edit ScannedAccountEditBatch) error { + _, err := c.api. + URL("/secrets-manager/api/v1/targetdomains/%s/accounts/batch/edit", tdID). + Post(edit) return err } // MARK: Managed accounts -// ManagedAccounts lists all managed accounts in a target domain -func (s *Client) ManagedAccounts(offset, limit int, sortkey, sortdir, tdId string) (ManagedAccountResult, error) { - result := ManagedAccountResult{} - filters := Params{ - Offset: offset, - Limit: limit, - Sortkey: sortkey, - Sortdir: sortdir, +// GetManagedAccounts get managed accounts in a target domain. +func (c *SecretsManager) GetManagedAccounts(tdID string, opts ...filters.Option) (*response.ResultSet[ManagedAccount], error) { + accounts := &response.ResultSet[ManagedAccount]{} + params := url.Values{} + + for _, opt := range opts { + opt(¶ms) } - _, err := s.api. - URL("/secrets-manager/api/v1/targetdomains/%s/managedaccounts", url.PathEscape(tdId)). - Query(&filters). - Get(&result) + _, err := c.api. + URL("/secrets-manager/api/v1/targetdomains/%s/managedaccounts", tdID). + Query(params). + Get(&accounts) - return result, err + return accounts, err } -// CreateManagedAccount create a managed account -func (s *Client) CreateManagedAccount(tdId string, ma ManagedAccount) (string, error) { - var object struct { - ID string `json:"id"` - } +// CreateManagedAccount create a managed account. +func (c *SecretsManager) CreateManagedAccount(tdID string, account *ManagedAccount) (response.Identifier, error) { + identifier := response.Identifier{} - _, err := s.api. - URL("/secrets-manager/api/v1/targetdomains/%s/managedaccounts", url.PathEscape(tdId)). - Post(&ma, &object) + _, err := c.api. + URL("/secrets-manager/api/v1/targetdomains/%s/managedaccounts", tdID). + Post(&account, &identifier) - return object.ID, err + return identifier, err } -// SearchManagedAccounts search managed accounts in a target domain -func (s *Client) SearchManagedAccounts(sortkey, sortdir, tdId string, offset, limit int, searchObject ManagedAccountsSearch) (ManagedAccountResult, error) { - result := ManagedAccountResult{} - filters := Params{ - Offset: offset, - Limit: limit, - Sortkey: sortkey, - Sortdir: sortdir, +// SearchManagedAccounts search managed accounts in a target domain. +func (c *SecretsManager) SearchManagedAccounts(tdID string, search ManagedAccountsSearch, opts ...filters.Option) (*response.ResultSet[ManagedAccount], error) { + accounts := &response.ResultSet[ManagedAccount]{} + params := url.Values{} + + for _, opt := range opts { + opt(¶ms) } - _, err := s.api. - URL("/secrets-manager/api/v1/targetdomains/%s/managedaccounts/search", url.PathEscape(tdId)). - Query(&filters). - Post(&searchObject, &result) + _, err := c.api. + URL("/secrets-manager/api/v1/targetdomains/%s/managedaccounts/search", tdID). + Query(params). + Post(&search, &accounts) - return result, err + return accounts, err } -// ManagedAccount get managed account -func (s *Client) ManagedAccount(tdId, maId string) (ManagedAccount, error) { - account := ManagedAccount{} +// GetManagedAccount get managed account in target domain by id. +func (c *SecretsManager) GetManagedAccount(tdID, maID string) (*ManagedAccount, error) { + account := &ManagedAccount{} - _, err := s.api. - URL("/secrets-manager/api/v1/targetdomains/%s/managedaccounts/%s", url.PathEscape(tdId), url.PathEscape(maId)). + _, err := c.api. + URL("/secrets-manager/api/v1/targetdomains/%s/managedaccounts/%s", tdID, maID). Get(&account) return account, err } -// UpdateTargetManagedAccount update managed account -func (s *Client) UpdateTargetManagedAccount(tdId, maId string, change ManagedAccount) error { - _, err := s.api. - URL("/secrets-manager/api/v1/targetdomains/%s/managedaccounts/%s", url.PathEscape(tdId), url.PathEscape(maId)). - Put(change) +// UpdateTargetManagedAccount update managed account. +func (c *SecretsManager) UpdateTargetManagedAccount(tdID, maID string, account *ManagedAccount) error { + _, err := c.api. + URL("/secrets-manager/api/v1/targetdomains/%s/managedaccounts/%s", tdID, maID). + Put(&account) return err } -// DeleteManagedAccount delete managed account -func (s *Client) DeleteManagedAccount(tdId, maId string) error { - _, err := s.api. - URL("/secrets-manager/api/v1/targetdomains/%s/managedaccounts/%s", url.PathEscape(tdId), url.PathEscape(maId)). +// DeleteManagedAccount delete managed account. +func (c *SecretsManager) DeleteManagedAccount(tdID, maID string) error { + _, err := c.api. + URL("/secrets-manager/api/v1/targetdomains/%s/managedaccounts/%s", tdID, maID). Delete() return err } -// RotateManagedAccountPassword trigger managed account password rotation -func (s *Client) RotateManagedAccountPassword(tdId, maId string) error { - _, err := s.api. - URL("/secrets-manager/api/v1/targetdomains/%s/managedaccounts/%s/rotate", url.PathEscape(tdId), url.PathEscape(maId)). +// RotateManagedAccountPassword trigger managed account password rotation. +func (c *SecretsManager) RotateManagedAccountPassword(tdID, maID string) error { + _, err := c.api. + URL("/secrets-manager/api/v1/targetdomains/%s/managedaccounts/%s/rotate", tdID, maID). Post(nil) return err } -// ManagedAccountPassword provide password for managed account -func (s *Client) ManagedAccountPassword(tdId, maId, password string) error { - pwReq := ManagedAccountPasswordRequest{ - Password: password, - } - - _, err := s.api. - URL("/secrets-manager/api/v1/targetdomains/%s/managedaccounts/%s/password", url.PathEscape(tdId), url.PathEscape(maId)). - Post(pwReq) +// SetManagedAccountPassword set password for managed account. +func (c *SecretsManager) SetManagedAccountPassword(tdID, maID, password ManagedAccountPasswordSet) error { + _, err := c.api. + URL("/secrets-manager/api/v1/targetdomains/%s/managedaccounts/%s/password", tdID, maID). + Post(&password) return err } -// BatchCreateManagedAccount create a batch of managed accounts -func (s *Client) BatchCreateManagedAccount(tdId string, ma ManagedAccountCreateBatch) ([]string, error) { - var object struct { - IDs []string `json:"ids"` - } +// BatchCreateManagedAccount create a batch of managed accounts. +func (c *SecretsManager) BatchCreateManagedAccount(tdID string, create ManagedAccountCreateBatch) (IDList, error) { + ids := IDList{} - _, err := s.api. - URL("/secrets-manager/api/v1/targetdomains/%s/managedaccounts/batch/create", url.PathEscape(tdId)). - Post(&ma, &object) + _, err := c.api. + URL("/secrets-manager/api/v1/targetdomains/%s/managedaccounts/batch/create", tdID). + Post(&create, &ids) - return object.IDs, err + return ids, err } -// BatchUpdateManagedAccount update a batch of managed accounts -func (s *Client) BatchUpdateManagedAccount(tdId string, change ManagedAccountChangeSet) error { - _, err := s.api. - URL("/secrets-manager/api/v1/targetdomains/%s/managedaccounts/batch/edit", url.PathEscape(tdId)). +// BatchUpdateManagedAccount update a batch of managed accounts. +func (c *SecretsManager) BatchUpdateManagedAccount(tdID string, change *ManagedAccountEditBatch) error { + _, err := c.api. + URL("/secrets-manager/api/v1/targetdomains/%s/managedaccounts/batch/edit", tdID). Post(&change) return err } -// BatchDeleteManagedAccount delete a batch of managed accounts -func (s *Client) BatchDeleteManagedAccount(tdId string, delete ManagedAccountBatch) error { - _, err := s.api. - URL("/secrets-manager/api/v1/targetdomains/%s/managedaccounts/batch/delete", url.PathEscape(tdId)). +// BatchDeleteManagedAccount delete a batch of managed accounts. +func (c *SecretsManager) BatchDeleteManagedAccount(tdID string, delete ManagedAccountDeleteBatch) error { + _, err := c.api. + URL("/secrets-manager/api/v1/targetdomains/%s/managedaccounts/batch/delete", tdID). Post(&delete) return err } -// BatchRotateManagedAccount rotate a batch of managed accounts -func (s *Client) BatchRotateManagedAccount(tdId string, rotate ManagedAccountBatch) error { - _, err := s.api. - URL("/secrets-manager/api/v1/targetdomains/%s/managedaccounts/batch/rotate", url.PathEscape(tdId)). +// BatchRotateManagedAccount rotate a batch of managed accounts. +func (c *SecretsManager) BatchRotateManagedAccount(tdID string, rotate ManagedAccountRotateBatch) error { + _, err := c.api. + URL("/secrets-manager/api/v1/targetdomains/%s/managedaccounts/batch/rotate", tdID). Post(&rotate) return err diff --git a/api/secretsmanager/model.go b/api/secretsmanager/model.go index 78188af..9c28f11 100644 --- a/api/secretsmanager/model.go +++ b/api/secretsmanager/model.go @@ -2,13 +2,46 @@ package secretsmanager import "time" -type Params struct { - Offset int `json:"offset,omitempty"` - Limit int `json:"limit,omitempty"` - Sortdir string `json:"sortdir,omitempty"` - Sortkey string `json:"sortkey,omitempty"` +// PostHostSecret host secret metadata definition. +type PostHostSecret struct { + Metadata HostSecret `json:"metadata" validate:"required"` + Accounts []AccountSecret `json:"accounts" validate:"required"` } +// AccountSecret account secret definition. +type AccountSecret struct { + Account string `json:"account"` + HostID string `json:"host_id"` + RotationInitiated *time.Time `json:"rotation_initiated"` + LastRotated *time.Time `json:"last_rotated"` + LastError *time.Time `json:"last_error"` + LastErrorDetails string `json:"last_error_details"` + InitialPassword string `json:"initial_password,omitempty"` + Created *time.Time `json:"created"` + CreatedBy string `json:"created_by"` +} + +// HostSecret host secret definition. +type HostSecret struct { + HostID string `json:"host_id"` + AccessGroupID string `json:"access_group_id"` + Address string `json:"address"` + Port int `json:"port"` + OperatingSystem string `json:"operating_system"` + Protocol string `json:"protocol"` + CertificateValidationOptions string `json:"certificate_validation_options"` + WinRMHostCertificateTrustAnchors string `json:"winrm_host_certificate_trust_anchors"` + UseMainAccount bool `json:"use_main_account"` + MainAccount string `json:"main_account"` + PolicyID string `json:"policy_id"` + ScriptTemplateID string `json:"script_template_id"` + Created *time.Time `json:"created"` + CreatedBy string `json:"created_by"` + Updated *time.Time `json:"updated"` + UpdatedBy string `json:"updated_by"` +} + +// PasswordPolicy password policy definition. type PasswordPolicy struct { ID string `json:"id"` Name string `json:"name"` @@ -32,6 +65,7 @@ type PasswordPolicy struct { UpdatedBy string `json:"updated_by"` } +// ScriptTemplate script template definition. type ScriptTemplate struct { ID string `json:"id"` Name string `json:"name"` @@ -43,11 +77,18 @@ type ScriptTemplate struct { UpdatedBy string `json:"updated_by"` } -type CompileScriptRequest struct { +// CompileScript compile script request definition. +type CompileScript struct { OperatingSystem string `json:"operating_system"` Script string `json:"script"` } +// CompileScriptResponse compile script response definition. +type CompileScriptResponse struct { + Script string `json:"script"` +} + +// TargetDomain target domain definition. type TargetDomain struct { ID string `json:"id"` Name string `json:"name"` @@ -68,14 +109,15 @@ type TargetDomain struct { UpdatedBy string `json:"updated_by,omitempty"` } +// PasswordPolicyHandle password policy handle definition. type PasswordPolicyHandle struct { ID string `json:"id,omitempty"` Name string `json:"name,omitempty"` Deleted bool `json:"deleted,omitempty"` } +// TargetDomainEndpoint target domain endpoint definition. type TargetDomainEndpoint struct { - TargetDomainID string `json:"-"` Type string `json:"type"` ScanPriority int `json:"scan_priority"` RotationPriority int `json:"rotation_priority"` @@ -105,6 +147,7 @@ type TargetDomainsSearch struct { AutoOnboarding *bool `json:"auto_onboarding,omitempty"` } +// ScannedAccount scanned account definition. type ScannedAccount struct { ID string `json:"id"` Username string `json:"username"` @@ -122,12 +165,14 @@ type ScannedAccount struct { UpdatedBy string `json:"updated_by,omitempty"` } +// TargetDomainHandle target domain handle definition. type TargetDomainHandle struct { ID string `json:"id"` Name string `json:"name,omitempty"` Deleted bool `json:"deleted,omitempty"` } +// ScannedAccountsSearch scanned account search request definition. type ScannedAccountsSearch struct { Keywords string `json:"keywords,omitempty"` CreatedAfter *time.Time `json:"created_after,omitempty"` @@ -138,16 +183,19 @@ type ScannedAccountsSearch struct { Ignored *bool `json:"ignored,omitempty"` } +// ScannedAccountChangeSet scanned account change set definition. type ScannedAccountChangeSet struct { Ignored *bool `json:"ignored,omitempty"` Comment *string `json:"comment,omitempty"` } +// ScannedAccountEditBatch scanned account edit batch request definition. type ScannedAccountEditBatch struct { IDs []string `json:"ids"` ChangeSet ScannedAccountChangeSet `json:"changes"` } +// ManagedAccount managed account definition. type ManagedAccount struct { ID string `json:"id"` Username string `json:"username"` @@ -173,9 +221,10 @@ type ManagedAccount struct { Author string `json:"author,omitempty"` Updated *time.Time `json:"updated,omitempty"` UpdatedBy string `json:"updated_by,omitempty"` - DisableRdpCertAuth bool `json:"disable_rdp_cert_auth"` + DisableRDPCertAuth bool `json:"disable_rdp_cert_auth"` } +// SecretRotationEvent secret rotation event definition. type SecretRotationEvent struct { Version int `json:"version"` Rotated time.Time `json:"rotated"` @@ -183,6 +232,7 @@ type SecretRotationEvent struct { Status string `json:"status"` } +// SecretCheckout secret checkout definition. type SecretCheckout struct { ID string `json:"id"` Type string `json:"type"` @@ -201,12 +251,14 @@ type SecretCheckout struct { Meta string `json:"meta,omitempty"` } +// SecretVersion secret version definition. type SecretVersion struct { Version int `json:"version"` Secret string `json:"secret"` Created time.Time `json:"created"` } +// ManagedAccountsSearch managed account search request definition. type ManagedAccountsSearch struct { Keywords string `json:"keywords,omitempty"` Enabled *bool `json:"enabled,omitempty"` @@ -219,21 +271,29 @@ type ManagedAccountsSearch struct { ExplicitCheckout *bool `json:"explicit_checkout,omitempty"` } -type ManagedAccountPasswordRequest struct { +// ManagedAccountPasswordSet manage account password set request definition. +type ManagedAccountPasswordSet struct { Password string `json:"password"` } +// IDList id list response definition. +type IDList struct { + IDs []string `json:"ids"` +} + +// ManagedAccountCreateBatch managed account create batch definition. type ManagedAccountCreateBatch struct { IDs []string `json:"ids"` Data ManagedAccountCreateData `json:"data"` } +// ManagedAccountCreateData managed account batch create data definition. type ManagedAccountCreateData struct { Enabled bool `json:"enabled"` RotationEnabled bool `json:"rotation_enabled"` Rotate bool `json:"rotate"` ExplicitCheckout bool `json:"explicit_checkout"` - DisableRdpCertAuth bool `json:"disable_rdp_cert_auth"` + DisableRDPCertAuth bool `json:"disable_rdp_cert_auth"` PasswordPolicy PasswordPolicyHandle `json:"password_policy,omitempty"` Comment string `json:"comment,omitempty"` } @@ -243,40 +303,23 @@ type ManagedAccountEditBatch struct { ChangeSet ManagedAccountChangeSet `json:"changes"` } +// ManagedAccountChangeSet manage account change set request definition. type ManagedAccountChangeSet struct { Enabled *bool `json:"enabled"` RotationEnabled *bool `json:"rotation_enabled"` ExplicitCheckout *bool `json:"explicit_checkout"` - DisableRdpCertAuth *bool `json:"disable_rdp_cert_auth"` + DisableRDPCertAuth *bool `json:"disable_rdp_cert_auth"` PasswordPolicy *PasswordPolicyHandle `json:"password_policy,omitempty"` Comment *string `json:"comment,omitempty"` } -type ManagedAccountBatch struct { +// ManagedAccountDeleteBatch manage account batch delete request definition. +type ManagedAccountDeleteBatch struct { IDs []string `json:"ids"` } -type PwPolicyResult struct { - Count int `json:"count"` - Items []PasswordPolicy `json:"items"` -} - -type ScriptTemplateResult struct { - Count int `json:"count"` - Items []ScriptTemplate `json:"items"` -} - -type TdResult struct { - Count int `json:"count"` - Items []TargetDomain `json:"items"` -} - -type ScannedAccountResult struct { - Count int `json:"count"` - Items []ScannedAccount `json:"items"` -} +// ManagedAccountRotateBatch manage account batch rotate request definition. -type ManagedAccountResult struct { - Count int `json:"count"` - Items []ManagedAccount `json:"items"` +type ManagedAccountRotateBatch struct { + IDs []string `json:"ids"` } From 414067f172610136a647939b83c1521234cf1046 Mon Sep 17 00:00:00 2001 From: iljaSL Date: Tue, 12 Nov 2024 14:59:49 +0200 Subject: [PATCH 4/5] refactor(v2): add refactored state of userstore and vault --- api/userstore/client.go | 326 +++++++++++++++++++--------------------- api/userstore/model.go | 177 +++++++++++----------- api/vault/client.go | 206 +++++++++++++++++++++++++ api/vault/model.go | 46 +++--- api/vault/vault.go | 278 ---------------------------------- 5 files changed, 475 insertions(+), 558 deletions(-) create mode 100644 api/vault/client.go delete mode 100644 api/vault/vault.go diff --git a/api/userstore/client.go b/api/userstore/client.go index e63da73..26b669e 100644 --- a/api/userstore/client.go +++ b/api/userstore/client.go @@ -9,260 +9,246 @@ package userstore import ( "net/url" - "github.com/SSHcom/privx-sdk-go/api/rolestore" + "github.com/SSHcom/privx-sdk-go/api/filters" + "github.com/SSHcom/privx-sdk-go/api/response" "github.com/SSHcom/privx-sdk-go/restapi" ) -// UserStore is a role-store client instance. +// UserStore is a local user store client instance. type UserStore struct { api restapi.Connector } -type usersResult struct { - Count int `json:"count"` - Items []LocalUser `json:"items"` +// New local user store client constructor. +func New(api restapi.Connector) *UserStore { + return &UserStore{api: api} } -type tagsResult struct { - Count int `json:"count"` - Items []string `json:"items"` -} +// MARK: Status +// Status get local user store microservice status. +func (c *UserStore) Status() (*response.ServiceStatus, error) { + status := &response.ServiceStatus{} -type clientsResult struct { - Count int `json:"count"` - Items []TrustedClient `json:"items"` -} + _, err := c.api. + URL("/local-user-store/api/v1/status"). + Get(status) -// New creates a new user-store client instance -func New(api restapi.Connector) *UserStore { - return &UserStore{api: api} + return status, err } -// LocalUsers returns user details from all known local users -func (store *UserStore) LocalUsers(offset, limit int, userID, username string) ([]LocalUser, error) { - result := usersResult{} - filters := FilterUser{ - Params: Params{ - Offset: offset, - Limit: limit, - }, - UserID: userID, - Username: username, +// MARK: API Client +// GetAPIClients get registered api clients. +func (c *UserStore) GetAPIClients(opts ...filters.Option) (*response.ResultSet[APIClient], error) { + clients := &response.ResultSet[APIClient]{} + params := url.Values{} + + for _, opt := range opts { + opt(¶ms) } - _, err := store.api. - URL("/local-user-store/api/v1/users"). - Query(&filters). - Get(&result) + _, err := c.api. + URL("/local-user-store/api/v1/api-clients"). + Query(params). + Get(&clients) - return result.Items, err + return clients, err } -// CreateLocalUser create a new local PrivX user -func (store *UserStore) CreateLocalUser(newUser LocalUser) (string, error) { - var object struct { - ID string `json:"id"` - } +// CreateAPIClient create api client. +func (c *UserStore) CreateAPIClient(client *APIClientCreate) (response.Identifier, error) { + identifier := response.Identifier{} - _, err := store.api. - URL("/local-user-store/api/v1/users"). - Post(newUser, &object) + _, err := c.api. + URL("/local-user-store/api/v1/api-clients"). + Post(&client, &identifier) - return object.ID, err + return identifier, err } -// LocalUser returns details about the local user -func (store *UserStore) LocalUser(userID string) (*LocalUser, error) { - user := &LocalUser{} +// SearchAPIClients search api clients. +func (c *UserStore) SearchAPIClients(search *APIClientSearch) (*response.ResultSet[APIClient], error) { + clients := &response.ResultSet[APIClient]{} - _, err := store.api. - URL("/local-user-store/api/v1/users/%s", url.PathEscape(userID)). - Get(user) + _, err := c.api. + URL("/local-user-store/api/v1/api-clients/search"). + Post(search, &clients) - return user, err + return clients, err } -// UpdateLocalUser update existing local user -func (store *UserStore) UpdateLocalUser(userID string, localUser *LocalUser) error { - _, err := store.api. - URL("/local-user-store/api/v1/users/%s", url.PathEscape(userID)). - Put(localUser) +// GetAPIClient get api client by id. +func (c *UserStore) GetAPIClient(clientID string) (*APIClient, error) { + client := &APIClient{} - return err + _, err := c.api. + URL("/local-user-store/api/v1/api-clients/%s", clientID). + Get(client) + + return client, err } -// DeleteLocalUser delete a local user -func (store *UserStore) DeleteLocalUser(userID string) error { - _, err := store.api. - URL("/local-user-store/api/v1/users/%s", userID). - Delete() +// UpdateAPIClient update api client. +func (c *UserStore) UpdateAPIClient(clientID string, client *APIClient) error { + _, err := c.api. + URL("/local-user-store/api/v1/api-clients/%s", clientID). + Put(&client) return err } -// UpdateLocalUserPassword update existing local user password -func (store *UserStore) UpdateLocalUserPassword(userID string, password *Password) error { - _, err := store.api. - URL("/local-user-store/api/v1/users/%s/password", url.PathEscape(userID)). - Put(password) +// DeleteAPIClient delete api client. +func (c *UserStore) DeleteAPIClient(clientID string) error { + _, err := c.api. + URL("/local-user-store/api/v1/api-clients/%s", clientID). + Delete() return err } -// LocalUserTags returns local user tags -func (store *UserStore) LocalUserTags(offset, limit int, sortdir, query string) ([]string, error) { - result := tagsResult{} - filters := FilterUser{ - Params: Params{ - Offset: offset, - Limit: limit, - Sortdir: sortdir, - Query: query, - }, - } +// MARK: Extender Clients +// GetExtenderClients get extender clients. +func (c *UserStore) GetExtenderClients() (*response.ResultSet[ExtenderClient], error) { + clients := &response.ResultSet[ExtenderClient]{} - _, err := store.api. - URL("/local-user-store/api/v1/users/tags"). - Query(&filters). - Get(&result) + _, err := c.api. + URL("/local-user-store/api/v1/extender-clients"). + Get(&clients) - return result.Items, err + return clients, err } -// TrustedClients fetches all known trusted clients -func (store *UserStore) TrustedClients() ([]TrustedClient, error) { - var object struct { - Items []TrustedClient +// MARK: Users +// GetUsers get local users. +func (c *UserStore) GetUsers(opts ...filters.Option) (*response.ResultSet[LocalUser], error) { + users := &response.ResultSet[LocalUser]{} + params := url.Values{} + + for _, opt := range opts { + opt(¶ms) } - _, err := store.api. - URL("/local-user-store/api/v1/trusted-clients"). - Get(&object) + _, err := c.api. + URL("/local-user-store/api/v1/users"). + Query(params). + Get(&users) - return object.Items, err + return users, err } -// CreateTrustedClient registers new client to PrivX -func (store *UserStore) CreateTrustedClient(client TrustedClient) (string, error) { - var object struct { - ID string `json:"id"` - } +// CreateUser create local user. +func (c *UserStore) CreateUser(user *LocalUser) (response.Identifier, error) { + identifier := response.Identifier{} - _, err := store.api. - URL("/local-user-store/api/v1/trusted-clients"). - Post(client, &object) + _, err := c.api. + URL("/local-user-store/api/v1/users"). + Post(&user, &identifier) - return object.ID, err + return identifier, err } -// TrustedClient returns details about the client -func (store *UserStore) TrustedClient(clientID string) (*TrustedClient, error) { - client := &TrustedClient{} - - _, err := store.api. - URL("/local-user-store/api/v1/trusted-clients/%s", clientID). - Get(client) +// GetUser get local user by id. +func (c *UserStore) GetUser(userID string) (*LocalUser, error) { + user := &LocalUser{} - if err != nil { - return nil, err - } + _, err := c.api. + URL("/local-user-store/api/v1/users/%s", userID). + Get(&user) - return client, nil + return user, err } -// DeleteTrustedClient removes the client -func (store *UserStore) DeleteTrustedClient(clientID string) error { - _, err := store.api. - URL("/local-user-store/api/v1/trusted-clients/%s", clientID). - Delete() +// UpdateUser update local user. +func (c *UserStore) UpdateUser(userID string, user *LocalUser) error { + _, err := c.api. + URL("/local-user-store/api/v1/users/%s", userID). + Put(user) return err } -// UpdateTrustedClient update existing trusted client -func (store *UserStore) UpdateTrustedClient(clientID string, client *TrustedClient) error { - _, err := store.api. - URL("/local-user-store/api/v1/trusted-clients/%s", url.PathEscape(clientID)). - Put(client) +// DeleteUser delete local user. +func (c *UserStore) DeleteUser(userID string) error { + _, err := c.api. + URL("/local-user-store/api/v1/users/%s", userID). + Delete() return err } -// ExtenderClients returns a list of extender client names and types -func (store *UserStore) ExtenderClients() ([]TrustedClient, error) { - result := clientsResult{} - - _, err := store.api. - URL("/local-user-store/api/v1/extender-clients"). - Get(&result) +// UpdateUserPassword update local user password. +func (c *UserStore) UpdateUserPassword(userID string, password LocalUserPassword) error { + _, err := c.api. + URL("/local-user-store/api/v1/users/%s/password", userID). + Put(password) - return result.Items, err + return err } -// APIClients returns list of all registered api clients -func (store *UserStore) APIClients() ([]APIClient, error) { - var object struct { - Items []APIClient +// GetUserTags get local user tags. +func (c *UserStore) GetUserTags(opts ...filters.Option) (*response.ResultSet[string], error) { + tags := &response.ResultSet[string]{} + params := url.Values{} + + for _, opt := range opts { + opt(¶ms) } - _, err := store.api. - URL("/local-user-store/api/v1/api-clients"). - Get(&object) + _, err := c.api. + URL("/local-user-store/api/v1/users/tags"). + Query(params). + Get(&tags) - return object.Items, err + return tags, err } -// CreateAPIClient creates new API client -func (store *UserStore) CreateAPIClient(name string, roles []string) (string, error) { - var object struct { - ID string `json:"id"` - } +// MARK: Trusted Clients +// GetTrustedClients get trusted clients. +func (c *UserStore) GetTrustedClients() (*response.ResultSet[TrustedClient], error) { + clients := &response.ResultSet[TrustedClient]{} + + _, err := c.api. + URL("/local-user-store/api/v1/trusted-clients"). + Get(&clients) - req := struct { - Name string `json:"name"` - Roles []rolestore.RoleRef `json:"roles"` - }{Name: name, Roles: []rolestore.RoleRef{}} + return clients, err +} - for _, role := range roles { - req.Roles = append(req.Roles, rolestore.RoleRef{ID: role}) - } +// CreateTrustedClient created trusted client. +func (c *UserStore) CreateTrustedClient(client *TrustedClient) (response.Identifier, error) { + identifier := response.Identifier{} - _, err := store.api. - URL("/local-user-store/api/v1/api-clients"). - Post(req, &object) + _, err := c.api. + URL("/local-user-store/api/v1/trusted-clients"). + Post(&client, &identifier) - return object.ID, err + return identifier, err } -// APIClient returns details about API client -func (store *UserStore) APIClient(clientID string) (*APIClient, error) { - client := &APIClient{} - - _, err := store.api. - URL("/local-user-store/api/v1/api-clients/%s", clientID). - Get(client) +// GetTrustedClient get trusted client by id. +func (c *UserStore) GetTrustedClient(clientID string) (*TrustedClient, error) { + client := &TrustedClient{} - if err != nil { - return nil, err - } + _, err := c.api. + URL("/local-user-store/api/v1/trusted-clients/%s", clientID). + Get(&client) - return client, nil + return client, err } -// DeleteAPIClient removes existing API client -func (store *UserStore) DeleteAPIClient(clientID string) error { - _, err := store.api. - URL("/local-user-store/api/v1/api-clients/%s", clientID). - Delete() +// UpdateTrustedClient update trusted client. +func (c *UserStore) UpdateTrustedClient(clientID string, client *TrustedClient) error { + _, err := c.api. + URL("/local-user-store/api/v1/trusted-clients/%s", clientID). + Put(client) return err } -// UpdateAPIClient update existing api client -func (store *UserStore) UpdateAPIClient(clientID string, client *APIClient) error { - _, err := store.api. - URL("/local-user-store/api/v1/api-clients/%s", url.PathEscape(clientID)). - Put(client) +// DeleteTrustedClient delete trusted client. +func (c *UserStore) DeleteTrustedClient(clientID string) error { + _, err := c.api. + URL("/local-user-store/api/v1/trusted-clients/%s", clientID). + Delete() return err } diff --git a/api/userstore/model.go b/api/userstore/model.go index b1960da..e370dc3 100644 --- a/api/userstore/model.go +++ b/api/userstore/model.go @@ -8,115 +8,110 @@ package userstore import "github.com/SSHcom/privx-sdk-go/api/rolestore" -// ClientType is a type of trusted clients -type ClientType string - -// ClientType supported values -const ( - ClientExtender = ClientType("EXTENDER") - ClientHostProvisioning = ClientType("HOST_PROVISIONING") -) - -// Params struct for pagination queries. -type Params struct { - Offset int `json:"offset,omitempty"` - Limit int `json:"limit,omitempty"` - Sortdir string `json:"sortdir,omitempty"` - Query string `json:"query,omitempty"` +// LocalUserParams local user query parameters definition. +type LocalUserParams struct { + UserID string `url:"id,omitempty"` + Username string `url:"username,omitempty"` } -// FilterUser struct for local users queries. -type FilterUser struct { - Params - UserID string `json:"id,omitempty"` - Username string `json:"username,omitempty"` +// TrustedClient trusted client definition. +type TrustedClient struct { + ID string `json:"id"` + Type string `json:"type"` + Secret string `json:"secret"` + Name string `json:"name"` + AccessGroupID string `json:"access_group_id"` + Created string `json:"created,omitempty"` + Updated string `json:"updated,omitempty"` + UpdatedBy string `json:"updated_by,omitempty"` + Author string `json:"author,omitempty"` + Permissions []string `json:"permissions"` + Subnets []string `json:"subnets"` + Enabled bool `json:"enabled"` + Registered bool `json:"registered"` + ExtenderAddress []string `json:"extender_address"` + OAuthClientID string `json:"oauth_client_id,omitempty"` + OAuthClientSecret string `json:"oauth_client_secret,omitempty"` + GroupID string `json:"group_id"` + WebProxyAddress string `json:"web_proxy_address,omitempty"` + WebProxyPort string `json:"web_proxy_port,omitempty"` + WebProxyExtenderRoutePatterns []string `json:"web_proxy_extender_route_patterns,omitempty"` + Data string `json:"data,omitempty"` + RoutingPrefix string `json:"routing_prefix"` } -// TrustedClient definition -type TrustedClient struct { - ID string `json:"id,omitempty"` - Secret string `json:"secret,omitempty"` - Name string `json:"name,omitempty"` - WebProxyAddress string `json:"web_proxy_address,omitempty"` - WebProxyPort string `json:"web_proxy_port,omitempty"` - Registered bool `json:"registered,omitempty"` - Enabled bool `json:"enabled,omitempty"` - Type ClientType `json:"type,omitempty"` - Permissions []string `json:"permissions,omitempty"` - WebProxyExtenderRoutePatterns []string `json:"web_proxy_extender_route_patterns,omitempty"` - ExtenderAddress []string `json:"extender_address,omitempty"` - Subnets []string `json:"subnets,omitempty"` - RoutingPrefix string `json:"routing_prefix,omitempty"` - AccessGroupId string `json:"access_group_id,omitempty"` - GroupId string `json:"group_id,omitempty"` - OAuthClientID string `json:"oauth_client_id,omitempty"` - OAuthClientSecret string `json:"oauth_client_secret,omitempty"` - Data string `json:"data,omitempty"` - Created string `json:"created,omitempty"` - Updated string `json:"updated,omitempty"` - UpdatedBy string `json:"updated_by,omitempty"` - Author string `json:"author,omitempty"` +type ExtenderClient struct { + Type string `json:"type"` + Name string `json:"name"` + RoutingPrefix string `json:"routing_prefix"` + WebProxyExtenderRoutePatterns []string `json:"web_proxy_extender_route_patterns,omitempty"` + WebProxyExtenderRoutes []string `json:"web_proxy_extender_routes,omitempty"` } -// Extender creates new trusted client -func Extender(name string) TrustedClient { - return TrustedClient{ - Type: ClientExtender, - Permissions: []string{"privx-extender"}, - Name: name, - } +// APIClient api client definition. +type APIClient struct { + ID string `json:"id"` + Secret string `json:"secret"` + Name string `json:"name"` + Created string `json:"created,omitempty"` + Updated string `json:"updated,omitempty"` + UpdatedBy string `json:"updated_by,omitempty"` + Author string `json:"author,omitempty"` + Roles []rolestore.RoleHandle `json:"roles"` + OAuthClientID string `json:"oauth_client_id,omitempty"` + OAuthClientSecret string `json:"oauth_client_secret,omitempty"` } -// HostProvisioning creates new trusted client -func HostProvisioning(name string) TrustedClient { - return TrustedClient{ - Type: ClientHostProvisioning, - Permissions: []string{"privx-host-provisioning"}, - Name: name, - } +// APIClientCreate api client create request definition. +type APIClientCreate struct { + Name string `json:"name"` + Roles []rolestore.RoleHandle `json:"roles"` } -// APIClient definition -type APIClient struct { - ID string `json:"id,omitempty"` - Name string `json:"name,omitempty"` - Secret string `json:"secret,omitempty"` - AuthClientID string `json:"oauth_client_id"` - AuthClientSecret string `json:"oauth_client_secret"` - Roles []rolestore.RoleRef `json:"roles,omitempty"` - Created string `json:"created,omitempty"` - Author string `json:"author,omitempty"` +// APIClientSearch api client search request definition. +type APIClientSearch struct { + Keywords string `json:"keywords"` + SortDir string `json:"sortdir"` + SortKey string `json:"sortkey"` + Limit *int `json:"limit"` + Offset *int `json:"offset"` } -// LocalUser definition +// LocalUser local user definition. type LocalUser struct { - ID string `json:"id,omitempty"` - Created string `json:"created,omitempty"` - Updated string `json:"updated,omitempty"` - UpdatedBy string `json:"updated_by,omitempty"` - Author string `json:"author,omitempty"` - Comment string `json:"comment,omitempty"` - Tags []string `json:"tags,omitempty"` - Username string `json:"username,omitempty"` - GivenName string `json:"given_name,omitempty"` - FullName string `json:"full_name,omitempty"` - JobTitle string `json:"job_title,omitempty"` - Company string `json:"company,omitempty"` - Department string `json:"department,omitempty"` - Email string `json:"email,omitempty"` - Telephone string `json:"telephone,omitempty"` - Locale string `json:"locale,omitempty"` - Password Password `json:"password,omitempty"` - Attributes []Attribute `json:"attributes,omitempty"` + ID string `json:"id,omitempty"` + Created string `json:"created,omitempty"` + Updated string `json:"updated,omitempty"` + UpdatedBy string `json:"updated_by,omitempty"` + Author string `json:"author,omitempty"` + Comment string `json:"comment,omitempty"` + Tags []string `json:"tags,omitempty"` + Principal string `json:"username,omitempty"` + WindowsAccount string `json:"windows_account,omitempty"` + UnixAccount string `json:"unix_account,omitempty"` + FullName string `json:"full_name,omitempty"` + DisplayName string `json:"display_name,omitempty"` + FirstName string `json:"first_name,omitempty"` + LastName string `json:"last_name,omitempty"` + JobTitle string `json:"job_title,omitempty"` + Company string `json:"company,omitempty"` + Department string `json:"department,omitempty"` + Email string `json:"email,omitempty"` + Telephone string `json:"telephone,omitempty"` + Locale string `json:"locale,omitempty"` + Password LocalUserPassword `json:"password"` + PasswordChangeRequired bool `json:"password_change_required"` + Attributes []Attributes `json:"attributes"` } -// User attribute -type Attribute struct { +// Attributes user attribute definition. +type Attributes struct { Key string `json:"key"` Value string `json:"value"` } -// Password definition -type Password struct { +// LocalUserPassword local user password definition. +type LocalUserPassword struct { Password string `json:"password,omitempty"` + Created string `json:"created,omitempty"` } diff --git a/api/vault/client.go b/api/vault/client.go new file mode 100644 index 0000000..d72e998 --- /dev/null +++ b/api/vault/client.go @@ -0,0 +1,206 @@ +// +// Copyright (c) 2020 SSH Communications Security Inc. +// +// All rights reserved. +// + +package vault + +import ( + "encoding/json" + "net/url" + + "github.com/SSHcom/privx-sdk-go/api/filters" + "github.com/SSHcom/privx-sdk-go/api/response" + "github.com/SSHcom/privx-sdk-go/restapi" +) + +// Vault is a vault client instance. +type Vault struct { + api restapi.Connector +} + +// New vault client constructor. +func New(api restapi.Connector) *Vault { + return &Vault{api: api} +} + +// MARK: Status +// Status get role store microservice status. +func (c *Vault) Status() (*response.ServiceStatus, error) { + status := &response.ServiceStatus{} + + _, err := c.api. + URL("/vault/api/v1/status"). + Get(status) + + return status, err +} + +// MARK: Metadata +// GetSecretsMetadata get secrets metadata. +func (c *Vault) GetSecretsMetadata(name string) (*Secret, error) { + metadata := &Secret{} + + _, err := c.api. + URL("/vault/api/v1/metadata/secrets/%s", name). + Get(&metadata) + + return metadata, err +} + +// GetUsersSecretsMetadata get users secrets metadata. +func (c *Vault) GetUsersSecretsMetadata(userID, name string) (*Secret, error) { + metadata := &Secret{} + + _, err := c.api. + URL("/vault/api/v1/user/%s/metadata/secrets/%s", userID, name). + Get(&metadata) + + return metadata, err +} + +// MARK: Personal Secrets +// GetUserSecrets get user secrets. +func (c *Vault) GetUserSecrets(userID string, opts ...filters.Option) (*response.ResultSet[Secret], error) { + secrets := &response.ResultSet[Secret]{} + params := url.Values{} + + for _, opt := range opts { + opt(¶ms) + } + + _, err := c.api. + URL("/vault/api/v1/user/%s/secrets", userID). + Query(params). + Get(&secrets) + + return secrets, err +} + +// CreateUserSecret create user secret. +func (c *Vault) CreateUserSecret(userID string, secret *SecretRequest) (SecretCreate, error) { + created := SecretCreate{} + + _, err := c.api. + URL("/vault/api/v1/user/%s/secrets", userID). + Post(&secret, &created) + + return created, err +} + +// UserSecret get user secret by secret name. +func (c *Vault) GetUserSecret(userID, secretName string) (*Secret, error) { + secret := &Secret{} + + _, err := c.api. + URL("/vault/api/v1/user/%s/secrets/%s", userID, secretName). + Get(&secret) + + return secret, err +} + +// UpdateUserSecret update user secret. +func (c *Vault) UpdateUserSecret(userID, secretName string, secret *SecretRequest) error { + _, err := c.api. + URL("/vault/api/v1/user/%s/secrets/%s", userID, secretName). + Put(&secret) + + return err +} + +// DeleteUserSecret delete user secret. +func (c *Vault) DeleteUserSecret(userID, secretName string) error { + _, err := c.api. + URL("/vault/api/v1/user/%s/secrets/%s", userID, secretName). + Delete() + + return err +} + +// MARK: Schemas +// GetSchemas get the defined vault schemas. +func (c *Vault) GetSchemas() (*json.RawMessage, error) { + schemas := &json.RawMessage{} + + _, err := c.api. + URL("/vault/api/v1/schemas"). + Get(&schemas) + + return schemas, err +} + +// MARK: Secrets +// GetSecrets get secrets. +func (c *Vault) GetSecrets(opts ...filters.Option) (*response.ResultSet[Secret], error) { + secrets := &response.ResultSet[Secret]{} + params := url.Values{} + + for _, opt := range opts { + opt(¶ms) + } + + _, err := c.api. + URL("/vault/api/v1/secrets"). + Query(params). + Get(&secrets) + + return secrets, err +} + +// CreateSecret create secret. +func (c *Vault) CreateSecret(secret *SecretRequest) (SecretCreate, error) { + created := SecretCreate{} + + _, err := c.api. + URL("/vault/api/v1/secrets"). + Post(&secret, &created) + + return created, err +} + +// GetSecret get secret by secret name. +func (c *Vault) GetSecret(secretName string) (*Secret, error) { + secret := &Secret{} + + _, err := c.api. + URL("/vault/api/v1/secrets/%s", secretName). + Get(&secret) + + return secret, err +} + +// UpdateSecret update secret. +func (c *Vault) UpdateSecret(secretName string, secret *SecretRequest) error { + _, err := c.api. + URL("/vault/api/v1/secrets/%s", secretName). + Put(&secret) + + return err +} + +// DeleteSecret delete secret. +func (c *Vault) DeleteSecret(secretName string) error { + _, err := c.api. + URL("/vault/api/v1/secrets/%s", secretName). + Delete() + + return err +} + +// SearchSecrets search secrets. +func (c *Vault) SearchSecrets(search SecretSearch, opts ...filters.Option) (*response.ResultSet[Secret], error) { + secrets := &response.ResultSet[Secret]{} + params := url.Values{} + + for _, opt := range opts { + opt(¶ms) + } + + _, err := c.api. + URL("/vault/api/v1/search/secrets"). + Query(params). + Post(&search, &secrets) + + return secrets, err +} diff --git a/api/vault/model.go b/api/vault/model.go index 78dd742..7be75a6 100644 --- a/api/vault/model.go +++ b/api/vault/model.go @@ -7,34 +7,42 @@ package vault import ( - "encoding/json" + "time" "github.com/SSHcom/privx-sdk-go/api/rolestore" ) -// Params struct for pagination queries. -type Params struct { - Offset int `json:"offset,omitempty"` - Limit int `json:"limit,omitempty"` - Sortkey string `json:"sortkey,omitempty"` - Sortdir string `json:"sortdir,omitempty"` +// Secret secret definition. +type Secret struct { + SecretRequest + Created time.Time `json:"created"` + Updated time.Time `json:"updated"` + UpdatedBy string `json:"updated_by"` + Author string `json:"author"` + Path string `json:"path"` } -// Secret contains PrivX metadata about secret and its vault -type Secret struct { - ID string `json:"name"` - Author string `json:"author,omitempty"` - Editor string `json:"updated_by,omitempty"` - Created string `json:"created,omitempty"` - Updated string `json:"updated,omitempty"` - AllowRead []rolestore.RoleRef `json:"read_roles,omitempty"` - AllowWrite []rolestore.RoleRef `json:"write_roles,omitempty"` - Data json.RawMessage `json:"data,omitempty"` +// SecretRequest secret request definition. +type SecretRequest struct { + Name string `json:"name"` + ReadRoles []rolestore.RoleHandle `json:"read_roles"` + WriteRoles []rolestore.RoleHandle `json:"write_roles"` + Data *map[string]interface{} `json:"data,omitempty"` + OwnerID string `json:"owner_id,omitempty"` +} + +// SecretCreate secret create create response definition. +type SecretCreate struct { + Name string `json:"name"` } -// Search criteria for secrets -type SecretSearchRequest struct { +// SecretSearch secret search request definition. +type SecretSearch struct { Keywords string `json:"keywords"` + SortDir string `json:"sortdir"` + SortKey string `json:"sortkey"` Filter string `json:"filter"` OwnerIDs []string `json:"owner_id"` + Limit int `json:"limit"` + Offset int `json:"offset"` } diff --git a/api/vault/vault.go b/api/vault/vault.go deleted file mode 100644 index 86425d3..0000000 --- a/api/vault/vault.go +++ /dev/null @@ -1,278 +0,0 @@ -// -// Copyright (c) 2020 SSH Communications Security Inc. -// -// All rights reserved. -// - -package vault - -import ( - "encoding/json" - "fmt" - "net/url" - - "github.com/SSHcom/privx-sdk-go/api/rolestore" - "github.com/SSHcom/privx-sdk-go/restapi" -) - -// Vault is client instance. -type Vault struct { - api restapi.Connector -} - -type secretResult struct { - Count int `json:"count"` - Items []Secret `json:"items"` -} - -type SecretID struct { - OwnerID string - Name string -} - -// tVaultReq t vault request definition -type tVaultReq struct { - Name string `json:"name,omitempty"` - Data interface{} `json:"data"` - AllowRead []rolestore.RoleRef `json:"read_roles,omitempty"` - AllowWrite []rolestore.RoleRef `json:"write_roles,omitempty"` - OwnerID string `json:"owner_id,omitempty"` -} - -// New creates a new Vault client instance, using the argument -// SDK API client. -func New(api restapi.Connector) *Vault { - return &Vault{api: api} -} - -// CreateSecret create new secret to PrivX Vault -func (vault *Vault) CreateSecret( - name string, - allowReadBy []string, - allowWriteBy []string, - secret interface{}, -) error { - req := vault.mkVaultReq(allowReadBy, allowWriteBy, secret) - req.Name = name - - _, err := vault.api. - URL("/vault/api/v1/secrets"). - Post(req) - - return err -} - -//CreateUserSecret creates a user secret -func (vault *Vault) CreateUserSecret( - secretID SecretID, - allowReadBy []string, - allowWriteBy []string, - secret interface{}, -) error { - req := vault.mkVaultReq(allowReadBy, allowWriteBy, secret) - req.Name = secretID.Name - req.OwnerID = url.PathEscape(secretID.OwnerID) - - _, err := vault.api. - URL("/vault/api/v1/user/%s/secrets", req.OwnerID). - Post(req) - - return err -} - -// Secrets returns secrets client has access to -func (vault *Vault) Secrets(offset, limit int) ([]Secret, error) { - result := secretResult{} - filters := Params{ - Offset: offset, - Limit: limit, - } - - _, err := vault.api. - URL("/vault/api/v1/secrets"). - Query(&filters). - Get(&result) - - return result.Items, err -} - -// UserSecrets returns user secrets client has access to -func (vault *Vault) UserSecrets(secretID SecretID, offset, limit int) ([]Secret, error) { - result := secretResult{} - filters := Params{ - Offset: offset, - Limit: limit, - } - - _, err := vault.api. - URL("/vault/api/v1/user/%s/secrets", url.PathEscape(secretID.OwnerID)). - Query(&filters). - Get(&result) - - return result.Items, err -} - -// Secret gets the content of the argument secret. -func (vault *Vault) Secret(name string) (*Secret, error) { - bag := &Secret{} - _, err := vault.api. - URL("/vault/api/v1/secrets/%s", url.PathEscape(name)). - Get(&bag) - - return bag, err -} - -// UserSecret gets the content of the argument user secret. -func (vault *Vault) UserSecret(secretID SecretID) (*Secret, error) { - bag := &Secret{} - _, err := vault.api. - URL("/vault/api/v1/user/%s/secrets/%s", url.PathEscape(secretID.OwnerID), url.PathEscape(secretID.Name)). - Get(&bag) - - return bag, err -} - -// UpdateSecret existing secret at PrivX Vault -func (vault *Vault) UpdateSecret( - name string, - allowReadTo []string, - allowWriteTo []string, - secret interface{}, -) error { - req := vault.mkVaultReq(allowReadTo, allowWriteTo, secret) - - _, err := vault.api. - URL("/vault/api/v1/secrets/%s", name). - Put(req) - - return err -} - -// UpdateUserSecret existing secret at PrivX Vault -func (vault *Vault) UpdateUserSecret( - secretID SecretID, - allowReadTo []string, - allowWriteTo []string, - secret interface{}, -) error { - req := vault.mkVaultReq(allowReadTo, allowWriteTo, secret) - req.Name = url.PathEscape(secretID.Name) - req.OwnerID = url.PathEscape(secretID.OwnerID) - _, err := vault.api. - URL("/vault/api/v1/user/%s/secrets/%s", req.OwnerID, req.Name). - Put(req) - - return err -} - -// DeleteSecret delete existing secret from PrivX vault -func (vault *Vault) DeleteSecret(name string) error { - _, err := vault.api. - URL("/vault/api/v1/secrets/%s", name). - Delete() - - return err -} - -// DeleteSecret delete existing secret from PrivX vault -func (vault *Vault) DeleteUserSecret(secretID SecretID) error { - ownerID := url.PathEscape(secretID.OwnerID) - name := url.PathEscape(secretID.Name) - - _, err := vault.api. - URL("/vault/api/v1/user/%s/secrets/%s", ownerID, name). - Delete() - - return err -} - -// SecretMetadata returns secret metadata -func (vault *Vault) SecretMetadata(name string) (*Secret, error) { - metadata := &Secret{} - - _, err := vault.api. - URL("/vault/api/v1/metadata/secrets/%s", url.PathEscape(name)). - Get(&metadata) - - return metadata, err -} - -// SecretMetadata returns secret metadata -func (vault *Vault) UserSecretMetadata(secretID SecretID) (*Secret, error) { - metadata := &Secret{} - ownerID := url.PathEscape(secretID.OwnerID) - name := url.PathEscape(secretID.Name) - - _, err := vault.api. - URL("/vault/api/v1/user/%s/metadata/secrets/%s", ownerID, name). - Get(&metadata) - - return metadata, err -} - -func validateFilter(filter string) error { - filterAllowedValues := []string{"personal", "shared", "accessible", "readable", "writable", ""} - - for _, a := range filterAllowedValues { - if a == filter { - return nil - } - } - - return fmt.Errorf("filter field must be one of these values %q", filterAllowedValues) -} - -// SearchSecrets search for existing secrets -func (vault *Vault) SearchSecrets(offset, limit int, sortkey, sortdir string, searchBody SecretSearchRequest) ([]Secret, error) { - - err := validateFilter(searchBody.Filter) - if err != nil { - return nil, err - } - result := secretResult{} - filters := Params{ - Offset: offset, - Limit: limit, - Sortkey: sortkey, - Sortdir: sortdir, - } - - _, err = vault.api. - URL("/vault/api/v1/search/secrets"). - Query(&filters). - Post(searchBody, &result) - - return result.Items, err -} - -// VaultSchemas returns the defined schemas -func (vault *Vault) VaultSchemas() (*json.RawMessage, error) { - schemas := &json.RawMessage{} - - _, err := vault.api. - URL("/vault/api/v1/schemas"). - Get(&schemas) - - return schemas, err -} - -func (vault *Vault) mkVaultReq( - allowReadBy []string, - allowWriteBy []string, - secret interface{}, -) tVaultReq { - allow := func(ids []string) []rolestore.RoleRef { - seq := []rolestore.RoleRef{} - for _, id := range ids { - seq = append(seq, rolestore.RoleRef{ID: id}) - } - return seq - } - - return tVaultReq{ - Data: secret, - AllowRead: allow(allowReadBy), - AllowWrite: allow(allowWriteBy), - OwnerID: "", - } -} From 344cc17794649292a3066bc1ad8f2100843f5830 Mon Sep 17 00:00:00 2001 From: iljaSL Date: Thu, 14 Nov 2024 11:59:28 +0200 Subject: [PATCH 5/5] fix(v2): changes func signatures,names, models --- api/connectionmanager/client.go | 12 ++++----- api/connectionmanager/model.go | 4 +-- api/hoststore/client.go | 20 +++++++++----- api/hoststore/model.go | 14 +++++----- api/rolestore/client.go | 46 ++++++++++++++++----------------- api/rolestore/model.go | 18 ++++++++++--- api/secretsmanager/client.go | 8 +++--- api/secretsmanager/model.go | 36 +++++++++++++------------- api/userstore/model.go | 4 +-- 9 files changed, 90 insertions(+), 72 deletions(-) diff --git a/api/connectionmanager/client.go b/api/connectionmanager/client.go index 2a6ec57..7369a45 100644 --- a/api/connectionmanager/client.go +++ b/api/connectionmanager/client.go @@ -270,8 +270,8 @@ func (c *ConnectionManager) CreateUebaAnomalySettings(settings UebaAnomalySettin return err } -// StartAnalyzing start analyzing connections with a saved dataset. -func (c *ConnectionManager) StartAnalyzing(datasetID string) error { +// StartUebaAnalyzing start ueba analyzing connections with a saved dataset. +func (c *ConnectionManager) StartUebaAnalyzing(datasetID string) error { _, err := c.api. URL("/connection-manager/api/v1/ueba/start-analyzing/%s", datasetID). Post(nil) @@ -279,8 +279,8 @@ func (c *ConnectionManager) StartAnalyzing(datasetID string) error { return err } -// StopAnalyzing stop analyzing connection anomalies. -func (c *ConnectionManager) StopAnalyzing() error { +// StopUebaAnalyzing stop ueba analyzing connection anomalies. +func (c *ConnectionManager) StopUebaAnalyzing() error { _, err := c.api. URL("/connection-manager/api/v1/ueba/stop-analyzing"). Post(nil) @@ -357,8 +357,8 @@ func (c *ConnectionManager) TrainUebaDataset(datasetID string, opts ...filters.O return count, err } -// GetConnectionCounts get number of connections for dataset. -func (c *ConnectionManager) GetConnectionCounts(timeRange TimeRange) (ConnectionCount, error) { +// GetUebaConnectionCounts get number of connections for dataset. +func (c *ConnectionManager) GetUebaConnectionCounts(timeRange TimeRange) (ConnectionCount, error) { count := ConnectionCount{} _, err := c.api. diff --git a/api/connectionmanager/model.go b/api/connectionmanager/model.go index 26a459a..24897d0 100644 --- a/api/connectionmanager/model.go +++ b/api/connectionmanager/model.go @@ -146,10 +146,10 @@ type UebaAnomalySettings struct { // Dataset ueba dataset definition. type Dataset struct { ID string `json:"id"` - LastTraining *time.Time `json:"last_training"` + LastTraining *time.Time `json:"last_training,omitempty"` IsActive bool `json:"is_active"` UseForInferenceOnceTrained bool `json:"use_for_inference_once_trained"` - TimeRangeSettings *TimeRange `json:"time_range_settings"` + TimeRangeSettings *TimeRange `json:"time_range_settings,omitempty"` TrainingResults []UebaTrainingResult `json:"training_results"` Created *time.Time `json:"created,omitempty"` CreatedBy string `json:"created_by,omitempty"` diff --git a/api/hoststore/client.go b/api/hoststore/client.go index 30ff17c..eff56b9 100644 --- a/api/hoststore/client.go +++ b/api/hoststore/client.go @@ -134,10 +134,14 @@ func (c *HostStore) DeployHost(host *Host) (HostResponse, error) { } // UpdateDeployStatus update host to be deployable or undeployable. -func (c *HostStore) UpdateDeployStatus(hostID string, deployable HostDeployable) error { +func (c *HostStore) UpdateDeployStatus(hostID string, deployable bool) error { + d := HostDeployable{ + Deployable: deployable, + } + _, err := c.api. URL("/host-store/api/v1/hosts/%s/deployable", hostID). - Put(&deployable) + Put(&d) return err } @@ -160,10 +164,14 @@ func (c *HostStore) GetHostTags(opts ...filters.Option) (*response.ResultSet[str } // UpdateHostStatus enable/disable host. -func (c *HostStore) UpdateHostStatus(hostID string, disabled HostDisabled) error { +func (c *HostStore) UpdateHostStatus(hostID string, disabled bool) error { + d := HostDisabled{ + Disabled: disabled, + } + _, err := c.api. URL("/host-store/api/v1/hosts/%s/disabled", hostID). - Put(disabled) + Put(&d) return err } @@ -217,8 +225,8 @@ func (c *HostStore) GetWhitelist(whitelistID string) (*Whitelist, error) { return whitelist, err } -// UpdateWhitelist update whitelist -func (c *HostStore) UpdateWhitelist(whitelist Whitelist, whitelistID string) error { +// UpdateWhitelist update whitelist. +func (c *HostStore) UpdateWhitelist(whitelistID string, whitelist Whitelist) error { _, err := c.api. URL("/host-store/api/v1/whitelists/%s", whitelistID). Put(&whitelist) diff --git a/api/hoststore/model.go b/api/hoststore/model.go index a5eafde..efbc80d 100644 --- a/api/hoststore/model.go +++ b/api/hoststore/model.go @@ -127,14 +127,14 @@ type Principal struct { // Host defines PrivX target type Host struct { ID string `json:"id"` - Deployable *bool `json:"deployable"` - Tofu *bool `json:"tofu"` + Deployable *bool `json:"deployable,omitempty"` + Tofu *bool `json:"tofu,omitempty"` StandAloneHost bool `json:"stand_alone_host"` ExternalID string `json:"external_id"` InstanceID string `json:"instance_id"` SSHHostPubKeys []HostSSHPubKeys `json:"ssh_host_public_keys"` HostCertificateRaw string `json:"host_certificate_raw"` - HostCertificate *HostCertificateInfo `json:"host_certificate"` + HostCertificate *HostCertificateInfo `json:"host_certificate,omitempty"` ContactAddress string `json:"contact_address"` PasswordRotationEnabled bool `json:"password_rotation_enabled"` Services []HostService `json:"services"` @@ -158,11 +158,11 @@ type Host struct { HostClassification string `json:"host_classification"` Comment string `json:"comment"` Addresses []string `json:"addresses"` - AuditEnabled *bool `json:"audit_enabled"` + AuditEnabled *bool `json:"audit_enabled,omitempty"` Tags []string `json:"tags"` UserMessage string `json:"user_message"` Disabled string `json:"disabled"` - SessionRecordingOptions *SessionRecordingOptions `json:"session_recording_options"` + SessionRecordingOptions *SessionRecordingOptions `json:"session_recording_options,omitempty"` Deleted bool `json:"deleted,omitempty"` } @@ -191,8 +191,8 @@ type RotationMetadata struct { type RotationStatusItem struct { Account string `json:"principal"` - LastRotated *time.Time `json:"last_rotated"` - LastError *time.Time `json:"last_error"` + LastRotated *time.Time `json:"last_rotated,omitempty"` + LastError *time.Time `json:"last_error,omitempty"` LastErrorDetails string `json:"last_error_details"` } diff --git a/api/rolestore/client.go b/api/rolestore/client.go index dcf9fd7..09a42b7 100644 --- a/api/rolestore/client.go +++ b/api/rolestore/client.go @@ -137,8 +137,8 @@ func (c *RoleStore) DeleteAWSRole(awsRoleID string) error { } // GetLinkedRoles get AWS role granting PrivX roles. -func (c *RoleStore) GetLinkedRoles(awsRoleID string) (*response.ResultSet[AWSRole], error) { - roles := &response.ResultSet[AWSRole]{} +func (c *RoleStore) GetLinkedRoles(awsRoleID string) (*response.ResultSet[LinkedPrivXRole], error) { + roles := &response.ResultSet[LinkedPrivXRole]{} _, err := c.api. URL("/role-store/api/v1/awsroles/%s/roles", awsRoleID). @@ -208,7 +208,7 @@ func (c *RoleStore) UpdateUserRoles(userID string, roles []Role) error { } // SetMFA enable, disable or reset mfa authentication. -func (c *RoleStore) SetMFA(userIDs []string, action string) error { +func (c *RoleStore) SetMFA(userIDs []string, action MFAAction) error { _, err := c.api. URL("/role-store/api/v1/users/mfa/%s", action). Post(&userIDs) @@ -216,8 +216,8 @@ func (c *RoleStore) SetMFA(userIDs []string, action string) error { return err } -// GetCurrentUserAndSettings get current user and user settings. -func (c *RoleStore) GetCurrentUserAndSettings() (*json.RawMessage, error) { +// GetCurrentUserInfo get current user and user settings. +func (c *RoleStore) GetCurrentUserInfo() (*json.RawMessage, error) { current := &json.RawMessage{} _, err := c.api. @@ -314,8 +314,8 @@ func (c *RoleStore) GetUsersAuthorizedKeys(userID string, opts ...filters.Option return keys, err } -// CreateAuthorizedKey create authorized key for user. -func (c *RoleStore) CreateAuthorizedKey(userID string, key *AuthorizedKey) (response.Identifier, error) { +// CreateUserAuthorizedKey create authorized key for user. +func (c *RoleStore) CreateUserAuthorizedKey(userID string, key *AuthorizedKey) (response.Identifier, error) { identifier := response.Identifier{} _, err := c.api. @@ -325,8 +325,8 @@ func (c *RoleStore) CreateAuthorizedKey(userID string, key *AuthorizedKey) (resp return identifier, err } -// GetUsersAuthorizedKey get users authorized key by id. -func (c *RoleStore) GetUsersAuthorizedKey(userID, keyID string) (*AuthorizedKey, error) { +// GetUserAuthorizedKey get user authorized key by id. +func (c *RoleStore) GetUserAuthorizedKey(userID, keyID string) (*AuthorizedKey, error) { key := &AuthorizedKey{} _, err := c.api. @@ -336,8 +336,8 @@ func (c *RoleStore) GetUsersAuthorizedKey(userID, keyID string) (*AuthorizedKey, return key, err } -// UpdateUsersAuthorizedKey update users authorized key. -func (c *RoleStore) UpdateUsersAuthorizedKey(userID, keyID string, key *AuthorizedKey) error { +// UpdateUserAuthorizedKey update user authorized key. +func (c *RoleStore) UpdateUserAuthorizedKey(userID, keyID string, key *AuthorizedKey) error { _, err := c.api. URL("/role-store/api/v1/users/%s/authorizedkeys/%s", userID, keyID). Put(&key) @@ -345,8 +345,8 @@ func (c *RoleStore) UpdateUsersAuthorizedKey(userID, keyID string, key *Authoriz return err } -// DeleteUsersAuthorizedKey delete a users authorized key. -func (c *RoleStore) DeleteUsersAuthorizedKey(userID, keyID string) error { +// DeleteUserAuthorizedKey delete a user authorized key. +func (c *RoleStore) DeleteUserAuthorizedKey(userID, keyID string) error { _, err := c.api. URL("/role-store/api/v1/users/%s/authorizedkeys/%s", userID, keyID). Delete() @@ -354,8 +354,8 @@ func (c *RoleStore) DeleteUsersAuthorizedKey(userID, keyID string) error { return err } -// GetCurrentUsersAuthorizedKeys get current users authorized keys. -func (c *RoleStore) GetCurrentUsersAuthorizedKeys(opts ...filters.Option) (*response.ResultSet[AuthorizedKey], error) { +// GetCurrentUserAuthorizedKeys get current user authorized keys. +func (c *RoleStore) GetCurrentUserAuthorizedKeys(opts ...filters.Option) (*response.ResultSet[AuthorizedKey], error) { keys := &response.ResultSet[AuthorizedKey]{} params := url.Values{} @@ -371,8 +371,8 @@ func (c *RoleStore) GetCurrentUsersAuthorizedKeys(opts ...filters.Option) (*resp return keys, err } -// CreateAuthorizedKeyCurrentUser create authorized key for current user. -func (c *RoleStore) CreateAuthorizedKeyCurrentUser(key *AuthorizedKey) (response.Identifier, error) { +// CreateCurrentUserAuthorizedKey create authorized key for current user. +func (c *RoleStore) CreateCurrentUserAuthorizedKey(key *AuthorizedKey) (response.Identifier, error) { identifier := response.Identifier{} _, err := c.api. @@ -382,8 +382,8 @@ func (c *RoleStore) CreateAuthorizedKeyCurrentUser(key *AuthorizedKey) (response return identifier, err } -// GetCurrentUsersAuthorizedKey get current users authorized key by id. -func (c *RoleStore) GetCurrentUsersAuthorizedKey(keyID string) (*AuthorizedKey, error) { +// GetCurrentUserAuthorizedKey get current user authorized key by id. +func (c *RoleStore) GetCurrentUserAuthorizedKey(keyID string) (*AuthorizedKey, error) { key := &AuthorizedKey{} _, err := c.api. @@ -393,8 +393,8 @@ func (c *RoleStore) GetCurrentUsersAuthorizedKey(keyID string) (*AuthorizedKey, return key, err } -// UpdateCurrentUsersAuthorizedKey update current users authorized key. -func (c *RoleStore) UpdateCurrentUsersAuthorizedKey(keyID string, key *AuthorizedKey) error { +// UpdateCurrentUserAuthorizedKey update current user authorized key. +func (c *RoleStore) UpdateCurrentUserAuthorizedKey(keyID string, key *AuthorizedKey) error { _, err := c.api. URL("/role-store/api/v1/users/current/authorizedkeys/%s", keyID). Put(&key) @@ -402,8 +402,8 @@ func (c *RoleStore) UpdateCurrentUsersAuthorizedKey(keyID string, key *Authorize return err } -// DeleteCurrentUsersAuthorizedKey delete current a users authorized key. -func (c *RoleStore) DeleteCurrentUsersAuthorizedKey(keyID string) error { +// DeleteCurrentUserAuthorizedKey delete current a user authorized key. +func (c *RoleStore) DeleteCurrentUserAuthorizedKey(keyID string) error { _, err := c.api. URL("/role-store/api/v1/users/current/authorizedkeys/%s", keyID). Delete() diff --git a/api/rolestore/model.go b/api/rolestore/model.go index 70b2ab4..69973bd 100644 --- a/api/rolestore/model.go +++ b/api/rolestore/model.go @@ -12,9 +12,19 @@ import ( "github.com/SSHcom/privx-sdk-go/api/auth" ) +const ( + // Enumerated values for MFA actions. + MFAActionEnable MFAAction = "enable" + MFAActionDisable MFAAction = "disable" + MFAActionReset MFAAction = "reset" +) + +// MFAAction definition for possible actions related to MFA. +type MFAAction string + // AWSRoleParams aws role query parameter definition. type AWSRoleParams struct { - Refresh string `url:"refresh,omitempty"` + Refresh bool `url:"refresh,omitempty"` } // AuthorizedKeyResolve authorized key resolve request definition. @@ -227,7 +237,7 @@ type User struct { Comment string `json:"comment,omitempty"` Tags []string `json:"tags,omitempty"` Roles []Role `json:"roles"` - Attributes []Attributes `json:"attributes"` + Attributes []UserAttribute `json:"attributes"` Permissions []string `json:"permissions"` FirstName string `json:"first_name,omitempty"` LastName string `json:"last_name,omitempty"` @@ -280,8 +290,8 @@ type MFASeed struct { Seed_qr_code string `json:"seed_qr_code,omitempty"` } -// Attributes user attributes definition. -type Attributes struct { +// UserAttribute user attribute definition. +type UserAttribute struct { Key string `json:"key"` Value string `json:"value"` } diff --git a/api/secretsmanager/client.go b/api/secretsmanager/client.go index 21450aa..fd142f3 100644 --- a/api/secretsmanager/client.go +++ b/api/secretsmanager/client.go @@ -157,8 +157,8 @@ func (c *SecretsManager) CompileScript(compile CompileScript) (CompileScriptResp // MARK: Manage Secrets // GetHostSecretMetadata get host secret metadata for all accounts. -func (c *SecretsManager) GetHostSecretMetadata(hostID string) (*PostHostSecret, error) { - secret := &PostHostSecret{} +func (c *SecretsManager) GetHostSecretMetadata(hostID string) (*HostSecretMetadata, error) { + secret := &HostSecretMetadata{} _, err := c.api. URL("/secrets-manager/api/v1/host-secret/%s", hostID). @@ -168,8 +168,8 @@ func (c *SecretsManager) GetHostSecretMetadata(hostID string) (*PostHostSecret, } // CreateHostSecret create host secret. -func (c *SecretsManager) CreateHostSecret(hostID string, secret *PostHostSecret) (*PostHostSecret, error) { - hostSecret := &PostHostSecret{} +func (c *SecretsManager) CreateHostSecret(hostID string, secret *HostSecretMetadata) (*HostSecretMetadata, error) { + hostSecret := &HostSecretMetadata{} _, err := c.api. URL("/secrets-manager/api/v1/host-secret/%s", hostID). diff --git a/api/secretsmanager/model.go b/api/secretsmanager/model.go index 9c28f11..ee25851 100644 --- a/api/secretsmanager/model.go +++ b/api/secretsmanager/model.go @@ -2,22 +2,22 @@ package secretsmanager import "time" -// PostHostSecret host secret metadata definition. -type PostHostSecret struct { - Metadata HostSecret `json:"metadata" validate:"required"` - Accounts []AccountSecret `json:"accounts" validate:"required"` +// HostSecretMetadata host secret metadata definition. +type HostSecretMetadata struct { + Metadata HostSecret `json:"metadata"` + Accounts []AccountSecret `json:"accounts"` } // AccountSecret account secret definition. type AccountSecret struct { Account string `json:"account"` HostID string `json:"host_id"` - RotationInitiated *time.Time `json:"rotation_initiated"` - LastRotated *time.Time `json:"last_rotated"` - LastError *time.Time `json:"last_error"` + RotationInitiated *time.Time `json:"rotation_initiate,omitempty"` + LastRotated *time.Time `json:"last_rotated,omitempty"` + LastError *time.Time `json:"last_error,omitempty"` LastErrorDetails string `json:"last_error_details"` InitialPassword string `json:"initial_password,omitempty"` - Created *time.Time `json:"created"` + Created *time.Time `json:"created,omitempty"` CreatedBy string `json:"created_by"` } @@ -35,9 +35,9 @@ type HostSecret struct { MainAccount string `json:"main_account"` PolicyID string `json:"policy_id"` ScriptTemplateID string `json:"script_template_id"` - Created *time.Time `json:"created"` + Created *time.Time `json:"created,omitempty"` CreatedBy string `json:"created_by"` - Updated *time.Time `json:"updated"` + Updated *time.Time `json:"updated,omitempty"` UpdatedBy string `json:"updated_by"` } @@ -59,9 +59,9 @@ type PasswordPolicy struct { MaxCheckoutDuration string `json:"max_checkout_duration"` RotateOnRelease bool `json:"rotate_on_release"` VerifyAfterRotation bool `json:"verify_after_rotation"` - Created *time.Time `json:"created"` + Created *time.Time `json:"created,omitempty"` CreatedBy string `json:"created_by"` - Updated *time.Time `json:"updated"` + Updated *time.Time `json:"updated,omitempty"` UpdatedBy string `json:"updated_by"` } @@ -71,9 +71,9 @@ type ScriptTemplate struct { Name string `json:"name"` OperatingSystem string `json:"operating_system"` Script string `json:"script"` - Created *time.Time `json:"created"` + Created *time.Time `json:"created,omitempty"` CreatedBy string `json:"created_by"` - Updated *time.Time `json:"updated"` + Updated *time.Time `json:"updated,omitempty"` UpdatedBy string `json:"updated_by"` } @@ -305,10 +305,10 @@ type ManagedAccountEditBatch struct { // ManagedAccountChangeSet manage account change set request definition. type ManagedAccountChangeSet struct { - Enabled *bool `json:"enabled"` - RotationEnabled *bool `json:"rotation_enabled"` - ExplicitCheckout *bool `json:"explicit_checkout"` - DisableRDPCertAuth *bool `json:"disable_rdp_cert_auth"` + Enabled *bool `json:"enabled,omitempty"` + RotationEnabled *bool `json:"rotation_enabled,omitempty"` + ExplicitCheckout *bool `json:"explicit_checkout,omitempty"` + DisableRDPCertAuth *bool `json:"disable_rdp_cert_auth,omitempty"` PasswordPolicy *PasswordPolicyHandle `json:"password_policy,omitempty"` Comment *string `json:"comment,omitempty"` } diff --git a/api/userstore/model.go b/api/userstore/model.go index e370dc3..163a342 100644 --- a/api/userstore/model.go +++ b/api/userstore/model.go @@ -73,8 +73,8 @@ type APIClientSearch struct { Keywords string `json:"keywords"` SortDir string `json:"sortdir"` SortKey string `json:"sortkey"` - Limit *int `json:"limit"` - Offset *int `json:"offset"` + Limit *int `json:"limit,omitempty"` + Offset *int `json:"offset,omitempty"` } // LocalUser local user definition.