mirror of
https://github.com/empayre/fleet.git
synced 2024-11-06 17:05:18 +00:00
5eb926c891
* add a js validator that makes smtp server port required * specifying that the InputField should be a number. this doesn't work, but i think that it should. * casting the port as an int as a stop-gap fix * email doesn't already have to be enabled to be enabled * don't return the smtp password from the API * show a fake placeholder password if the username is also set * error type for @groob
163 lines
3.5 KiB
Go
163 lines
3.5 KiB
Go
package service
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
|
|
kithttp "github.com/go-kit/kit/transport/http"
|
|
"golang.org/x/net/context"
|
|
)
|
|
|
|
// erroer interface is implemented by response structs to encode business logic errors
|
|
type errorer interface {
|
|
error() error
|
|
}
|
|
|
|
type jsonError struct {
|
|
Message string `json:"message"`
|
|
Errors []map[string]string `json:"errors,omitempty"`
|
|
}
|
|
|
|
// use baseError to encode an jsonError.Errors field with an error that has
|
|
// a generic "name" field. The frontend client always expects errors in a
|
|
// []map[string]string format.
|
|
func baseError(err string) []map[string]string {
|
|
return []map[string]string{map[string]string{
|
|
"name": "base",
|
|
"reason": err},
|
|
}
|
|
}
|
|
|
|
// encode error and status header to the client
|
|
func encodeError(ctx context.Context, err error, w http.ResponseWriter) {
|
|
// Unwrap Go-Kit Error
|
|
domain := "service"
|
|
if e, ok := err.(kithttp.Error); ok {
|
|
err = e.Err
|
|
domain = e.Domain
|
|
}
|
|
|
|
enc := json.NewEncoder(w)
|
|
enc.SetIndent("", " ")
|
|
|
|
type validationError interface {
|
|
error
|
|
Invalid() []map[string]string
|
|
}
|
|
if e, ok := err.(validationError); ok {
|
|
ve := jsonError{
|
|
Message: "Validation Failed",
|
|
Errors: e.Invalid(),
|
|
}
|
|
w.WriteHeader(http.StatusUnprocessableEntity)
|
|
enc.Encode(ve)
|
|
return
|
|
}
|
|
|
|
type authenticationError interface {
|
|
error
|
|
AuthError() string
|
|
}
|
|
if e, ok := err.(authenticationError); ok {
|
|
ae := jsonError{
|
|
Message: "Authentication Failed",
|
|
Errors: baseError(e.AuthError()),
|
|
}
|
|
w.WriteHeader(http.StatusUnauthorized)
|
|
enc.Encode(ae)
|
|
return
|
|
}
|
|
|
|
type permissionError interface {
|
|
PermissionError() []map[string]string
|
|
}
|
|
if e, ok := err.(permissionError); ok {
|
|
pe := jsonError{
|
|
Message: "Permission Denied",
|
|
Errors: e.PermissionError(),
|
|
}
|
|
w.WriteHeader(http.StatusForbidden)
|
|
enc.Encode(pe)
|
|
return
|
|
}
|
|
|
|
type mailError interface {
|
|
MailError() []map[string]string
|
|
}
|
|
if e, ok := err.(mailError); ok {
|
|
me := jsonError{
|
|
Message: "Mail Error",
|
|
Errors: e.MailError(),
|
|
}
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
enc.Encode(me)
|
|
return
|
|
}
|
|
|
|
type osqueryError interface {
|
|
error
|
|
NodeInvalid() bool
|
|
}
|
|
if e, ok := err.(osqueryError); ok {
|
|
// osquery expects to receive the node_invalid key when a TLS
|
|
// request provides an invalid node_key for authentication. It
|
|
// doesn't use the error message provided, but we provide this
|
|
// for debugging purposes (and perhaps osquery will use this
|
|
// error message in the future).
|
|
|
|
errMap := map[string]interface{}{"error": e.Error()}
|
|
if e.NodeInvalid() {
|
|
w.WriteHeader(http.StatusUnauthorized)
|
|
errMap["node_invalid"] = true
|
|
} else {
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
}
|
|
|
|
enc.Encode(errMap)
|
|
return
|
|
}
|
|
|
|
type notFoundError interface {
|
|
error
|
|
IsNotFound() bool
|
|
}
|
|
if e, ok := err.(notFoundError); ok {
|
|
je := jsonError{
|
|
Message: "Resource Not Found",
|
|
Errors: baseError(e.Error()),
|
|
}
|
|
w.WriteHeader(http.StatusNotFound)
|
|
enc.Encode(je)
|
|
return
|
|
}
|
|
|
|
type existsError interface {
|
|
error
|
|
IsExists() bool
|
|
}
|
|
if e, ok := err.(existsError); ok {
|
|
je := jsonError{
|
|
Message: "Resource Already Exists",
|
|
Errors: baseError(e.Error()),
|
|
}
|
|
w.WriteHeader(http.StatusConflict)
|
|
enc.Encode(je)
|
|
return
|
|
}
|
|
|
|
// Other errors
|
|
switch domain {
|
|
case kithttp.DomainDecode:
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
case kithttp.DomainDo:
|
|
w.WriteHeader(http.StatusServiceUnavailable)
|
|
default:
|
|
w.WriteHeader(http.StatusInternalServerError)
|
|
}
|
|
je := jsonError{
|
|
Message: "Unknown Error",
|
|
Errors: baseError(err.Error()),
|
|
}
|
|
enc.Encode(je)
|
|
}
|