Skip to content

Add shared GitLab user enumeration for gl users enum and gluna users enum#629

Merged
frjcomp merged 16 commits into
mainfrom
copilot/add-gitlab-users-enum-command
May 21, 2026
Merged

Add shared GitLab user enumeration for gl users enum and gluna users enum#629
frjcomp merged 16 commits into
mainfrom
copilot/add-gitlab-users-enum-command

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 13, 2026

Adds GitLab user enumeration to both authenticated and unauthenticated command trees. The new commands iterate all users exposed by the GitLab API and emit structured zerolog user entries through a shared implementation.

  • New command surface

    • Adds gl users enum
    • Adds gluna users enum
    • Wires a new users command group into both GitLab roots
  • Shared enumeration logic

    • Introduces a shared GitLab users enumerator under pkg/gitlab/users
    • Walks /api/v4/users with pagination until exhaustion
    • Supports both token-backed and anonymous access through the same code path
    • Falls back to public groups and projects when anonymous /users enumeration is unavailable
  • Logging behavior

    • Emits one structured info log line per enumerated user in normal output
    • Keeps per-discovery tracing at debug level for pagination/fallback visibility
    • Includes useful user context such as:
      • id
      • username
      • name
      • publicEmail
      • profile
      • state
      • bot
      • admin
      • external
      • privateProfile
  • Command/config handling

    • Uses the standard config binding path for --url / --token
    • Requires only the GitLab URL for enumeration
    • Keeps gluna users enum unauthenticated: it does not expose --token, and configured tokens are ignored with a warning

Example:

pipeleek gl users enum --url https://gitlab.example.com --token glpat-xxxx
pipeleek gluna users enum --url https://gitlab.example.com

Copilot AI linked an issue May 13, 2026 that may be closed by this pull request
Copilot AI changed the title [WIP] Add GitLab users enum command for gl and gluna Add shared GitLab user enumeration for gl users enum and gluna users enum May 13, 2026
Copilot AI requested a review from frjcomp May 13, 2026 09:13
@frjcomp frjcomp force-pushed the copilot/add-gitlab-users-enum-command branch from 31b6497 to 527a015 Compare May 21, 2026 11:16
@frjcomp frjcomp marked this pull request as ready for review May 21, 2026 12:13
Copilot AI review requested due to automatic review settings May 21, 2026 12:13
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a shared GitLab user enumeration capability to Pipeleek for both the authenticated (gl) and unauthenticated (gluna) command trees, implemented via a new shared package under pkg/gitlab/users and covered by unit + e2e tests.

Changes:

  • Introduces gl users enum and gluna users enum under a new users command group in both GitLab roots.
  • Adds a shared enumerator (pkg/gitlab/users) that paginates /api/v4/users and falls back to public group/project membership enumeration (incl. GraphQL fallback).
  • Adds unit tests for dedup/ID parsing and e2e tests for authenticated, unauthenticated, and fallback behaviors.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
tests/e2e/gitlab/users/enum_test.go E2E coverage for gl users enum plus unauth fallback/rejection scenarios.
tests/e2e/gitlab/unauth/users/enum_test.go Additional e2e coverage for direct unauth /users enumeration.
pkg/gitlab/users/enum.go Core shared user enumeration logic (REST + membership + GraphQL fallback) and structured logging.
pkg/gitlab/users/enum_test.go Unit tests for dedup behavior and GraphQL user ID parsing.
internal/cmd/gitlab/users/users.go Adds the users command root and wires enum.
internal/cmd/gitlab/users/enum.go CLI command implementation for users enum with config binding + optional token behavior for gluna.
internal/cmd/gitlab/users/enum_test.go Unit tests validating token header behavior and gluna token ignoring unless explicitly set.
internal/cmd/gitlab/gitlab.go Wires users into authenticated GitLab root command.
internal/cmd/gitlab/gitlab_unauth.go Wires users into unauthenticated GitLab root command.
internal/cmd/gitlab/gitlab_test.go Extends GitLab root command tests to assert users exists.
.github/copilot-instructions.md Updates documented canonical command config pattern to config.NewCommandSetup.
Comments suppressed due to low confidence (1)

pkg/gitlab/users/enum.go:309

  • collectProjectMembers receives projectPathWithNamespace but then discards it (_ = projectPathWithNamespace). This is dead code that makes the signature misleading. Either remove the parameter or use it for logging/context (especially helpful when member enumeration fails).
func collectProjectMembers(git *gitlab.Client, projectID int64, projectPathWithNamespace string, allUsers *enumeratedUsers, stats *publicEnumerationStats) error {
	_ = projectPathWithNamespace
	page := int64(1)

Comment thread pkg/gitlab/users/enum.go
Comment thread pkg/gitlab/users/enum.go Outdated
Comment on lines +559 to +561
// Use retryable HTTP client with automatic retries for 429 and 5xx errors
client := httpclient.GetPipeleekHTTPClient(apiBase, nil, nil).StandardClient()
resp, err := client.Do(req)
Comment thread pkg/gitlab/users/enum.go Outdated
Comment on lines +212 to +214
func collectGroupMembers(git *gitlab.Client, groupID int64, groupFullPath string, allUsers *enumeratedUsers, stats *publicEnumerationStats) error {
_ = groupFullPath
page := int64(1)
Comment thread internal/cmd/gitlab/users/enum.go Outdated
Comment on lines +25 to +56
if err := config.AutoBindFlags(cmd, map[string]string{
"url": "gitlab.url",
"token": "gitlab.token",
}); err != nil {
log.Fatal().Err(err).Msg("Failed to bind command flags to configuration keys")
}

if err := config.RequireConfigKeys("gitlab.url"); err != nil {
log.Fatal().Err(err).Msg("required configuration missing")
}

gitlabURL := config.GetString("gitlab.url")
gitlabAPIToken := config.GetString("gitlab.token")

// gluna commands should stay unauthenticated by default even when a token
// exists in config/env; only honor token when user explicitly sets --token.
if isSubcommandOf(cmd, "gluna") {
if flag := cmd.Flags().Lookup("token"); flag == nil || !flag.Changed {
gitlabAPIToken = ""
}
}

if err := config.ValidateURL(gitlabURL, "GitLab URL"); err != nil {
log.Fatal().Err(err).Msg("Invalid GitLab URL")
}
if gitlabAPIToken != "" {
if err := config.ValidateToken(gitlabAPIToken, "GitLab API Token"); err != nil {
log.Fatal().Err(err).Msg("Invalid GitLab API Token")
}
}

pkgusers.RunEnum(gitlabURL, gitlabAPIToken)
Comment thread internal/cmd/gitlab/users/enum.go
@frjcomp frjcomp force-pushed the copilot/add-gitlab-users-enum-command branch from c8453b2 to fde4520 Compare May 21, 2026 12:56
@frjcomp frjcomp merged commit 51edb3d into main May 21, 2026
13 checks passed
@frjcomp frjcomp deleted the copilot/add-gitlab-users-enum-command branch May 21, 2026 13:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

GitLab users enum

3 participants