users

package
v0.0.0-...-310f30e Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 15, 2026 License: AGPL-3.0 Imports: 21 Imported by: 0

Documentation

Overview

Package users hosts the `olares-cli settings users ...` subtree.

common.go centralizes the per-area Doer / output plumbing in the same shape as cli/cmd/ctl/settings/me/common.go. We deliberately don't share the helpers across packages because the per-area transports may need per-area types in later phases (e.g. settings/apps will need ListResult awareness, settings/backup will need a different base path), and a duplicated 100-line common.go per package is a much smaller cost than teasing the shared abstraction out before we know what stays common.

All `users` reads we ship here are gated server-side: app-service's /app-service/v1/users handler runs as the cluster controller and lists every user; user-service's /api/users/v2 wrapper applies a role-based filter so non-privileged callers only see themselves. We standardize on v2 for `users list` so the CLI degrades gracefully — a normal user gets a 1-row table instead of a 403, which matches the SPA's UX.

Package users implements the `olares-cli settings users` subtree.

Backed by user-service's bfl/users.controller.ts which itself proxies BFL's /api/users surface; see plan.md's section "1. Users" for the authoritative API map. Each settings area lives in its own Go package (rather than one flat `settings` package) so per-area types, parsers, and printers don't collide across the 13 sub-trees.

The umbrella exposes a `me` alias that delegates to the shared whoami helper in cmd/ctl/profile, matching plan.md's "two entry points, same implementation" rule.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NewCreateCommand

func NewCreateCommand(f *cmdutil.Factory) *cobra.Command

NewCreateCommand implements `settings users create`.

func NewDeleteCommand

func NewDeleteCommand(f *cmdutil.Factory) *cobra.Command

NewDeleteCommand implements `settings users delete`.

func NewGetCommand

func NewGetCommand(f *cmdutil.Factory) *cobra.Command

`olares-cli settings users get <username>`

Wraps user-service's GET /api/users/:username. user-service's bfl/users.controller.ts:95 explicitly returns `data.data` from the upstream axios response — the upstream is app-service /app-service/v1/users/<name>, which writes a single UserInfo struct directly to the response body (see framework/app-service/.../ handler_user.go:422 handleUser).

Depending on whether NestJS' global response interceptor is active, the wire body shows up either as the raw UserInfo object or wrapped in an envelope `{code:200, data:{...}}`. decodeObjectResult (cli/cmd/ctl/settings/users/common.go) probes for a top-level `code` field and unwraps `data` accordingly, falling back to raw-body decode when no envelope is present, so we stay forward-compatible with whichever shape user-service settles on.

Role: admin floor. app-service does not gate handleUser server-side (any authenticated user gets a successful response for any username), but the SPA's "Users" page is admin-only — non-admin users have no UI entry into per-user inspection. We mirror that here so the CLI surface matches the SPA. A 404 still wins when the username doesn't exist on the server.

func NewListCommand

func NewListCommand(f *cmdutil.Factory) *cobra.Command

`olares-cli settings users list`

Wraps user-service's GET /api/users/v2 — chosen over /api/users so non-privileged callers see themselves rather than a 403. Server flow (users.controller.ts:71-93):

  1. proxy app-service /app-service/v1/users (ListResult with all users)
  2. resolve currentUser by olaresId.split('@')[0]
  3. if currentUser is owner/admin → return as-is else → return only currentUser

Wire shape (after step 3, what NestJS sends back):

{ code: 200, data: [UserInfo, ...], totals: N }

We unwrap manually here because the BFL envelope helper in settings/me/common.go expects code=0 with a message field. App-service uses code=200 and no message.

Role: admin floor. The SPA only surfaces "Users" in the Settings menu for admin/owner (apps/.../stores/settings/admin.ts:menus); we mirror that here so a non-admin caller gets a refresh-and-retry hint up front rather than a single self-only row that quietly hides the rest of the instance. The server-side v2 endpoint still gracefully degrades, so passing the gate (or running with an empty role cache) yields the same shape the SPA would.

func NewMeCommand

func NewMeCommand(f *cmdutil.Factory) *cobra.Command

NewMeCommand: `olares-cli settings users me [--refresh] [-o table|json]`

Canonical "Settings -> Users -> me" entry point — a verb under the users area rather than a sibling of users / appearance / apps. Same behavior as `olares-cli profile whoami` and `olares-cli settings me whoami`: both are aliases that flow through pkg/whoami.Run, so they share output shape, cache write semantics, and the --refresh flag.

We deliberately ship all three at once (rather than picking a winner) because each entry point matches a different mental model:

  • profile whoami → "where am I logged in / which profile is active" — same family as profile list, profile use.
  • settings users me → docs.olares.com/manual/olares/settings/ UI mapping; you found Users in the SPA menu, the SPA shows you at the top.
  • settings me whoami → tucked under the Person dropdown in the SPA; CLI-friendly self-service tree.

All three call the same code; the help text disambiguates which is which.

func NewUsersCommand

func NewUsersCommand(f *cmdutil.Factory) *cobra.Command

NewUsersCommand returns the `settings users` parent: list and inspect Olares users, create/delete (HTTP-backed, same routes as Termipass), plus the `me` whoami shortcut. set-password / set-limits remain out of scope until wired here.

Types

type Doer

type Doer interface {
	DoJSON(ctx context.Context, method, path string, body, out interface{}) error
}

Doer is the smallest contract the verbs need from the underlying HTTP client; *whoami.HTTPClient satisfies it (and has the desktop-ingress 401/403 reformatting we want), tests can supply a fake.

type Format

type Format string

Format selects how a `users` read verb renders its result.

const (
	FormatTable Format = "table"
	FormatJSON  Format = "json"
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL