[management] Enable PAT creation during setup (#6003)

* enable pat creation on setup

* remove logic from handler towards setup service

* fix lint issue

* fix rollback on account id returning empty

* fix coderabbit comments

* fix setup PAT rollback behavior
This commit is contained in:
Nicolas Frati
2026-04-30 17:21:35 +02:00
committed by GitHub
parent f29f5a0978
commit dcd1db42ef
11 changed files with 997 additions and 19 deletions
@@ -7,6 +7,7 @@ import (
"github.com/gorilla/mux"
log "github.com/sirupsen/logrus"
"github.com/netbirdio/netbird/management/server/account"
nbinstance "github.com/netbirdio/netbird/management/server/instance"
"github.com/netbirdio/netbird/shared/management/http/api"
"github.com/netbirdio/netbird/shared/management/http/util"
@@ -15,13 +16,15 @@ import (
// handler handles the instance setup HTTP endpoints
type handler struct {
instanceManager nbinstance.Manager
setupManager *nbinstance.SetupService
}
// AddEndpoints registers the instance setup endpoints.
// These endpoints bypass authentication for initial setup.
func AddEndpoints(instanceManager nbinstance.Manager, router *mux.Router) {
func AddEndpoints(instanceManager nbinstance.Manager, accountManager account.Manager, router *mux.Router) {
h := &handler{
instanceManager: instanceManager,
setupManager: nbinstance.NewSetupService(instanceManager, accountManager),
}
router.HandleFunc("/instance", h.getInstanceStatus).Methods("GET", "OPTIONS")
@@ -55,24 +58,36 @@ func (h *handler) getInstanceStatus(w http.ResponseWriter, r *http.Request) {
// setup creates the initial admin user for the instance.
// This endpoint is unauthenticated but only works when setup is required.
func (h *handler) setup(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
var req api.SetupRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
util.WriteErrorResponse("invalid request body", http.StatusBadRequest, w)
return
}
userData, err := h.instanceManager.CreateOwnerUser(r.Context(), req.Email, req.Password, req.Name)
result, err := h.setupManager.SetupOwner(ctx, req.Email, req.Password, req.Name, nbinstance.SetupOptions{
CreatePAT: req.CreatePat != nil && *req.CreatePat,
PATExpireInDays: req.PatExpireIn,
})
if err != nil {
util.WriteError(r.Context(), err, w)
util.WriteError(ctx, err, w)
return
}
log.WithContext(r.Context()).Infof("instance setup completed: created user %s", req.Email)
log.WithContext(ctx).Infof("instance setup completed: created user %s", req.Email)
util.WriteJSONObject(r.Context(), w, api.SetupResponse{
UserId: userData.ID,
Email: userData.Email,
})
resp := api.SetupResponse{
UserId: result.User.ID,
Email: result.User.Email,
}
if result.PATPlainToken != "" {
resp.PersonalAccessToken = &result.PATPlainToken
}
w.Header().Set("Cache-Control", "no-store")
util.WriteJSONObject(ctx, w, resp)
}
// getVersionInfo returns version information for NetBird components.