refactor(server): use httperror.NewError instead of struct [EE-6189] (#10398)

pull/10444/head
Chaim Lev-Ari 2023-10-05 11:26:24 +03:00 committed by GitHub
parent da346cba60
commit 95f3cf6e5b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 39 additions and 35 deletions

View File

@ -74,7 +74,7 @@ func (handler *Handler) authenticate(rw http.ResponseWriter, r *http.Request) *h
if settings.AuthenticationMethod == portainer.AuthenticationInternal ||
settings.AuthenticationMethod == portainer.AuthenticationOAuth ||
(settings.AuthenticationMethod == portainer.AuthenticationLDAP && !settings.LDAPSettings.AutoCreateUsers) {
return &httperror.HandlerError{StatusCode: http.StatusUnprocessableEntity, Message: "Invalid credentials", Err: httperrors.ErrUnauthorized}
return httperror.NewError(http.StatusUnprocessableEntity, "Invalid credentials", httperrors.ErrUnauthorized)
}
}
@ -83,14 +83,14 @@ func (handler *Handler) authenticate(rw http.ResponseWriter, r *http.Request) *h
}
if settings.AuthenticationMethod == portainer.AuthenticationOAuth {
return &httperror.HandlerError{StatusCode: http.StatusUnprocessableEntity, Message: "Only initial admin is allowed to login without oauth", Err: httperrors.ErrUnauthorized}
return httperror.NewError(http.StatusUnprocessableEntity, "Only initial admin is allowed to login without oauth", httperrors.ErrUnauthorized)
}
if settings.AuthenticationMethod == portainer.AuthenticationLDAP {
return handler.authenticateLDAP(rw, user, payload.Username, payload.Password, &settings.LDAPSettings)
}
return &httperror.HandlerError{StatusCode: http.StatusUnprocessableEntity, Message: "Login method is not supported", Err: httperrors.ErrUnauthorized}
return httperror.NewError(http.StatusUnprocessableEntity, "Login method is not supported", httperrors.ErrUnauthorized)
}
func isUserInitialAdmin(user *portainer.User) bool {
@ -100,7 +100,7 @@ func isUserInitialAdmin(user *portainer.User) bool {
func (handler *Handler) authenticateInternal(w http.ResponseWriter, user *portainer.User, password string) *httperror.HandlerError {
err := handler.CryptoService.CompareHashAndData(user.Password, password)
if err != nil {
return &httperror.HandlerError{StatusCode: http.StatusUnprocessableEntity, Message: "Invalid credentials", Err: httperrors.ErrUnauthorized}
return httperror.NewError(http.StatusUnprocessableEntity, "Invalid credentials", httperrors.ErrUnauthorized)
}
forceChangePassword := !handler.passwordStrengthChecker.Check(password)

View File

@ -59,7 +59,7 @@ func deleteEdgeGroup(tx dataservices.DataStoreTx, ID portainer.EdgeGroupID) erro
for _, edgeStack := range edgeStacks {
for _, groupID := range edgeStack.EdgeGroups {
if groupID == ID {
return httperror.NewError(http.StatusConflict, "Edge group is used by an Edge stack", errors.New("edge group is used by an Edge stack"))
return httperror.Conflict("Edge group is used by an Edge stack", errors.New("edge group is used by an Edge stack"))
}
}
}
@ -72,7 +72,7 @@ func deleteEdgeGroup(tx dataservices.DataStoreTx, ID portainer.EdgeGroupID) erro
for _, edgeJob := range edgeJobs {
for _, groupID := range edgeJob.EdgeGroups {
if groupID == ID {
return httperror.NewError(http.StatusConflict, "Edge group is used by an Edge job", errors.New("edge group is used by an Edge job"))
return httperror.Conflict("Edge group is used by an Edge job", errors.New("edge group is used by an Edge job"))
}
}
}

View File

@ -36,7 +36,7 @@ func (handler *Handler) edgeStackCreate(w http.ResponseWriter, r *http.Request)
case httperrors.IsInvalidPayloadError(err):
return httperror.BadRequest("Invalid payload", err)
case httperrors.IsConflictError(err):
return httperror.NewError(http.StatusConflict, err.Error(), err)
return httperror.Conflict(err.Error(), err)
default:
return httperror.InternalServerError("Unable to create Edge stack", err)
}

View File

@ -216,7 +216,7 @@ func (handler *Handler) endpointCreate(w http.ResponseWriter, r *http.Request) *
}
if !isUnique {
return httperror.NewError(http.StatusConflict, "Name is not unique", nil)
return httperror.Conflict("Name is not unique", nil)
}
endpoint, endpointCreationError := handler.createEndpoint(handler.DataStore, payload)

View File

@ -100,7 +100,7 @@ func (handler *Handler) endpointUpdate(w http.ResponseWriter, r *http.Request) *
}
if !isUnique {
return httperror.NewError(http.StatusConflict, "Name is not unique", nil)
return httperror.Conflict("Name is not unique", nil)
}
endpoint.Name = name

View File

@ -69,7 +69,7 @@ func (handler *Handler) createFDOProfileFromFileContent(w http.ResponseWriter, r
}
if !isUnique {
return &httperror.HandlerError{StatusCode: http.StatusConflict, Message: fmt.Sprintf("A profile with the name '%s' already exists", payload.Name), Err: errors.New("a profile already exists with this name")}
return httperror.Conflict(fmt.Sprintf("A profile with the name '%s' already exists", payload.Name), errors.New("a profile already exists with this name"))
}
profileID := handler.DataStore.FDOProfile().GetNextIdentifier()

View File

@ -49,7 +49,7 @@ func (handler *Handler) updateProfile(w http.ResponseWriter, r *http.Request) *h
return httperror.InternalServerError(err.Error(), err)
}
if !isUnique {
return &httperror.HandlerError{StatusCode: http.StatusConflict, Message: fmt.Sprintf("A profile with the name '%s' already exists", payload.Name), Err: errors.New("a profile already exists with this name")}
return httperror.Conflict(fmt.Sprintf("A profile with the name '%s' already exists", payload.Name), errors.New("a profile already exists with this name"))
}
filePath, err := handler.FileService.StoreFDOProfileFileFromBytes(strconv.Itoa(int(profile.ID)), []byte(payload.ProfileFileContent))

View File

@ -128,10 +128,10 @@ func (handler *Handler) registryCreate(w http.ResponseWriter, r *http.Request) *
}
for _, r := range registries {
if r.Name == registry.Name {
return &httperror.HandlerError{StatusCode: http.StatusConflict, Message: "Another registry with the same name already exists", Err: errors.New("A registry is already defined with this name")}
return httperror.Conflict("Another registry with the same name already exists", errors.New("A registry is already defined with this name"))
}
if handler.registriesHaveSameURLAndCredentials(&r, registry) {
return &httperror.HandlerError{StatusCode: http.StatusConflict, Message: "Another registry with the same URL and credentials already exists", Err: errors.New("A registry is already defined for this URL and credentials")}
return httperror.Conflict("Another registry with the same URL and credentials already exists", errors.New("A registry is already defined for this URL and credentials"))
}
}

View File

@ -97,7 +97,7 @@ func (handler *Handler) registryUpdate(w http.ResponseWriter, r *http.Request) *
// see https://portainer.atlassian.net/browse/EE-2706 for more details
for _, r := range registries {
if r.ID != registry.ID && r.Name == registry.Name {
return &httperror.HandlerError{StatusCode: http.StatusConflict, Message: "Another registry with the same name already exists", Err: errors.New("A registry is already defined with this name")}
return httperror.Conflict("Another registry with the same name already exists", errors.New("A registry is already defined with this name"))
}
}
@ -148,7 +148,7 @@ func (handler *Handler) registryUpdate(w http.ResponseWriter, r *http.Request) *
for _, r := range registries {
if r.ID != registry.ID && handler.registriesHaveSameURLAndCredentials(&r, registry) {
return &httperror.HandlerError{StatusCode: http.StatusConflict, Message: "Another registry with the same URL and credentials already exists", Err: errors.New("A registry is already defined for this URL and credentials")}
return httperror.Conflict("Another registry with the same URL and credentials already exists", errors.New("A registry is already defined for this URL and credentials"))
}
}
}

View File

@ -78,7 +78,7 @@ func (handler *Handler) resourceControlCreate(w http.ResponseWriter, r *http.Req
return httperror.InternalServerError("Unable to retrieve resource controls from the database", err)
}
if rc != nil {
return &httperror.HandlerError{StatusCode: http.StatusConflict, Message: "A resource control is already associated to this resource", Err: errResourceControlAlreadyExists}
return httperror.Conflict("A resource control is already associated to this resource", errResourceControlAlreadyExists)
}
var userAccesses = make([]portainer.UserResourceAccess, 0)

View File

@ -272,7 +272,7 @@ func (handler *Handler) createComposeStackFromGitRepository(w http.ResponseWrite
return httperror.InternalServerError("Unable to check for webhook ID collision", err)
}
if !isUnique {
return &httperror.HandlerError{StatusCode: http.StatusConflict, Message: fmt.Sprintf("Webhook ID: %s already exists", payload.AutoUpdate.Webhook), Err: stackutils.ErrWebhookIDAlreadyExists}
return httperror.Conflict(fmt.Sprintf("Webhook ID: %s already exists", payload.AutoUpdate.Webhook), stackutils.ErrWebhookIDAlreadyExists)
}
}

View File

@ -166,7 +166,7 @@ func (handler *Handler) createKubernetesStackFromFileContent(w http.ResponseWrit
return httperror.InternalServerError("Unable to check for name collision", err)
}
if !isUnique {
return &httperror.HandlerError{StatusCode: http.StatusConflict, Message: fmt.Sprintf("A stack with the name '%s' already exists", payload.StackName), Err: stackutils.ErrStackAlreadyExists}
return httperror.Conflict(fmt.Sprintf("A stack with the name '%s' already exists", payload.StackName), stackutils.ErrStackAlreadyExists)
}
stackPayload := createStackPayloadFromK8sFileContentPayload(payload.StackName, payload.Namespace, payload.StackFileContent, payload.ComposeFormat, payload.FromAppTemplate)
@ -231,7 +231,7 @@ func (handler *Handler) createKubernetesStackFromGitRepository(w http.ResponseWr
return httperror.InternalServerError("Unable to check for name collision", err)
}
if !isUnique {
return &httperror.HandlerError{StatusCode: http.StatusConflict, Message: fmt.Sprintf("A stack with the name '%s' already exists", payload.StackName), Err: stackutils.ErrStackAlreadyExists}
return httperror.Conflict(fmt.Sprintf("A stack with the name '%s' already exists", payload.StackName), stackutils.ErrStackAlreadyExists)
}
//make sure the webhook ID is unique
@ -241,7 +241,7 @@ func (handler *Handler) createKubernetesStackFromGitRepository(w http.ResponseWr
return httperror.InternalServerError("Unable to check for webhook ID collision", err)
}
if !isUnique {
return &httperror.HandlerError{StatusCode: http.StatusConflict, Message: fmt.Sprintf("Webhook ID: %s already exists", payload.AutoUpdate.Webhook), Err: stackutils.ErrWebhookIDAlreadyExists}
return httperror.Conflict(fmt.Sprintf("Webhook ID: %s already exists", payload.AutoUpdate.Webhook), stackutils.ErrWebhookIDAlreadyExists)
}
}
@ -309,7 +309,7 @@ func (handler *Handler) createKubernetesStackFromManifestURL(w http.ResponseWrit
return httperror.InternalServerError("Unable to check for name collision", err)
}
if !isUnique {
return &httperror.HandlerError{StatusCode: http.StatusConflict, Message: fmt.Sprintf("A stack with the name '%s' already exists", payload.StackName), Err: stackutils.ErrStackAlreadyExists}
return httperror.Conflict(fmt.Sprintf("A stack with the name '%s' already exists", payload.StackName), stackutils.ErrStackAlreadyExists)
}
stackPayload := createStackPayloadFromK8sUrlPayload(payload.StackName,

View File

@ -214,7 +214,7 @@ func (handler *Handler) createSwarmStackFromGitRepository(w http.ResponseWriter,
return httperror.InternalServerError("Unable to check for webhook ID collision", err)
}
if !isUnique {
return &httperror.HandlerError{StatusCode: http.StatusConflict, Message: fmt.Sprintf("Webhook ID: %s already exists", payload.AutoUpdate.Webhook), Err: stackutils.ErrWebhookIDAlreadyExists}
return httperror.Conflict(fmt.Sprintf("Webhook ID: %s already exists", payload.AutoUpdate.Webhook), stackutils.ErrWebhookIDAlreadyExists)
}
}

View File

@ -46,7 +46,7 @@ type Handler struct {
func stackExistsError(name string) *httperror.HandlerError {
msg := fmt.Sprintf("A stack with the normalized name '%s' already exists", name)
err := errors.New(msg)
return &httperror.HandlerError{StatusCode: http.StatusConflict, Message: msg, Err: err}
return httperror.Conflict(msg, err)
}
// NewHandler creates a handler to manage stack operations.

View File

@ -151,7 +151,7 @@ func (handler *Handler) deleteExternalStack(r *http.Request, w http.ResponseWrit
}
if !securityContext.IsAdmin {
return &httperror.HandlerError{StatusCode: http.StatusUnauthorized, Message: "Permission denied to delete the stack", Err: httperrors.ErrUnauthorized}
return httperror.Unauthorized("Permission denied to delete the stack", httperrors.ErrUnauthorized)
}
stack, err := handler.DataStore.Stack().StackByName(stackName)

View File

@ -145,7 +145,7 @@ func (handler *Handler) stackMigrate(w http.ResponseWriter, r *http.Request) *ht
if !isUnique {
errorMessage := fmt.Sprintf("A stack with the name '%s' is already running on endpoint '%s'", stack.Name, targetEndpoint.Name)
return &httperror.HandlerError{StatusCode: http.StatusConflict, Message: errorMessage, Err: errors.New(errorMessage)}
return httperror.Conflict(errorMessage, errors.New(errorMessage))
}
migrationError := handler.migrateStack(r, stack, targetEndpoint)

View File

@ -85,7 +85,7 @@ func (handler *Handler) stackStart(w http.ResponseWriter, r *http.Request) *http
}
if !isUnique {
errorMessage := fmt.Sprintf("A stack with the name '%s' is already running", stack.Name)
return &httperror.HandlerError{StatusCode: http.StatusConflict, Message: errorMessage, Err: errors.New(errorMessage)}
return httperror.Conflict(errorMessage, errors.New(errorMessage))
}
resourceControl, err := handler.DataStore.ResourceControl().ResourceControlByResourceIDAndType(stackutils.ResourceControlID(stack.EndpointID, stack.Name), portainer.StackResourceControl)

View File

@ -35,13 +35,13 @@ func (handler *Handler) webhookInvoke(w http.ResponseWriter, r *http.Request) *h
statusCode = http.StatusNotFound
}
return &httperror.HandlerError{StatusCode: statusCode, Message: "Unable to find the stack by webhook ID", Err: err}
return httperror.NewError(statusCode, "Unable to find the stack by webhook ID", err)
}
if err = deployments.RedeployWhenChanged(stack.ID, handler.StackDeployer, handler.DataStore, handler.GitService); err != nil {
var StackAuthorMissingErr *deployments.StackAuthorMissingErr
if errors.As(err, &StackAuthorMissingErr) {
return &httperror.HandlerError{StatusCode: http.StatusConflict, Message: "Autoupdate for the stack isn't available", Err: err}
return httperror.Conflict("Autoupdate for the stack isn't available", err)
}
return httperror.InternalServerError("Failed to update the stack", err)

View File

@ -62,7 +62,7 @@ func createTag(tx dataservices.DataStoreTx, payload tagCreatePayload) (*portaine
for _, tag := range tags {
if tag.Name == payload.Name {
return nil, &httperror.HandlerError{StatusCode: http.StatusConflict, Message: "This name is already associated to a tag", Err: errors.New("a tag already exists with this name")}
return nil, httperror.Conflict("This name is already associated to a tag", errors.New("a tag already exists with this name"))
}
}

View File

@ -75,7 +75,7 @@ func (handler *Handler) teamMembershipCreate(w http.ResponseWriter, r *http.Requ
if len(memberships) > 0 {
for _, membership := range memberships {
if membership.UserID == portainer.UserID(payload.UserID) && membership.TeamID == portainer.TeamID(payload.TeamID) {
return &httperror.HandlerError{StatusCode: http.StatusConflict, Message: "Team membership already registered", Err: errors.New("Team membership already exists for this user and team")}
return httperror.Conflict("Team membership already registered", errors.New("Team membership already exists for this user and team"))
}
}
}

View File

@ -53,7 +53,7 @@ func (handler *Handler) teamCreate(w http.ResponseWriter, r *http.Request) *http
return httperror.InternalServerError("Unable to retrieve teams from the database", err)
}
if team != nil {
return &httperror.HandlerError{StatusCode: http.StatusConflict, Message: "A team with the same name already exists", Err: errors.New("Team already exists")}
return httperror.Conflict("A team with the same name already exists", errors.New("Team already exists"))
}
team = &portainer.Team{

View File

@ -55,7 +55,7 @@ func (handler *Handler) adminInit(w http.ResponseWriter, r *http.Request) *httpe
}
if len(users) != 0 {
return &httperror.HandlerError{StatusCode: http.StatusConflict, Message: "Unable to create administrator user", Err: errAdminAlreadyInitialized}
return httperror.Conflict("Unable to create administrator user", errAdminAlreadyInitialized)
}
if !handler.passwordStrengthChecker.Check(payload.Password) {

View File

@ -59,7 +59,7 @@ func (handler *Handler) userCreate(w http.ResponseWriter, r *http.Request) *http
return httperror.InternalServerError("Unable to retrieve users from the database", err)
}
if user != nil {
return &httperror.HandlerError{StatusCode: http.StatusConflict, Message: "Another user with the same username already exists", Err: errUserAlreadyExists}
return httperror.Conflict("Another user with the same username already exists", errUserAlreadyExists)
}
user = &portainer.User{

View File

@ -107,7 +107,7 @@ func (handler *Handler) userUpdate(w http.ResponseWriter, r *http.Request) *http
return httperror.InternalServerError("Unable to retrieve users from the database", err)
}
if sameNameUser != nil && sameNameUser.ID != portainer.UserID(userID) {
return &httperror.HandlerError{StatusCode: http.StatusConflict, Message: "Another user with the same username already exists", Err: errUserAlreadyExists}
return httperror.Conflict("Another user with the same username already exists", errUserAlreadyExists)
}
user.Username = payload.Username

View File

@ -61,7 +61,7 @@ func (handler *Handler) webhookCreate(w http.ResponseWriter, r *http.Request) *h
return httperror.InternalServerError("An error occurred retrieving webhooks from the database", err)
}
if webhook != nil {
return &httperror.HandlerError{StatusCode: http.StatusConflict, Message: "A webhook for this resource already exists", Err: errors.New("A webhook for this resource already exists")}
return httperror.Conflict("A webhook for this resource already exists", errors.New("A webhook for this resource already exists"))
}
endpointID := payload.EndpointID

View File

@ -40,3 +40,7 @@ func Unauthorized(message string, err error) *HandlerError {
func Forbidden(message string, err error) *HandlerError {
return NewError(http.StatusForbidden, message, err)
}
func Conflict(message string, err error) *HandlerError {
return NewError(http.StatusConflict, message, err)
}