From d958a55409ac8946b088e07c6d800e5589961884 Mon Sep 17 00:00:00 2001 From: Stefan Kostic Date: Thu, 9 Sep 2021 00:34:51 +0200 Subject: [PATCH 1/2] Poc for vaults paginated response --- api/client.go | 17 +++++++++++++++++ api/vault/service.go | 23 +++++++++++++++-------- common/util/vault.go | 2 +- 3 files changed, 33 insertions(+), 9 deletions(-) diff --git a/api/client.go b/api/client.go index c08e6fc..c42dfb6 100644 --- a/api/client.go +++ b/api/client.go @@ -45,6 +45,11 @@ type Client struct { Password *string } +type PaginatedResponse struct { + Results interface{} + TotalCount string +} + func requestTimeout() time.Duration { if customRequestTimeout != nil { return *customRequestTimeout @@ -273,6 +278,18 @@ func (c *Client) Get(uri string, params map[string]interface{}) (status int, res return c.parseResponse(resp) } +// Get paginated constructs and synchronously sends an API GET request +func (c *Client) GetPaginated(uri string, params map[string]interface{}) (status int, response *PaginatedResponse, err error) { + url := c.buildURL(uri) + resp, err := c.sendRequest("GET", url, defaultContentType, params) + status, results, err := c.parseResponse(resp) + paginatedResponse := &PaginatedResponse{ + Results: results, + TotalCount: resp.Header.Get("x-total-results-count"), + } + return status, paginatedResponse, err +} + // Head constructs and synchronously sends an API HEAD request; returns the headers func (c *Client) Head(uri string, params map[string]interface{}) (status int, response map[string][]string, err error) { url := c.buildURL(uri) diff --git a/api/vault/service.go b/api/vault/service.go index 2e8bd0b..5d3272f 100644 --- a/api/vault/service.go +++ b/api/vault/service.go @@ -18,6 +18,10 @@ type Service struct { api.Client } +type Response struct { + TotalCount string +} + // InitVaultService convenience method to initialize an `vault.Service` instance func InitVaultService(token *string) *Service { host := defaultVaultHost @@ -71,31 +75,34 @@ func CreateVault(token string, params map[string]interface{}) (*Vault, error) { } // ListVaults retrieves a paginated list of vaults scoped to the given API token -func ListVaults(token string, params map[string]interface{}) ([]*Vault, error) { - status, resp, err := InitVaultService(common.StringOrNil(token)).Get("vaults", params) +func ListVaults(token string, params map[string]interface{}) ([]*Vault, *Response, error) { + status, resp, err := InitVaultService(common.StringOrNil(token)).GetPaginated("vaults", params) if err != nil { - return nil, err + return nil, nil, err } if status != 200 { - return nil, fmt.Errorf("failed to fetch vaults; status: %v; %s", status, resp) + return nil, nil, fmt.Errorf("failed to fetch vaults; status: %v; %s", status, resp) } vaults := make([]*Vault, 0) - for _, item := range resp.([]interface{}) { + for _, item := range resp.Results.([]interface{}) { vlt := &Vault{} vltraw, err := json.Marshal(item) if err != nil { - return nil, fmt.Errorf("failed to fetch vaults; status: %v; %s", status, err.Error()) + return nil, nil, fmt.Errorf("failed to fetch vaults; status: %v; %s", status, err.Error()) } err = json.Unmarshal(vltraw, &vlt) if err != nil { - return nil, fmt.Errorf("failed to fetch vaults; status: %v; %s", status, err.Error()) + return nil, nil, fmt.Errorf("failed to fetch vaults; status: %v; %s", status, err.Error()) } vaults = append(vaults, vlt) } - return vaults, nil + response := &Response{ + TotalCount: resp.TotalCount, + } + return vaults, response, nil } // ListKeys retrieves a paginated list of vault keys diff --git a/common/util/vault.go b/common/util/vault.go index 8c35ecc..48de9f3 100644 --- a/common/util/vault.go +++ b/common/util/vault.go @@ -83,7 +83,7 @@ func RequireVault() { } } - vaults, err := vault.ListVaults(DefaultVaultAccessJWT, map[string]interface{}{}) + vaults, _, err := vault.ListVaults(DefaultVaultAccessJWT, map[string]interface{}{}) if err != nil { common.Log.Warningf("failed to fetch vaults for given token; %s", err.Error()) continue From 7649d760db5840b9b41638e5b82833bb6b4cae6e Mon Sep 17 00:00:00 2001 From: Stefan Kostic Date: Thu, 9 Sep 2021 19:36:23 +0200 Subject: [PATCH 2/2] Use get paginated in rest of list wrapper methods --- api/baseline/service.go | 45 ++++---- api/c2/service.go | 30 +++--- api/ident/models.go | 2 +- api/ident/service.go | 150 ++++++++++++++++----------- api/nchain/service.go | 224 +++++++++++++++++++++++++--------------- api/privacy/service.go | 15 +-- api/vault/service.go | 46 +++++---- common/globals.go | 4 + common/util/jwt.go | 2 +- 9 files changed, 314 insertions(+), 204 deletions(-) diff --git a/api/baseline/service.go b/api/baseline/service.go index 63e1188..a5f22fd 100644 --- a/api/baseline/service.go +++ b/api/baseline/service.go @@ -60,25 +60,28 @@ func ConfigureStack(token string, params map[string]interface{}) error { } // ListWorkgroups retrieves a paginated list of baseline workgroups scoped to the given API token -func ListWorkgroups(token, applicationID string, params map[string]interface{}) ([]*Workgroup, error) { - status, resp, err := InitBaselineService(token).Get("workgroups", params) +func ListWorkgroups(token, applicationID string, params map[string]interface{}) ([]*Workgroup, *common.Response, error) { + status, resp, err := InitBaselineService(token).GetPaginated("workgroups", params) if err != nil { - return nil, err + return nil, nil, err } if status != 200 { - return nil, fmt.Errorf("failed to list baseline workgroups; status: %v", status) + return nil, nil, fmt.Errorf("failed to list baseline workgroups; status: %v", status) } workgroups := make([]*Workgroup, 0) - for _, item := range resp.([]interface{}) { + for _, item := range resp.Results.([]interface{}) { workgroup := &Workgroup{} workgroupraw, _ := json.Marshal(item) json.Unmarshal(workgroupraw, &workgroup) workgroups = append(workgroups, workgroup) } - return workgroups, nil + response := &common.Response{ + TotalCount: resp.TotalCount, + } + return workgroups, response, nil } // CreateWorkgroup initializes a new or previously-joined workgroup on the local baseline stack @@ -115,25 +118,28 @@ func UpdateWorkgroup(id, token string, params map[string]interface{}) error { } // ListWorkflows retrieves a paginated list of baseline workflows scoped to the given API token -func ListWorkflows(token, applicationID string, params map[string]interface{}) ([]*Workflow, error) { - status, resp, err := InitBaselineService(token).Get("workflows", params) +func ListWorkflows(token, applicationID string, params map[string]interface{}) ([]*Workflow, *common.Response, error) { + status, resp, err := InitBaselineService(token).GetPaginated("workflows", params) if err != nil { - return nil, err + return nil, nil, err } if status != 200 { - return nil, fmt.Errorf("failed to list baseline workflows; status: %v", status) + return nil, nil, fmt.Errorf("failed to list baseline workflows; status: %v", status) } workflows := make([]*Workflow, 0) - for _, item := range resp.([]interface{}) { + for _, item := range resp.Results.([]interface{}) { workflow := &Workflow{} workflowraw, _ := json.Marshal(item) json.Unmarshal(workflowraw, &workflow) workflows = append(workflows, workflow) } - return workflows, nil + response := &common.Response{ + TotalCount: resp.TotalCount, + } + return workflows, response, nil } // CreateWorkflow initializes a new workflow on the local baseline stack @@ -155,25 +161,28 @@ func CreateWorkflow(token string, params map[string]interface{}) (*Workflow, err } // ListWorksteps retrieves a paginated list of baseline worksteps scoped to the given API token -func ListWorksteps(token, applicationID string, params map[string]interface{}) ([]*Workstep, error) { - status, resp, err := InitBaselineService(token).Get("worksteps", params) +func ListWorksteps(token, applicationID string, params map[string]interface{}) ([]*Workstep, *common.Response, error) { + status, resp, err := InitBaselineService(token).GetPaginated("worksteps", params) if err != nil { - return nil, err + return nil, nil, err } if status != 200 { - return nil, fmt.Errorf("failed to list baseline worksteps; status: %v", status) + return nil, nil, fmt.Errorf("failed to list baseline worksteps; status: %v", status) } worksteps := make([]*Workstep, 0) - for _, item := range resp.([]interface{}) { + for _, item := range resp.Results.([]interface{}) { workstep := &Workstep{} workstepraw, _ := json.Marshal(item) json.Unmarshal(workstepraw, &workstep) worksteps = append(worksteps, workstep) } - return worksteps, nil + response := &common.Response{ + TotalCount: resp.TotalCount, + } + return worksteps, response, nil } // CreateWorkstep initializes a new workstep on the local baseline stack diff --git a/api/c2/service.go b/api/c2/service.go index 7d0ee2b..a1a62a6 100644 --- a/api/c2/service.go +++ b/api/c2/service.go @@ -46,26 +46,29 @@ func InitC2Service(token string) *Service { } // ListNodes list nodes for the given authorization scope -func ListNodes(token string, params map[string]interface{}) ([]*Node, error) { +func ListNodes(token string, params map[string]interface{}) ([]*Node, *common.Response, error) { uri := fmt.Sprintf("nodes") - status, resp, err := InitC2Service(token).Get(uri, params) + status, resp, err := InitC2Service(token).GetPaginated(uri, params) if err != nil { - return nil, err + return nil, nil, err } if status != 200 { - return nil, fmt.Errorf("failed to list nodes; status: %v", status) + return nil, nil, fmt.Errorf("failed to list nodes; status: %v", status) } nodes := make([]*Node, 0) - for _, item := range resp.([]interface{}) { + for _, item := range resp.Results.([]interface{}) { node := &Node{} raw, _ := json.Marshal(item) json.Unmarshal(raw, &node) nodes = append(nodes, node) } - return nodes, nil + response := &common.Response{ + TotalCount: resp.TotalCount, + } + return nodes, response, nil } // CreateNode creates and deploys a new node for the given authorization scope @@ -183,25 +186,28 @@ func DeleteNode(token, nodeID string) (*Node, error) { } // ListLoadBalancers list load balancers for the given authorization scope -func ListLoadBalancers(token string, params map[string]interface{}) ([]*LoadBalancer, error) { - status, resp, err := InitC2Service(token).Get("load_balancers", params) +func ListLoadBalancers(token string, params map[string]interface{}) ([]*LoadBalancer, *common.Response, error) { + status, resp, err := InitC2Service(token).GetPaginated("load_balancers", params) if err != nil { - return nil, err + return nil, nil, err } if status != 200 { - return nil, fmt.Errorf("failed to list load balancers; status: %v", status) + return nil, nil, fmt.Errorf("failed to list load balancers; status: %v", status) } balancers := make([]*LoadBalancer, 0) - for _, item := range resp.([]interface{}) { + for _, item := range resp.Results.([]interface{}) { balancer := &LoadBalancer{} raw, _ := json.Marshal(item) json.Unmarshal(raw, &balancer) balancers = append(balancers, balancer) } - return balancers, nil + response := &common.Response{ + TotalCount: resp.TotalCount, + } + return balancers, response, nil } // CreateLoadBalancer creates and deploys a new load balancer for the given authorization scope diff --git a/api/ident/models.go b/api/ident/models.go index e9890a7..1a6baf5 100644 --- a/api/ident/models.go +++ b/api/ident/models.go @@ -102,7 +102,7 @@ type User struct { FirstName string `json:"first_name"` LastName string `json:"last_name"` Email string `json:"email"` - Permissions uint32 `json:"permissions,omitempty,omitempty"` + Permissions uint32 `json:"permissions,omitempty"` PrivacyPolicyAgreedAt *time.Time `json:"privacy_policy_agreed_at,omitempty"` TermsOfServiceAgreedAt *time.Time `json:"terms_of_service_agreed_at,omitempty"` Metadata map[string]interface{} `json:"metadata,omitempty"` diff --git a/api/ident/service.go b/api/ident/service.go index f7b270e..41d83fd 100644 --- a/api/ident/service.go +++ b/api/ident/service.go @@ -134,25 +134,28 @@ func DeleteApplication(token, applicationID string) error { } // ListApplications retrieves a paginated list of applications scoped to the given API token -func ListApplications(token string, params map[string]interface{}) ([]*Application, error) { - status, resp, err := InitIdentService(common.StringOrNil(token)).Get("applications", params) +func ListApplications(token string, params map[string]interface{}) ([]*Application, *common.Response, error) { + status, resp, err := InitIdentService(common.StringOrNil(token)).GetPaginated("applications", params) if err != nil { - return nil, err + return nil, nil, err } if status != 200 { - return nil, fmt.Errorf("failed to list applications; status: %v", status) + return nil, nil, fmt.Errorf("failed to list applications; status: %v", status) } apps := make([]*Application, 0) - for _, item := range resp.([]interface{}) { + for _, item := range resp.Results.([]interface{}) { app := &Application{} appraw, _ := json.Marshal(item) json.Unmarshal(appraw, &app) apps = append(apps, app) } - return apps, nil + response := &common.Response{ + TotalCount: resp.TotalCount, + } + return apps, response, nil } // GetApplicationDetails retrives application details for the given API token and application id @@ -180,72 +183,81 @@ func GetApplicationDetails(token, applicationID string, params map[string]interf } // ListApplicationTokens retrieves a paginated list of application API tokens -func ListApplicationTokens(token, applicationID string, params map[string]interface{}) ([]*Token, error) { +func ListApplicationTokens(token, applicationID string, params map[string]interface{}) ([]*Token, *common.Response, error) { uri := fmt.Sprintf("applications/%s/tokens", applicationID) - status, resp, err := InitIdentService(common.StringOrNil(token)).Get(uri, params) + status, resp, err := InitIdentService(common.StringOrNil(token)).GetPaginated(uri, params) if err != nil { - return nil, err + return nil, nil, err } if status != 200 { - return nil, fmt.Errorf("failed to list application tokens; status: %v", status) + return nil, nil, fmt.Errorf("failed to list application tokens; status: %v", status) } tkns := make([]*Token, 0) - for _, item := range resp.([]interface{}) { + for _, item := range resp.Results.([]interface{}) { tkn := &Token{} tknraw, _ := json.Marshal(item) json.Unmarshal(tknraw, &tkn) tkns = append(tkns, tkn) } - return tkns, nil + response := &common.Response{ + TotalCount: resp.TotalCount, + } + return tkns, response, nil } // ListApplicationInvitations retrieves a paginated list of invitations scoped to the given API token -func ListApplicationInvitations(token, applicationID string, params map[string]interface{}) ([]*User, error) { +func ListApplicationInvitations(token, applicationID string, params map[string]interface{}) ([]*User, *common.Response, error) { uri := fmt.Sprintf("applications/%s/invitations", applicationID) - status, resp, err := InitIdentService(common.StringOrNil(token)).Get(uri, params) + status, resp, err := InitIdentService(common.StringOrNil(token)).GetPaginated(uri, params) if err != nil { - return nil, err + return nil, nil, err } if status != 200 { - return nil, fmt.Errorf("failed to list application invitations; status: %v", status) + return nil, nil, fmt.Errorf("failed to list application invitations; status: %v", status) } users := make([]*User, 0) - for _, item := range resp.([]interface{}) { + for _, item := range resp.Results.([]interface{}) { usr := &User{} usrraw, _ := json.Marshal(item) json.Unmarshal(usrraw, &usr) users = append(users, usr) } - return users, nil + response := &common.Response{ + TotalCount: resp.TotalCount, + } + return users, response, nil } // ListApplicationOrganizations retrieves a paginated list of organizations scoped to the given API token -func ListApplicationOrganizations(token, applicationID string, params map[string]interface{}) ([]*Organization, error) { +func ListApplicationOrganizations(token, applicationID string, params map[string]interface{}) ([]*Organization, *common.Response, error) { uri := fmt.Sprintf("applications/%s/organizations", applicationID) - status, resp, err := InitIdentService(common.StringOrNil(token)).Get(uri, params) + status, resp, err := InitIdentService(common.StringOrNil(token)).GetPaginated(uri, params) if err != nil { - return nil, err + return nil, nil, err } if status != 200 { - return nil, fmt.Errorf("failed to list application organizations; status: %v", status) + return nil, nil, fmt.Errorf("failed to list application organizations; status: %v", status) } orgs := make([]*Organization, 0) - for _, item := range resp.([]interface{}) { + for _, item := range resp.Results.([]interface{}) { org := &Organization{} orgraw, _ := json.Marshal(item) json.Unmarshal(orgraw, &org) orgs = append(orgs, org) } - return orgs, nil + response := &common.Response{ + TotalCount: resp.TotalCount, + } + return orgs, response, nil } // CreateApplicationOrganization associates an organization with an application @@ -279,26 +291,29 @@ func DeleteApplicationOrganization(token, applicationID, organizationID string) } // ListApplicationUsers retrieves a paginated list of users scoped to the given API token -func ListApplicationUsers(token, applicationID string, params map[string]interface{}) ([]*User, error) { +func ListApplicationUsers(token, applicationID string, params map[string]interface{}) ([]*User, *common.Response, error) { uri := fmt.Sprintf("applications/%s/users", applicationID) - status, resp, err := InitIdentService(common.StringOrNil(token)).Get(uri, params) + status, resp, err := InitIdentService(common.StringOrNil(token)).GetPaginated(uri, params) if err != nil { - return nil, err + return nil, nil, err } if status != 200 { - return nil, fmt.Errorf("failed to list application users; status: %v", status) + return nil, nil, fmt.Errorf("failed to list application users; status: %v", status) } users := make([]*User, 0) - for _, item := range resp.([]interface{}) { + for _, item := range resp.Results.([]interface{}) { usr := &User{} usrraw, _ := json.Marshal(item) json.Unmarshal(usrraw, &usr) users = append(users, usr) } - return users, nil + response := &common.Response{ + TotalCount: resp.TotalCount, + } + return users, response, nil } // CreateApplicationUser associates a user with an application @@ -352,25 +367,28 @@ func CreateApplicationToken(token, applicationID string, params map[string]inter } // ListOrganizations retrieves a paginated list of organizations scoped to the given API token -func ListOrganizations(token string, params map[string]interface{}) ([]*Organization, error) { - status, resp, err := InitIdentService(common.StringOrNil(token)).Get("organizations", params) +func ListOrganizations(token string, params map[string]interface{}) ([]*Organization, *common.Response, error) { + status, resp, err := InitIdentService(common.StringOrNil(token)).GetPaginated("organizations", params) if err != nil { - return nil, err + return nil, nil, err } if status != 200 { - return nil, fmt.Errorf("failed to list organizations; status: %v", status) + return nil, nil, fmt.Errorf("failed to list organizations; status: %v", status) } orgs := make([]*Organization, 0) - for _, item := range resp.([]interface{}) { + for _, item := range resp.Results.([]interface{}) { org := &Organization{} orgraw, _ := json.Marshal(item) json.Unmarshal(orgraw, &org) orgs = append(orgs, org) } - return orgs, nil + response := &common.Response{ + TotalCount: resp.TotalCount, + } + return orgs, response, nil } // CreateToken creates a new API token. @@ -397,25 +415,28 @@ func CreateToken(token string, params map[string]interface{}) (*Token, error) { } // ListTokens retrieves a paginated list of API tokens scoped to the given API token -func ListTokens(token string, params map[string]interface{}) ([]*Token, error) { - status, resp, err := InitIdentService(common.StringOrNil(token)).Get("tokens", params) +func ListTokens(token string, params map[string]interface{}) ([]*Token, *common.Response, error) { + status, resp, err := InitIdentService(common.StringOrNil(token)).GetPaginated("tokens", params) if err != nil { - return nil, err + return nil, nil, err } if status != 200 { - return nil, fmt.Errorf("failed to list application tokens; status: %v", status) + return nil, nil, fmt.Errorf("failed to list application tokens; status: %v", status) } tkns := make([]*Token, 0) - for _, item := range resp.([]interface{}) { + for _, item := range resp.Results.([]interface{}) { tkn := &Token{} tknraw, _ := json.Marshal(item) json.Unmarshal(tknraw, &tkn) tkns = append(tkns, tkn) } - return tkns, nil + response := &common.Response{ + TotalCount: resp.TotalCount, + } + return tkns, response, nil } // GetTokenDetails retrieves details for the given API token id @@ -553,26 +574,29 @@ func CreateUser(token string, params map[string]interface{}) (*User, error) { } // ListOrganizationUsers retrieves a paginated list of users scoped to an organization -func ListOrganizationUsers(token, orgID string, params map[string]interface{}) ([]*User, error) { +func ListOrganizationUsers(token, orgID string, params map[string]interface{}) ([]*User, *common.Response, error) { uri := fmt.Sprintf("organizations/%s/users", orgID) - status, resp, err := InitIdentService(common.StringOrNil(token)).Get(uri, params) + status, resp, err := InitIdentService(common.StringOrNil(token)).GetPaginated(uri, params) if err != nil { - return nil, err + return nil, nil, err } if status != 200 { - return nil, fmt.Errorf("failed to list users; status: %v", status) + return nil, nil, fmt.Errorf("failed to list users; status: %v", status) } users := make([]*User, 0) - for _, item := range resp.([]interface{}) { + for _, item := range resp.Results.([]interface{}) { usr := &User{} usrraw, _ := json.Marshal(item) json.Unmarshal(usrraw, &usr) users = append(users, usr) } - return users, nil + response := &common.Response{ + TotalCount: resp.TotalCount, + } + return users, response, nil } // CreateOrganizationUser associates a user with an organization @@ -621,48 +645,54 @@ func DeleteOrganizationUser(token, orgID, userID string) error { } // ListOrganizationInvitations retrieves a paginated list of organization invitations scoped to the given API token -func ListOrganizationInvitations(token, organizationID string, params map[string]interface{}) ([]*User, error) { +func ListOrganizationInvitations(token, organizationID string, params map[string]interface{}) ([]*User, *common.Response, error) { uri := fmt.Sprintf("organizations/%s/invitations", organizationID) - status, resp, err := InitIdentService(common.StringOrNil(token)).Get(uri, params) + status, resp, err := InitIdentService(common.StringOrNil(token)).GetPaginated(uri, params) if err != nil { - return nil, err + return nil, nil, err } if status != 200 { - return nil, fmt.Errorf("failed to list organization invitations; status: %v", status) + return nil, nil, fmt.Errorf("failed to list organization invitations; status: %v", status) } users := make([]*User, 0) - for _, item := range resp.([]interface{}) { + for _, item := range resp.Results.([]interface{}) { usr := &User{} usrraw, _ := json.Marshal(item) json.Unmarshal(usrraw, &usr) users = append(users, usr) } - return users, nil + response := &common.Response{ + TotalCount: resp.TotalCount, + } + return users, response, nil } // ListUsers retrieves a paginated list of users scoped to the given API token -func ListUsers(token string, params map[string]interface{}) ([]*User, error) { - status, resp, err := InitIdentService(common.StringOrNil(token)).Get("users", params) +func ListUsers(token string, params map[string]interface{}) ([]*User, *common.Response, error) { + status, resp, err := InitIdentService(common.StringOrNil(token)).GetPaginated("users", params) if err != nil { - return nil, err + return nil, nil, err } if status != 200 { - return nil, fmt.Errorf("failed to list users; status: %v", status) + return nil, nil, fmt.Errorf("failed to list users; status: %v", status) } users := make([]*User, 0) - for _, item := range resp.([]interface{}) { + for _, item := range resp.Results.([]interface{}) { usr := &User{} usrraw, _ := json.Marshal(item) json.Unmarshal(usrraw, &usr) users = append(users, usr) } - return users, nil + response := &common.Response{ + TotalCount: resp.TotalCount, + } + return users, response, nil } // GetUserDetails retrieves details for the given user id diff --git a/api/nchain/service.go b/api/nchain/service.go index c3edaef..d115a24 100644 --- a/api/nchain/service.go +++ b/api/nchain/service.go @@ -70,24 +70,28 @@ func CreateAccount(token string, params map[string]interface{}) (*Account, error } // ListAccounts -func ListAccounts(token string, params map[string]interface{}) ([]*Account, error) { - status, resp, err := InitNChainService(token).Get("accounts", params) +func ListAccounts(token string, params map[string]interface{}) ([]*Account, *common.Response, error) { + status, resp, err := InitNChainService(token).GetPaginated("accounts", params) if err != nil { - return nil, err + return nil, nil, err } if status != 200 { - return nil, fmt.Errorf("failed to list accounts; status: %v", status) + return nil, nil, fmt.Errorf("failed to list accounts; status: %v", status) } accounts := make([]*Account, 0) - for _, item := range resp.([]interface{}) { + for _, item := range resp.Results.([]interface{}) { account := &Account{} raw, _ := json.Marshal(item) json.Unmarshal(raw, &account) accounts = append(accounts, account) } - return accounts, nil + + response := &common.Response{ + TotalCount: resp.TotalCount, + } + return accounts, response, nil } // GetAccountDetails @@ -156,24 +160,28 @@ func CreateConnector(token string, params map[string]interface{}) (*Connector, e } // ListConnectors -func ListConnectors(token string, params map[string]interface{}) ([]*Connector, error) { - status, resp, err := InitNChainService(token).Get("connectors", params) +func ListConnectors(token string, params map[string]interface{}) ([]*Connector, *common.Response, error) { + status, resp, err := InitNChainService(token).GetPaginated("connectors", params) if err != nil { - return nil, err + return nil, nil, err } if status != 200 { - return nil, fmt.Errorf("failed to list connectors; status: %v", status) + return nil, nil, fmt.Errorf("failed to list connectors; status: %v", status) } connectors := make([]*Connector, 0) - for _, item := range resp.([]interface{}) { + for _, item := range resp.Results.([]interface{}) { connector := &Connector{} raw, _ := json.Marshal(item) json.Unmarshal(raw, &connector) connectors = append(connectors, connector) } - return connectors, nil + + response := &common.Response{ + TotalCount: resp.TotalCount, + } + return connectors, response, nil } // GetConnectorDetails @@ -282,24 +290,28 @@ func ExecuteContract(token, contractID string, params map[string]interface{}) (* } // ListContracts -func ListContracts(token string, params map[string]interface{}) ([]*Contract, error) { - status, resp, err := InitNChainService(token).Get("contracts", params) +func ListContracts(token string, params map[string]interface{}) ([]*Contract, *common.Response, error) { + status, resp, err := InitNChainService(token).GetPaginated("contracts", params) if err != nil { - return nil, err + return nil, nil, err } if status != 200 { - return nil, fmt.Errorf("failed to list contracts; status: %v", status) + return nil, nil, fmt.Errorf("failed to list contracts; status: %v", status) } contracts := make([]*Contract, 0) - for _, item := range resp.([]interface{}) { + for _, item := range resp.Results.([]interface{}) { contract := &Contract{} raw, _ := json.Marshal(item) json.Unmarshal(raw, &contract) contracts = append(contracts, contract) } - return contracts, nil + + response := &common.Response{ + TotalCount: resp.TotalCount, + } + return contracts, response, nil } // GetContractDetails @@ -384,25 +396,29 @@ func UpdateNetwork(token, networkID string, params map[string]interface{}) error } // ListNetworks -func ListNetworks(token string, params map[string]interface{}) ([]*Network, error) { +func ListNetworks(token string, params map[string]interface{}) ([]*Network, *common.Response, error) { uri := "networks" - status, resp, err := InitNChainService(token).Get(uri, params) + status, resp, err := InitNChainService(token).GetPaginated(uri, params) if err != nil { - return nil, err + return nil, nil, err } if status != 200 { - return nil, fmt.Errorf("failed to list networks. status: %v", status) + return nil, nil, fmt.Errorf("failed to list networks. status: %v", status) } networks := make([]*Network, 0) - for _, item := range resp.([]interface{}) { + for _, item := range resp.Results.([]interface{}) { netwrk := &Network{} raw, _ := json.Marshal(item) json.Unmarshal(raw, &netwrk) networks = append(networks, netwrk) } - return networks, nil + + response := &common.Response{ + TotalCount: resp.TotalCount, + } + return networks, response, nil } // GetNetworkDetails returns the details for the specified network id @@ -428,25 +444,29 @@ func GetNetworkDetails(token, networkID string, params map[string]interface{}) ( } // ListNetworkAccounts -func ListNetworkAccounts(token, networkID string, params map[string]interface{}) ([]*Account, error) { +func ListNetworkAccounts(token, networkID string, params map[string]interface{}) ([]*Account, *common.Response, error) { uri := fmt.Sprintf("networks/%s/accounts", networkID) - status, resp, err := InitNChainService(token).Get(uri, params) + status, resp, err := InitNChainService(token).GetPaginated(uri, params) if err != nil { - return nil, err + return nil, nil, err } if status != 200 { - return nil, fmt.Errorf("failed to list accounts; status: %v", status) + return nil, nil, fmt.Errorf("failed to list accounts; status: %v", status) } accounts := make([]*Account, 0) - for _, item := range resp.([]interface{}) { + for _, item := range resp.Results.([]interface{}) { account := &Account{} raw, _ := json.Marshal(item) json.Unmarshal(raw, &account) accounts = append(accounts, account) } - return accounts, nil + + response := &common.Response{ + TotalCount: resp.TotalCount, + } + return accounts, response, nil } // ListNetworkBlocks @@ -484,25 +504,29 @@ func ListNetworkConnectors(token, networkID string, params map[string]interface{ } // ListNetworkContracts -func ListNetworkContracts(token, networkID string, params map[string]interface{}) ([]*Contract, error) { +func ListNetworkContracts(token, networkID string, params map[string]interface{}) ([]*Contract, *common.Response, error) { uri := fmt.Sprintf("networks/%s/contracts", networkID) - status, resp, err := InitNChainService(token).Get(uri, params) + status, resp, err := InitNChainService(token).GetPaginated(uri, params) if err != nil { - return nil, err + return nil, nil, err } if status != 200 { - return nil, fmt.Errorf("failed to list contracts; status: %v", status) + return nil, nil, fmt.Errorf("failed to list contracts; status: %v", status) } contracts := make([]*Contract, 0) - for _, item := range resp.([]interface{}) { + for _, item := range resp.Results.([]interface{}) { contract := &Contract{} raw, _ := json.Marshal(item) json.Unmarshal(raw, &contract) contracts = append(contracts, contract) } - return contracts, nil + + response := &common.Response{ + TotalCount: resp.TotalCount, + } + return contracts, response, nil } // GetNetworkContractDetails @@ -528,69 +552,81 @@ func GetNetworkContractDetails(token, networkID, contractID string, params map[s } // ListNetworkOracles -func ListNetworkOracles(token, networkID string, params map[string]interface{}) ([]*Oracle, error) { +func ListNetworkOracles(token, networkID string, params map[string]interface{}) ([]*Oracle, *common.Response, error) { uri := fmt.Sprintf("networks/%s/oracles", networkID) - status, resp, err := InitNChainService(token).Get(uri, params) + status, resp, err := InitNChainService(token).GetPaginated(uri, params) if err != nil { - return nil, err + return nil, nil, err } if status != 200 { - return nil, fmt.Errorf("failed to list oracles; status: %v", status) + return nil, nil, fmt.Errorf("failed to list oracles; status: %v", status) } oracles := make([]*Oracle, 0) - for _, item := range resp.([]interface{}) { + for _, item := range resp.Results.([]interface{}) { oracle := &Oracle{} raw, _ := json.Marshal(item) json.Unmarshal(raw, &oracle) oracles = append(oracles, oracle) } - return oracles, nil + + response := &common.Response{ + TotalCount: resp.TotalCount, + } + return oracles, response, nil } // ListNetworkTokens -func ListNetworkTokens(token, networkID string, params map[string]interface{}) ([]*Token, error) { +func ListNetworkTokens(token, networkID string, params map[string]interface{}) ([]*Token, *common.Response, error) { uri := fmt.Sprintf("networks/%s/tokens", networkID) - status, resp, err := InitNChainService(token).Get(uri, params) + status, resp, err := InitNChainService(token).GetPaginated(uri, params) if err != nil { - return nil, err + return nil, nil, err } if status != 200 { - return nil, fmt.Errorf("failed to list token contracts; status: %v", status) + return nil, nil, fmt.Errorf("failed to list token contracts; status: %v", status) } tknContracts := make([]*Token, 0) - for _, item := range resp.([]interface{}) { + for _, item := range resp.Results.([]interface{}) { tknContract := &Token{} raw, _ := json.Marshal(item) json.Unmarshal(raw, &tknContract) tknContracts = append(tknContracts, tknContract) } - return tknContracts, nil + + response := &common.Response{ + TotalCount: resp.TotalCount, + } + return tknContracts, response, nil } // ListNetworkTransactions -func ListNetworkTransactions(token, networkID string, params map[string]interface{}) ([]*Transaction, error) { +func ListNetworkTransactions(token, networkID string, params map[string]interface{}) ([]*Transaction, *common.Response, error) { uri := fmt.Sprintf("networks/%s/transactions", networkID) - status, resp, err := InitNChainService(token).Get(uri, params) + status, resp, err := InitNChainService(token).GetPaginated(uri, params) if err != nil { - return nil, err + return nil, nil, err } if status != 200 { - return nil, fmt.Errorf("failed to list transactions; status: %v", status) + return nil, nil, fmt.Errorf("failed to list transactions; status: %v", status) } txs := make([]*Transaction, 0) - for _, item := range resp.([]interface{}) { + for _, item := range resp.Results.([]interface{}) { tx := &Transaction{} raw, _ := json.Marshal(item) json.Unmarshal(raw, &tx) txs = append(txs, tx) } - return txs, nil + + response := &common.Response{ + TotalCount: resp.TotalCount, + } + return txs, response, nil } // GetNetworkTransactionDetails @@ -659,24 +695,28 @@ func CreateOracle(token string, params map[string]interface{}) (*Oracle, error) } // ListOracles -func ListOracles(token string, params map[string]interface{}) ([]*Oracle, error) { - status, resp, err := InitNChainService(token).Get("oracles", params) +func ListOracles(token string, params map[string]interface{}) ([]*Oracle, *common.Response, error) { + status, resp, err := InitNChainService(token).GetPaginated("oracles", params) if err != nil { - return nil, err + return nil, nil, err } if status != 200 { - return nil, fmt.Errorf("failed to list oracles; status: %v", status) + return nil, nil, fmt.Errorf("failed to list oracles; status: %v", status) } oracles := make([]*Oracle, 0) - for _, item := range resp.([]interface{}) { + for _, item := range resp.Results.([]interface{}) { oracle := &Oracle{} raw, _ := json.Marshal(item) json.Unmarshal(raw, &oracle) oracles = append(oracles, oracle) } - return oracles, nil + + response := &common.Response{ + TotalCount: resp.TotalCount, + } + return oracles, response, nil } // GetOracleDetails @@ -723,24 +763,28 @@ func CreateTokenContract(token string, params map[string]interface{}) (*Token, e } // ListTokenContracts -func ListTokenContracts(token string, params map[string]interface{}) ([]*Token, error) { - status, resp, err := InitNChainService(token).Get("tokens", params) +func ListTokenContracts(token string, params map[string]interface{}) ([]*Token, *common.Response, error) { + status, resp, err := InitNChainService(token).GetPaginated("tokens", params) if err != nil { - return nil, err + return nil, nil, err } if status != 200 { - return nil, fmt.Errorf("failed to list token contracts; status: %v", status) + return nil, nil, fmt.Errorf("failed to list token contracts; status: %v", status) } tknContracts := make([]*Token, 0) - for _, item := range resp.([]interface{}) { + for _, item := range resp.Results.([]interface{}) { tknContract := &Token{} raw, _ := json.Marshal(item) json.Unmarshal(raw, &tknContract) tknContracts = append(tknContracts, tknContract) } - return tknContracts, nil + + response := &common.Response{ + TotalCount: resp.TotalCount, + } + return tknContracts, response, nil } // GetTokenContractDetails @@ -787,24 +831,28 @@ func CreateTransaction(token string, params map[string]interface{}) (*Transactio } // ListTransactions -func ListTransactions(token string, params map[string]interface{}) ([]*Transaction, error) { - status, resp, err := InitNChainService(token).Get("transactions", params) +func ListTransactions(token string, params map[string]interface{}) ([]*Transaction, *common.Response, error) { + status, resp, err := InitNChainService(token).GetPaginated("transactions", params) if err != nil { - return nil, err + return nil, nil, err } if status != 200 { - return nil, fmt.Errorf("failed to list transactions; status: %v", status) + return nil, nil, fmt.Errorf("failed to list transactions; status: %v", status) } txs := make([]*Transaction, 0) - for _, item := range resp.([]interface{}) { + for _, item := range resp.Results.([]interface{}) { tx := &Transaction{} raw, _ := json.Marshal(item) json.Unmarshal(raw, &tx) txs = append(txs, tx) } - return txs, nil + + response := &common.Response{ + TotalCount: resp.TotalCount, + } + return txs, response, nil } // GetTransactionDetails @@ -851,24 +899,28 @@ func CreateWallet(token string, params map[string]interface{}) (*Wallet, error) } // ListWallets -func ListWallets(token string, params map[string]interface{}) ([]*Wallet, error) { - status, resp, err := InitNChainService(token).Get("wallets", params) +func ListWallets(token string, params map[string]interface{}) ([]*Wallet, *common.Response, error) { + status, resp, err := InitNChainService(token).GetPaginated("wallets", params) if err != nil { - return nil, err + return nil, nil, err } if status != 200 { - return nil, fmt.Errorf("failed to list wallets; status: %v", status) + return nil, nil, fmt.Errorf("failed to list wallets; status: %v", status) } wallets := make([]*Wallet, 0) - for _, item := range resp.([]interface{}) { + for _, item := range resp.Results.([]interface{}) { wallet := &Wallet{} raw, _ := json.Marshal(item) json.Unmarshal(raw, &wallet) wallets = append(wallets, wallet) } - return wallets, nil + + response := &common.Response{ + TotalCount: resp.TotalCount, + } + return wallets, response, nil } // GetWalletDetails @@ -894,23 +946,27 @@ func GetWalletDetails(token, walletID string, params map[string]interface{}) (*W } // ListWalletAccounts -func ListWalletAccounts(token, walletID string, params map[string]interface{}) ([]*Account, error) { +func ListWalletAccounts(token, walletID string, params map[string]interface{}) ([]*Account, *common.Response, error) { uri := fmt.Sprintf("wallets/%s/accounts", walletID) - status, resp, err := InitNChainService(token).Get(uri, params) + status, resp, err := InitNChainService(token).GetPaginated(uri, params) if err != nil { - return nil, err + return nil, nil, err } if status != 200 { - return nil, fmt.Errorf("failed to list accounts; status: %v", status) + return nil, nil, fmt.Errorf("failed to list accounts; status: %v", status) } accounts := make([]*Account, 0) - for _, item := range resp.([]interface{}) { + for _, item := range resp.Results.([]interface{}) { account := &Account{} raw, _ := json.Marshal(item) json.Unmarshal(raw, &account) accounts = append(accounts, account) } - return accounts, nil + + response := &common.Response{ + TotalCount: resp.TotalCount, + } + return accounts, response, nil } diff --git a/api/privacy/service.go b/api/privacy/service.go index f44c5c8..cb2837d 100644 --- a/api/privacy/service.go +++ b/api/privacy/service.go @@ -46,25 +46,28 @@ func InitPrivacyService(token string) *Service { } // ListCircuits lists the circuits in the scope of the given bearer token -func ListCircuits(token string, params map[string]interface{}) ([]*Circuit, error) { - status, resp, err := InitPrivacyService(token).Get("circuits", params) +func ListCircuits(token string, params map[string]interface{}) ([]*Circuit, *common.Response, error) { + status, resp, err := InitPrivacyService(token).GetPaginated("circuits", params) if err != nil { - return nil, err + return nil, nil, err } if status != 200 { - return nil, fmt.Errorf("failed to list circuits; status: %v", status) + return nil, nil, fmt.Errorf("failed to list circuits; status: %v", status) } circuits := make([]*Circuit, 0) - for _, item := range resp.([]interface{}) { + for _, item := range resp.Results.([]interface{}) { circuit := &Circuit{} raw, _ := json.Marshal(item) json.Unmarshal(raw, &circuit) circuits = append(circuits, circuit) } - return circuits, nil + response := &common.Response{ + TotalCount: resp.TotalCount, + } + return circuits, response, nil } // GetCircuitDetails fetches details for the given circuit diff --git a/api/vault/service.go b/api/vault/service.go index 5d3272f..05a90b5 100644 --- a/api/vault/service.go +++ b/api/vault/service.go @@ -18,10 +18,6 @@ type Service struct { api.Client } -type Response struct { - TotalCount string -} - // InitVaultService convenience method to initialize an `vault.Service` instance func InitVaultService(token *string) *Service { host := defaultVaultHost @@ -75,7 +71,7 @@ func CreateVault(token string, params map[string]interface{}) (*Vault, error) { } // ListVaults retrieves a paginated list of vaults scoped to the given API token -func ListVaults(token string, params map[string]interface{}) ([]*Vault, *Response, error) { +func ListVaults(token string, params map[string]interface{}) ([]*Vault, *common.Response, error) { status, resp, err := InitVaultService(common.StringOrNil(token)).GetPaginated("vaults", params) if err != nil { return nil, nil, err @@ -99,39 +95,42 @@ func ListVaults(token string, params map[string]interface{}) ([]*Vault, *Respons vaults = append(vaults, vlt) } - response := &Response{ + response := &common.Response{ TotalCount: resp.TotalCount, } return vaults, response, nil } // ListKeys retrieves a paginated list of vault keys -func ListKeys(token, vaultID string, params map[string]interface{}) ([]*Key, error) { +func ListKeys(token, vaultID string, params map[string]interface{}) ([]*Key, *common.Response, error) { uri := fmt.Sprintf("vaults/%s/keys", vaultID) - status, resp, err := InitVaultService(common.StringOrNil(token)).Get(uri, params) + status, resp, err := InitVaultService(common.StringOrNil(token)).GetPaginated(uri, params) if err != nil { - return nil, err + return nil, nil, err } if status != 200 { - return nil, fmt.Errorf("failed to fetch keys; status: %v; %s", status, resp) + return nil, nil, fmt.Errorf("failed to fetch keys; status: %v; %s", status, resp) } keys := make([]*Key, 0) - for _, item := range resp.([]interface{}) { + for _, item := range resp.Results.([]interface{}) { key := &Key{} keyraw, err := json.Marshal(item) if err != nil { - return nil, fmt.Errorf("failed to list vault keys; status: %v; %s", status, err.Error()) + return nil, nil, fmt.Errorf("failed to list vault keys; status: %v; %s", status, err.Error()) } err = json.Unmarshal(keyraw, &key) if err != nil { - return nil, fmt.Errorf("failed to list vault keys; status: %v; %s", status, err.Error()) + return nil, nil, fmt.Errorf("failed to list vault keys; status: %v; %s", status, err.Error()) } keys = append(keys, key) } - return keys, nil + response := &common.Response{ + TotalCount: resp.TotalCount, + } + return keys, response, nil } // CreateKey creates a new vault key @@ -285,32 +284,35 @@ func VerifySignature(token, vaultID, keyID, msg, sig string, opts map[string]int } // ListSecrets retrieves a paginated list of secrets in the vault -func ListSecrets(token, vaultID string, params map[string]interface{}) ([]*Secret, error) { +func ListSecrets(token, vaultID string, params map[string]interface{}) ([]*Secret, *common.Response, error) { uri := fmt.Sprintf("vaults/%s/secrets", vaultID) - status, resp, err := InitVaultService(common.StringOrNil(token)).Get(uri, params) + status, resp, err := InitVaultService(common.StringOrNil(token)).GetPaginated(uri, params) if err != nil { - return nil, err + return nil, nil, err } if status != 200 { - return nil, fmt.Errorf("failed to fetch secrets; status: %v; %s", status, resp) + return nil, nil, fmt.Errorf("failed to fetch secrets; status: %v; %s", status, resp) } secrets := make([]*Secret, 0) - for _, item := range resp.([]interface{}) { + for _, item := range resp.Results.([]interface{}) { secret := &Secret{} secretraw, err := json.Marshal(item) if err != nil { - return nil, fmt.Errorf("failed to fetch secrets; status: %v; %s", status, resp) + return nil, nil, fmt.Errorf("failed to fetch secrets; status: %v; %s", status, resp) } err = json.Unmarshal(secretraw, &secret) if err != nil { - return nil, fmt.Errorf("failed to fetch secrets; status: %v; %s", status, resp) + return nil, nil, fmt.Errorf("failed to fetch secrets; status: %v; %s", status, resp) } secrets = append(secrets, secret) } - return secrets, nil + response := &common.Response{ + TotalCount: resp.TotalCount, + } + return secrets, response, nil } // CreateSecret stores a new secret in the vault diff --git a/common/globals.go b/common/globals.go index edb9eec..076a2a1 100644 --- a/common/globals.go +++ b/common/globals.go @@ -21,6 +21,10 @@ var ( Log *logger.Logger ) +type Response struct { + TotalCount string +} + func init() { Log = logger.NewLogger("provide-go", getLogLevel(), getSyslogEndpoint()) } diff --git a/common/util/jwt.go b/common/util/jwt.go index 7197a43..0648767 100644 --- a/common/util/jwt.go +++ b/common/util/jwt.go @@ -537,7 +537,7 @@ func requireVaultJWTKeypairs() { select { case <-timer.C: if Vault != nil { - keys, err := vault.ListKeys(DefaultVaultAccessJWT, Vault.ID.String(), map[string]interface{}{ + keys, _, err := vault.ListKeys(DefaultVaultAccessJWT, Vault.ID.String(), map[string]interface{}{ "spec": defaultTokenSigningKeyspec, }) if err != nil {