Skip to content

Commit 6f1e918

Browse files
authored
Postman workspace enumeration (#3925)
* Updated Postman source logging * Added logging for enumeration * Got workspace enumeration to go with the additional step of making a request to every workspace listed * Edited logging levels * Updated context parameter and logging snake case * When errors occur, return explicit null values instead of zero variable * Updated returned error message
1 parent faa67f4 commit 6f1e918

File tree

2 files changed

+30
-14
lines changed

2 files changed

+30
-14
lines changed

pkg/sources/postman/postman.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -180,11 +180,12 @@ func (s *Source) Chunks(ctx context.Context, chunksChan chan *sources.Chunk, _ .
180180

181181
// Scan workspaces
182182
for _, workspaceID := range s.conn.Workspaces {
183-
w, err := s.client.GetWorkspace(workspaceID)
183+
w, err := s.client.GetWorkspace(ctx, workspaceID)
184184
if err != nil {
185185
return fmt.Errorf("error getting workspace %s: %w", workspaceID, err)
186186
}
187187
s.SetProgressOngoing(fmt.Sprintf("Scanning workspace %s", workspaceID), "")
188+
ctx.Logger().V(2).Info("scanning workspace from workspaces given", "workspace", workspaceID)
188189
if err = s.scanWorkspace(ctx, chunksChan, w); err != nil {
189190
return fmt.Errorf("error scanning workspace %s: %w", workspaceID, err)
190191
}
@@ -206,10 +207,11 @@ func (s *Source) Chunks(ctx context.Context, chunksChan chan *sources.Chunk, _ .
206207

207208
// Scan personal workspaces (from API token)
208209
if s.conn.Workspaces == nil && s.conn.Collections == nil && s.conn.Environments == nil && s.conn.GetToken() != "" {
209-
workspaces, err := s.client.EnumerateWorkspaces()
210+
workspaces, err := s.client.EnumerateWorkspaces(ctx)
210211
if err != nil {
211212
return fmt.Errorf("error enumerating postman workspaces: %w", err)
212213
}
214+
ctx.Logger().V(2).Info("enumerated workspaces", "workspaces", workspaces)
213215
for _, workspace := range workspaces {
214216
s.SetProgressOngoing(fmt.Sprintf("Scanning workspace %s", workspace.ID), "")
215217
if err = s.scanWorkspace(ctx, chunksChan, workspace); err != nil {
@@ -307,7 +309,7 @@ func (s *Source) scanWorkspace(ctx context.Context, chunksChan chan *sources.Chu
307309
// scanCollection scans a collection and all its items, folders, and requests.
308310
// locally scoped Metadata is updated as we drill down into the collection.
309311
func (s *Source) scanCollection(ctx context.Context, chunksChan chan *sources.Chunk, metadata Metadata, collection Collection) {
310-
ctx.Logger().V(2).Info("starting scanning collection", collection.Info.Name, "uuid", collection.Info.UID)
312+
ctx.Logger().V(2).Info("starting to scan collection", "collection_name", collection.Info.Name, "collection_uuid", collection.Info.UID)
311313
metadata.CollectionInfo = collection.Info
312314
metadata.Type = COLLECTION_TYPE
313315
s.attemptToAddKeyword(collection.Info.Name)
@@ -637,7 +639,7 @@ func (s *Source) scanHTTPResponse(ctx context.Context, chunksChan chan *sources.
637639

638640
func (s *Source) scanVariableData(ctx context.Context, chunksChan chan *sources.Chunk, m Metadata, variableData VariableData) {
639641
if len(variableData.KeyValues) == 0 {
640-
ctx.Logger().V(2).Info("no variables to scan", "type", m.Type, "uuid", m.FullID)
642+
ctx.Logger().V(2).Info("no variables to scan", "type", m.Type, "item_uuid", m.FullID)
641643
return
642644
}
643645

@@ -673,12 +675,14 @@ func (s *Source) scanVariableData(ctx context.Context, chunksChan chan *sources.
673675

674676
func (s *Source) scanData(ctx context.Context, chunksChan chan *sources.Chunk, data string, metadata Metadata) {
675677
if data == "" {
678+
ctx.Logger().V(3).Info("Data string is empty", "workspace_id", metadata.WorkspaceUUID)
676679
return
677680
}
678681
if metadata.FieldType == "" {
679682
metadata.FieldType = metadata.Type
680683
}
681684

685+
ctx.Logger().V(3).Info("Generating chunk and passing it to the channel", "link", metadata.Link)
682686
chunksChan <- &sources.Chunk{
683687
SourceType: s.Type(),
684688
SourceName: s.name,

pkg/sources/postman/postman_client.go

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import (
77
"net/http"
88
"time"
99

10+
"github.com/trufflesecurity/trufflehog/v3/pkg/context"
11+
1012
"github.com/trufflesecurity/trufflehog/v3/pkg/pb/source_metadatapb"
1113
)
1214

@@ -249,36 +251,46 @@ func (c *Client) getPostmanReq(url string, headers map[string]string) (*http.Res
249251

250252
// EnumerateWorkspaces returns the workspaces for a given user (both private, public, team and personal).
251253
// Consider adding additional flags to support filtering.
252-
func (c *Client) EnumerateWorkspaces() ([]Workspace, error) {
253-
var workspaces []Workspace
254+
func (c *Client) EnumerateWorkspaces(ctx context.Context) ([]Workspace, error) {
255+
ctx.Logger().V(2).Info("enumerating workspaces")
254256
workspacesObj := struct {
255257
Workspaces []Workspace `json:"workspaces"`
256258
}{}
257259

258260
r, err := c.getPostmanReq("https://api.getpostman.com/workspaces", nil)
259261
if err != nil {
260262
err = fmt.Errorf("could not get workspaces")
261-
return workspaces, err
263+
return nil, err
262264
}
263265

264266
body, err := io.ReadAll(r.Body)
265267
if err != nil {
266268
err = fmt.Errorf("could not read response body for workspaces")
267-
return workspaces, err
269+
return nil, err
268270
}
269271
r.Body.Close()
270272

271273
if err := json.Unmarshal([]byte(body), &workspacesObj); err != nil {
272274
err = fmt.Errorf("could not unmarshal workspaces JSON")
273-
return workspaces, err
275+
return nil, err
276+
}
277+
278+
for i, workspace := range workspacesObj.Workspaces {
279+
tempWorkspace, err := c.GetWorkspace(ctx, workspace.ID)
280+
if err != nil {
281+
return nil, fmt.Errorf("could not get workspace %q (%s) during enumeration: %w", workspace.Name, workspace.ID, err)
282+
}
283+
workspacesObj.Workspaces[i] = tempWorkspace
284+
285+
ctx.Logger().V(3).Info("individual workspace getting added to the slice", "workspace", workspacesObj.Workspaces[i])
274286
}
275287

276288
return workspacesObj.Workspaces, nil
277289
}
278290

279291
// GetWorkspace returns the workspace for a given workspace
280-
func (c *Client) GetWorkspace(workspaceUUID string) (Workspace, error) {
281-
var workspace Workspace
292+
func (c *Client) GetWorkspace(ctx context.Context, workspaceUUID string) (Workspace, error) {
293+
ctx.Logger().V(2).Info("getting workspace", "workspace", workspaceUUID)
282294
obj := struct {
283295
Workspace Workspace `json:"workspace"`
284296
}{}
@@ -287,19 +299,19 @@ func (c *Client) GetWorkspace(workspaceUUID string) (Workspace, error) {
287299
r, err := c.getPostmanReq(url, nil)
288300
if err != nil {
289301
err = fmt.Errorf("could not get workspace: %s", workspaceUUID)
290-
return workspace, err
302+
return Workspace{}, err
291303
}
292304

293305
body, err := io.ReadAll(r.Body)
294306
if err != nil {
295307
err = fmt.Errorf("could not read response body for workspace: %s", workspaceUUID)
296-
return workspace, err
308+
return Workspace{}, err
297309
}
298310
r.Body.Close()
299311

300312
if err := json.Unmarshal([]byte(body), &obj); err != nil {
301313
err = fmt.Errorf("could not unmarshal workspace JSON for workspace: %s", workspaceUUID)
302-
return workspace, err
314+
return Workspace{}, err
303315
}
304316

305317
return obj.Workspace, nil

0 commit comments

Comments
 (0)