mirror of
https://github.com/juanfont/headscale.git
synced 2026-11-04 04:34:07 +09:00
State.RenameUser went through UpdateUser and skipped the checks db.RenameUser applies, so the API could rename an OIDC user, whose name the identity provider owns, or rename any user to an invalid name. Apply both checks in the update function and map the username validation errors to 400.
67 lines
2.3 KiB
Go
67 lines
2.3 KiB
Go
package apiv1
|
|
|
|
import (
|
|
"errors"
|
|
|
|
"github.com/danielgtaylor/huma/v2"
|
|
"github.com/juanfont/headscale/hscontrol/db"
|
|
"github.com/juanfont/headscale/hscontrol/state"
|
|
"github.com/juanfont/headscale/hscontrol/types"
|
|
"github.com/juanfont/headscale/hscontrol/util"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// mapError translates a state/db-layer error into a Huma HTTP error
|
|
// (NotFound→404, invalid input→400, conflict→409, everything else→500).
|
|
// Handlers use this default mapping and may return a more specific huma.ErrorN
|
|
// directly. msg is a human context prefix, e.g. "getting node".
|
|
func mapError(msg string, err error) error {
|
|
if err == nil {
|
|
return nil
|
|
}
|
|
|
|
switch {
|
|
case errors.Is(err, types.ErrRegistrationPayloadTooLarge):
|
|
return huma.Error413RequestEntityTooLarge(msg, err)
|
|
|
|
case errors.Is(err, state.ErrAuthCacheFull),
|
|
errors.Is(err, state.ErrAuthCacheClosed):
|
|
return huma.Error503ServiceUnavailable(msg, err)
|
|
|
|
case errors.Is(err, gorm.ErrRecordNotFound),
|
|
errors.Is(err, state.ErrNodeNotFound),
|
|
errors.Is(err, state.ErrNodeNotInNodeStore),
|
|
errors.Is(err, db.ErrUserNotFound),
|
|
errors.Is(err, db.ErrNodeNotFoundRegistrationCache),
|
|
errors.Is(err, state.ErrRegistrationExpired):
|
|
return huma.Error404NotFound(msg, err)
|
|
|
|
case errors.Is(err, state.ErrGivenNameInvalid),
|
|
errors.Is(err, state.ErrGivenNameTaken),
|
|
errors.Is(err, state.ErrNodeNameNotUnique),
|
|
errors.Is(err, state.ErrNodeMarkedTaggedButHasNoTags),
|
|
errors.Is(err, state.ErrNodeHasNeitherUserNorTags),
|
|
errors.Is(err, state.ErrRequestedTagsInvalidOrNotPermitted),
|
|
errors.Is(err, types.ErrExpiryOutOfRange),
|
|
errors.Is(err, types.ErrHostinfoTooLarge),
|
|
errors.Is(err, db.ErrUserStillHasNodes),
|
|
errors.Is(err, db.ErrCannotChangeOIDCUser),
|
|
errors.Is(err, util.ErrUsernameTooShort),
|
|
errors.Is(err, util.ErrUsernameMustStartLetter),
|
|
errors.Is(err, util.ErrUsernameTooManyAt),
|
|
errors.Is(err, util.ErrUsernameInvalidChar),
|
|
errors.Is(err, db.ErrPreAuthKeyNotTaggedOrOwned),
|
|
errors.Is(err, db.ErrSingleUseAuthKeyHasBeenUsed),
|
|
errors.Is(err, state.ErrInvalidPolicy):
|
|
return huma.Error400BadRequest(msg, err)
|
|
|
|
case errors.Is(err, state.ErrNodeKeyInUse),
|
|
errors.Is(err, state.ErrAmbiguousNodeOwnership),
|
|
errors.Is(err, state.ErrAuthCacheEntryExists):
|
|
return huma.Error409Conflict(msg, err)
|
|
|
|
default:
|
|
return huma.Error500InternalServerError(msg, err)
|
|
}
|
|
}
|