remove deprecated errors package (#961)

This commit is contained in:
Victor Vrantchan 2017-01-14 15:00:09 -05:00 committed by GitHub
parent 501f2c74c7
commit 3802f3098e
6 changed files with 52 additions and 206 deletions

View File

@ -1,62 +0,0 @@
package errors
import "net/http"
// Kolide's internal representation for errors. It can be used to wrap another
// error (stored in Err), and additionally contains fields for public
// (PublicMessage) and private (PrivateMessage) error messages as well as the
// HTTP status code (StatusCode) corresponding to the error. Extra holds extra
// information that will be inserted as top level key/value pairs in the error
// response.
type KolideError struct {
Err error
StatusCode int
PublicMessage string
PrivateMessage string
Extra map[string]interface{}
}
// Implementation of error interface
func (e *KolideError) Error() string {
return e.PublicMessage
}
// Create a new KolideError specifying the public and private messages. The
// status code will be set to 500.
func New(publicMessage, privateMessage string) *KolideError {
return &KolideError{
StatusCode: http.StatusInternalServerError,
PublicMessage: publicMessage,
PrivateMessage: privateMessage,
}
}
// Create a new KolideError specifying the HTTP status, and public and private
// messages.
func NewWithStatus(status int, publicMessage, privateMessage string) *KolideError {
return &KolideError{
StatusCode: status,
PublicMessage: publicMessage,
PrivateMessage: privateMessage,
}
}
// Create a new KolideError from an error type. The public message and status
// code should be specified, while the private message will be drawn from
// err.Error()
func NewFromError(err error, status int, publicMessage string) *KolideError {
return &KolideError{
Err: err,
StatusCode: status,
PublicMessage: publicMessage,
PrivateMessage: err.Error(),
}
}
// Wrap a server error with the extra KolideError decorations
func InternalServerError(err error) *KolideError {
return NewFromError(err, http.StatusInternalServerError, "Internal server error")
}
// The status code returned for validation errors. Inspired by the Github API.
const StatusUnprocessableEntity = 422

View File

@ -1,67 +0,0 @@
package errors
import (
"errors"
"net/http"
"testing"
"github.com/stretchr/testify/assert"
)
func TestNew(t *testing.T) {
kolideErr := New("Public message", "Private message")
expect := &KolideError{
Err: nil,
StatusCode: http.StatusInternalServerError,
PublicMessage: "Public message",
PrivateMessage: "Private message",
}
assert.Equal(t, expect, kolideErr)
}
func TestNewWithStatus(t *testing.T) {
kolideErr := NewWithStatus(http.StatusUnauthorized, "Public message", "Private message")
expect := &KolideError{
Err: nil,
StatusCode: http.StatusUnauthorized,
PublicMessage: "Public message",
PrivateMessage: "Private message",
}
assert.Equal(t, expect, kolideErr)
}
func TestNewFromError(t *testing.T) {
err := errors.New("Foo error")
kolideErr := NewFromError(err, StatusUnprocessableEntity, "Public error")
assert.Equal(t, "Public error", kolideErr.Error())
expect := &KolideError{
Err: err,
StatusCode: StatusUnprocessableEntity,
PublicMessage: "Public error",
PrivateMessage: "Foo error",
}
assert.Equal(t, expect, kolideErr)
}
// These types and functions for performing an unordered comparison on a
// []map[string]string] as parsed from the error JSON
type errorField map[string]string
type errorFields []errorField
func (e errorFields) Len() int {
return len(e)
}
func (e errorFields) Less(i, j int) bool {
return e[i]["field"] <= e[j]["field"] &&
e[i]["code"] <= e[j]["code"] &&
e[i]["message"] <= e[j]["message"]
}
func (e errorFields) Swap(i, j int) {
e[i], e[j] = e[j], e[i]
}

View File

@ -3,31 +3,9 @@ package kolide
import (
"time"
jwt "github.com/dgrijalva/jwt-go"
"github.com/kolide/kolide-ose/server/errors"
"golang.org/x/net/context"
)
const publicErrorMessage string = "Session error"
var (
// An error returned by SessionStore.Get() if no session record was found
// in the database
ErrNoActiveSession = errors.New(publicErrorMessage, "Active session is not present in the database")
// An error returned by SessionStore methods when no session object has
// been created yet but the requested action requires one
ErrSessionNotCreated = errors.New(publicErrorMessage, "The session has not been created")
// An error returned by SessionStore.Get() when a session is requested but
// it has expired
ErrSessionExpired = errors.New(publicErrorMessage, "The session has expired")
// An error returned by SessionStore which indicates that the token
// or it's content were malformed
ErrSessionMalformed = errors.New(publicErrorMessage, "The session token was malformed")
)
// SessionStore is the abstract interface that all session backends must
// conform to.
type SessionStore interface {
@ -74,28 +52,3 @@ type Session struct {
UserID uint `db:"user_id"`
Key string
}
////////////////////////////////////////////////////////////////////////////////
// JSON Web Tokens
////////////////////////////////////////////////////////////////////////////////
// Given a session key create a JWT to be delivered to the client
func GenerateJWT(sessionKey, jwtKey string) (string, error) {
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"session_key": sessionKey,
})
return token.SignedString([]byte(jwtKey))
}
// ParseJWT attempts to parse a JWT token in serialized string form into a
// JWT token in a deserialized jwt.Token struct.
func ParseJWT(token, jwtKey string) (*jwt.Token, error) {
return jwt.Parse(token, func(t *jwt.Token) (interface{}, error) {
method, ok := t.Method.(*jwt.SigningMethodHMAC)
if !ok || method != jwt.SigningMethodHS256 {
return nil, errors.New(publicErrorMessage, "Unexpected signing method")
}
return []byte(jwtKey), nil
})
}

View File

@ -1,23 +0,0 @@
package kolide
import (
"testing"
jwt "github.com/dgrijalva/jwt-go"
"github.com/stretchr/testify/assert"
)
func TestGenerateJWT(t *testing.T) {
tokenString, err := GenerateJWT("4", "")
assert.Nil(t, err)
token, err := ParseJWT(tokenString, "")
assert.Nil(t, err)
claims, ok := token.Claims.(jwt.MapClaims)
assert.True(t, ok)
assert.True(t, token.Valid)
sessionKey := claims["session_key"].(string)
assert.Equal(t, "4", sessionKey)
}

View File

@ -6,8 +6,10 @@ import (
"strings"
"time"
jwt "github.com/dgrijalva/jwt-go"
"github.com/kolide/kolide-ose/server/contexts/viewer"
"github.com/kolide/kolide-ose/server/kolide"
"github.com/pkg/errors"
"golang.org/x/net/context"
)
@ -57,12 +59,12 @@ func (svc service) makeSession(id uint) (string, error) {
session, err = svc.ds.NewSession(session)
if err != nil {
return "", err
return "", errors.Wrap(err, "creating new session")
}
tokenString, err := kolide.GenerateJWT(session.Key, svc.config.Auth.JwtKey)
tokenString, err := generateJWT(session.Key, svc.config.Auth.JwtKey)
if err != nil {
return "", err
return "", errors.Wrap(err, "generating JWT token")
}
return tokenString, nil
@ -146,7 +148,10 @@ func (svc service) DeleteSession(ctx context.Context, id uint) error {
func (svc service) validateSession(session *kolide.Session) error {
if session == nil {
return kolide.ErrNoActiveSession
return authError{
reason: "active session not present",
clientReason: "session error",
}
}
sessionDuration := svc.config.Session.Duration
@ -154,10 +159,22 @@ func (svc service) validateSession(session *kolide.Session) error {
if sessionDuration != 0 && time.Since(session.AccessedAt) >= sessionDuration {
err := svc.ds.DestroySession(session)
if err != nil {
return err
return errors.Wrap(err, "destroying session")
}
return authError{
reason: "expired session",
clientReason: "session error",
}
return kolide.ErrSessionExpired
}
return svc.ds.MarkSessionAccessed(session)
}
// Given a session key create a JWT to be delivered to the client
func generateJWT(sessionKey, jwtKey string) (string, error) {
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"session_key": sessionKey,
})
return token.SignedString([]byte(jwtKey))
}

View File

@ -5,6 +5,7 @@ import (
"time"
"github.com/kolide/kolide-ose/server/config"
"github.com/kolide/kolide-ose/server/contexts/token"
"github.com/kolide/kolide-ose/server/datastore/inmem"
"github.com/kolide/kolide-ose/server/kolide"
"github.com/stretchr/testify/assert"
@ -57,5 +58,32 @@ func TestAuthenticate(t *testing.T) {
"access time should be set with current time at session creation")
})
}
}
func TestGenerateJWT(t *testing.T) {
jwtKey := ""
tokenString, err := generateJWT("4", jwtKey)
require.Nil(t, err)
svc := authViewerService{}
viewer, err := authViewer(
context.Background(),
jwtKey,
token.Token(tokenString),
svc,
)
require.Nil(t, err)
require.NotNil(t, viewer)
}
type authViewerService struct {
kolide.Service
}
func (authViewerService) GetSessionByKey(ctx context.Context, key string) (*kolide.Session, error) {
return &kolide.Session{}, nil
}
func (authViewerService) User(ctx context.Context, uid uint) (*kolide.User, error) {
return &kolide.User{}, nil
}