2016-09-26 18:48:55 +00:00
|
|
|
package service
|
2016-08-28 03:59:17 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"net/http"
|
2016-09-08 01:24:11 +00:00
|
|
|
"strings"
|
2016-08-28 03:59:17 +00:00
|
|
|
|
2016-09-08 01:24:11 +00:00
|
|
|
kithttp "github.com/go-kit/kit/transport/http"
|
2016-09-26 17:14:39 +00:00
|
|
|
"github.com/kolide/kolide-ose/server/contexts/token"
|
|
|
|
"github.com/kolide/kolide-ose/server/contexts/viewer"
|
2016-09-29 00:46:45 +00:00
|
|
|
"github.com/kolide/kolide-ose/server/kolide"
|
2016-09-03 17:25:16 +00:00
|
|
|
"golang.org/x/net/context"
|
2016-08-28 03:59:17 +00:00
|
|
|
)
|
|
|
|
|
2016-09-01 04:51:38 +00:00
|
|
|
// authentication error
|
2016-08-28 03:59:17 +00:00
|
|
|
type authError struct {
|
2016-09-20 19:22:54 +00:00
|
|
|
reason string
|
|
|
|
// client reason is used to provide
|
|
|
|
// a different error message to the client
|
|
|
|
// when security is a concern
|
|
|
|
clientReason string
|
2016-08-28 03:59:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (e authError) Error() string {
|
2016-09-20 19:22:54 +00:00
|
|
|
return e.reason
|
|
|
|
}
|
|
|
|
|
|
|
|
func (e authError) AuthError() string {
|
|
|
|
if e.clientReason != "" {
|
|
|
|
return e.clientReason
|
2016-08-28 03:59:17 +00:00
|
|
|
}
|
2016-09-29 00:46:45 +00:00
|
|
|
return "username or email and password do not match"
|
2016-08-28 03:59:17 +00:00
|
|
|
}
|
|
|
|
|
2016-09-23 02:41:58 +00:00
|
|
|
// permissionError, set when user is authenticated, but not allowed to perform action
|
|
|
|
type permissionError struct {
|
2016-09-01 04:51:38 +00:00
|
|
|
message string
|
2016-09-23 02:41:58 +00:00
|
|
|
badArgs []invalidArgument
|
2016-09-01 04:51:38 +00:00
|
|
|
}
|
|
|
|
|
2016-09-23 02:41:58 +00:00
|
|
|
func (e permissionError) Error() string {
|
|
|
|
switch len(e.badArgs) {
|
|
|
|
case 0:
|
|
|
|
case 1:
|
|
|
|
e.message = fmt.Sprintf("unauthorized: %s",
|
|
|
|
e.badArgs[0].reason,
|
|
|
|
)
|
|
|
|
default:
|
|
|
|
e.message = fmt.Sprintf("unauthorized: %s and %d other errors",
|
|
|
|
e.badArgs[0].reason,
|
|
|
|
len(e.badArgs),
|
|
|
|
)
|
|
|
|
}
|
2016-09-01 04:51:38 +00:00
|
|
|
if e.message == "" {
|
|
|
|
return "unauthorized"
|
|
|
|
}
|
2016-09-23 02:41:58 +00:00
|
|
|
return e.message
|
|
|
|
}
|
|
|
|
|
|
|
|
func (e permissionError) PermissionError() []map[string]string {
|
|
|
|
var forbidden []map[string]string
|
|
|
|
if len(e.badArgs) == 0 {
|
|
|
|
forbidden = append(forbidden, map[string]string{"reason": e.Error()})
|
|
|
|
return forbidden
|
|
|
|
}
|
|
|
|
for _, arg := range e.badArgs {
|
|
|
|
forbidden = append(forbidden, map[string]string{
|
|
|
|
"name": arg.name,
|
|
|
|
"reason": arg.reason,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
return forbidden
|
|
|
|
|
2016-09-01 04:51:38 +00:00
|
|
|
}
|
|
|
|
|
2016-09-26 17:14:39 +00:00
|
|
|
// setRequestsContexts updates the request with necessary context values for a request
|
|
|
|
func setRequestsContexts(svc kolide.Service, jwtKey string) kithttp.RequestFunc {
|
2016-09-08 01:24:11 +00:00
|
|
|
return func(ctx context.Context, r *http.Request) context.Context {
|
2016-09-26 17:14:39 +00:00
|
|
|
bearer := token.FromHTTPRequest(r)
|
|
|
|
ctx = token.NewContext(ctx, bearer)
|
|
|
|
v, err := authViewer(ctx, jwtKey, bearer, svc)
|
|
|
|
if err == nil {
|
|
|
|
ctx = viewer.NewContext(ctx, *v)
|
2016-09-08 01:24:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// get the user-id for request
|
|
|
|
if strings.Contains(r.URL.Path, "users/") {
|
|
|
|
ctx = withUserIDFromRequest(r, ctx)
|
|
|
|
}
|
|
|
|
return ctx
|
2016-08-28 03:59:17 +00:00
|
|
|
}
|
2016-09-08 01:24:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func withUserIDFromRequest(r *http.Request, ctx context.Context) context.Context {
|
|
|
|
id, _ := idFromRequest(r, "id")
|
|
|
|
return context.WithValue(ctx, "request-id", id)
|
2016-08-28 03:59:17 +00:00
|
|
|
}
|