github.com/jacobsoderblom/buffalo@v0.11.0/middleware/tokenauth/tokenauth_test.go (about)

     1  package tokenauth_test
     2  
     3  import (
     4  	"fmt"
     5  	"io/ioutil"
     6  	"log"
     7  	"net/http"
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/dgrijalva/jwt-go"
    12  	"github.com/gobuffalo/envy"
    13  	"github.com/pkg/errors"
    14  
    15  	"github.com/gobuffalo/buffalo"
    16  	"github.com/gobuffalo/buffalo/middleware/tokenauth"
    17  	"github.com/markbates/willie"
    18  	"github.com/stretchr/testify/require"
    19  )
    20  
    21  func appHMAC() *buffalo.App {
    22  	h := func(c buffalo.Context) error {
    23  		return c.Render(200, nil)
    24  	}
    25  	envy.Set("JWT_SECRET", "secret")
    26  	a := buffalo.New(buffalo.Options{})
    27  	// if method not specified it will use HMAC
    28  	a.Use(tokenauth.New(tokenauth.Options{
    29  		GetKey: tokenauth.GetHMACKey,
    30  	}))
    31  	a.GET("/", h)
    32  	return a
    33  }
    34  func appRSA() *buffalo.App {
    35  	h := func(c buffalo.Context) error {
    36  		return c.Render(200, nil)
    37  	}
    38  	envy.Set("JWT_PUBLIC_KEY", "test_certs/sample_key.pub")
    39  	a := buffalo.New(buffalo.Options{})
    40  	a.Use(tokenauth.New(tokenauth.Options{
    41  		SignMethod: jwt.SigningMethodRS256,
    42  	}))
    43  	a.GET("/", h)
    44  	return a
    45  }
    46  
    47  func appRSAPSS() *buffalo.App {
    48  	h := func(c buffalo.Context) error {
    49  		return c.Render(200, nil)
    50  	}
    51  	envy.Set("JWT_PUBLIC_KEY", "test_certs/sample_key.pub")
    52  	a := buffalo.New(buffalo.Options{})
    53  	a.Use(tokenauth.New(tokenauth.Options{
    54  		SignMethod: jwt.SigningMethodPS256,
    55  		GetKey:     tokenauth.GetKeyRSAPSS,
    56  	}))
    57  	a.GET("/", h)
    58  	return a
    59  }
    60  
    61  func appECDSA() *buffalo.App {
    62  	h := func(c buffalo.Context) error {
    63  		return c.Render(200, nil)
    64  	}
    65  	envy.Set("JWT_PUBLIC_KEY", "test_certs/ec256-public.pem")
    66  
    67  	a := buffalo.New(buffalo.Options{})
    68  	a.Use(tokenauth.New(tokenauth.Options{
    69  		SignMethod: jwt.SigningMethodES256,
    70  	}))
    71  	a.GET("/", h)
    72  	return a
    73  }
    74  
    75  // Test HMAC
    76  func TestTokenHMAC(t *testing.T) {
    77  	r := require.New(t)
    78  	w := willie.New(appHMAC())
    79  
    80  	// Missing Authorization
    81  	res := w.Request("/").Get()
    82  	r.Equal(http.StatusUnauthorized, res.Code)
    83  
    84  	// invalid token
    85  	req := w.Request("/")
    86  	req.Headers["Authorization"] = "badcreds"
    87  	res = req.Get()
    88  	r.Equal(http.StatusUnauthorized, res.Code)
    89  	r.Contains(res.Body.String(), "token invalid")
    90  
    91  	// expired token
    92  	secretKey := envy.Get("JWT_SECRET", "secret")
    93  	claims := jwt.MapClaims{}
    94  	claims["sub"] = "1234567890"
    95  	claims["exp"] = time.Now().Add(-time.Minute * 5).Unix()
    96  
    97  	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
    98  	tokenString, _ := token.SignedString([]byte(secretKey))
    99  	req.Headers["Authorization"] = fmt.Sprintf("Bearer %s", tokenString)
   100  	res = req.Get()
   101  	//fmt.Println(res.Body.String())
   102  	r.Equal(http.StatusUnauthorized, res.Code)
   103  	r.Contains(res.Body.String(), "Token is expired")
   104  
   105  	// valid token
   106  	claims["exp"] = time.Now().Add(time.Minute * 5).Unix()
   107  	token = jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
   108  	tokenString, _ = token.SignedString([]byte(secretKey))
   109  	req.Headers["Authorization"] = fmt.Sprintf("Bearer %s", tokenString)
   110  	res = req.Get()
   111  	r.Equal(http.StatusOK, res.Code)
   112  }
   113  
   114  // Test RSA
   115  func TestTokenRSA(t *testing.T) {
   116  	r := require.New(t)
   117  	w := willie.New(appRSA())
   118  
   119  	// Missing Authorization
   120  	res := w.Request("/").Get()
   121  	r.Equal(http.StatusUnauthorized, res.Code)
   122  
   123  	// invalid token
   124  	req := w.Request("/")
   125  	req.Headers["Authorization"] = "badcreds"
   126  	res = req.Get()
   127  	r.Equal(http.StatusUnauthorized, res.Code)
   128  	r.Contains(res.Body.String(), "token invalid")
   129  
   130  	// expired token
   131  	privateKeyFile := envy.Get("JWT_PRIVATE_KEY", "test_certs/sample_key")
   132  	key, err := ioutil.ReadFile(privateKeyFile)
   133  	if err != nil {
   134  		log.Fatal(err)
   135  	}
   136  	parsedKey, err := jwt.ParseRSAPrivateKeyFromPEM(key)
   137  	if err != nil {
   138  		log.Fatal(errors.Wrap(err, "error parsing key"))
   139  	}
   140  	claims := jwt.MapClaims{}
   141  	claims["sub"] = "1234567890"
   142  	claims["exp"] = time.Now().Add(-time.Minute * 5).Unix()
   143  
   144  	token := jwt.NewWithClaims(jwt.SigningMethodRS256, claims)
   145  	tokenString, err := token.SignedString(parsedKey)
   146  	if err != nil {
   147  		log.Fatal(errors.Wrap(err, "error signing token"))
   148  	}
   149  	req.Headers["Authorization"] = fmt.Sprintf("Bearer %s", tokenString)
   150  	res = req.Get()
   151  	r.Equal(http.StatusUnauthorized, res.Code)
   152  	r.Contains(res.Body.String(), "Token is expired")
   153  
   154  	// valid token
   155  	claims["exp"] = time.Now().Add(time.Minute * 5).Unix()
   156  	token = jwt.NewWithClaims(jwt.SigningMethodRS256, claims)
   157  	tokenString, _ = token.SignedString(parsedKey)
   158  	req.Headers["Authorization"] = fmt.Sprintf("Bearer %s", tokenString)
   159  	res = req.Get()
   160  	r.Equal(http.StatusOK, res.Code)
   161  }
   162  
   163  // Test ECDSA
   164  func TestTokenECDSA(t *testing.T) {
   165  	r := require.New(t)
   166  	w := willie.New(appECDSA())
   167  
   168  	// Missing Authorization
   169  	res := w.Request("/").Get()
   170  	r.Equal(http.StatusUnauthorized, res.Code)
   171  
   172  	// invalid token
   173  	req := w.Request("/")
   174  	req.Headers["Authorization"] = "badcreds"
   175  	res = req.Get()
   176  	r.Equal(http.StatusUnauthorized, res.Code)
   177  	r.Contains(res.Body.String(), "token invalid")
   178  
   179  	// expired token
   180  	privateKeyFile := envy.Get("JWT_PRIVATE_KEY", "test_certs/ec256-private.pem")
   181  	key, err := ioutil.ReadFile(privateKeyFile)
   182  	if err != nil {
   183  		log.Fatal(errors.Wrap(err, "error reading keyfile"))
   184  	}
   185  	parsedKey, err := jwt.ParseECPrivateKeyFromPEM(key)
   186  	if err != nil {
   187  		log.Fatal(errors.Wrap(err, "error parsing key"))
   188  	}
   189  	claims := jwt.MapClaims{}
   190  	claims["sub"] = "1234567890"
   191  	claims["exp"] = time.Now().Add(-time.Minute * 5).Unix()
   192  	token := jwt.NewWithClaims(jwt.SigningMethodES256, claims)
   193  	tokenString, err := token.SignedString(parsedKey)
   194  	if err != nil {
   195  		log.Fatal(errors.Wrap(err, "error signing token"))
   196  	}
   197  	req.Headers["Authorization"] = fmt.Sprintf("Bearer %s", tokenString)
   198  	res = req.Get()
   199  	r.Equal(http.StatusUnauthorized, res.Code)
   200  	r.Contains(res.Body.String(), "Token is expired")
   201  
   202  	// valid token
   203  	claims["exp"] = time.Now().Add(time.Minute * 5).Unix()
   204  	token = jwt.NewWithClaims(jwt.SigningMethodES256, claims)
   205  	tokenString, _ = token.SignedString(parsedKey)
   206  	req.Headers["Authorization"] = fmt.Sprintf("Bearer %s", tokenString)
   207  	res = req.Get()
   208  	r.Equal(http.StatusOK, res.Code)
   209  }
   210  
   211  // Test RSAPSS
   212  func TestTokenRSAPSS(t *testing.T) {
   213  	r := require.New(t)
   214  	w := willie.New(appRSAPSS())
   215  
   216  	// Missing Authorization
   217  	res := w.Request("/").Get()
   218  	r.Equal(http.StatusUnauthorized, res.Code)
   219  
   220  	// invalid token
   221  	req := w.Request("/")
   222  	req.Headers["Authorization"] = "badcreds"
   223  	res = req.Get()
   224  	r.Equal(http.StatusUnauthorized, res.Code)
   225  	r.Contains(res.Body.String(), "token invalid")
   226  
   227  	// expired token
   228  	privateKeyFile := envy.Get("JWT_PRIVATE_KEY", "test_certs/sample_key")
   229  	key, err := ioutil.ReadFile(privateKeyFile)
   230  	if err != nil {
   231  		log.Fatal(err)
   232  	}
   233  	parsedKey, err := jwt.ParseRSAPrivateKeyFromPEM(key)
   234  	if err != nil {
   235  		log.Fatal(errors.Wrap(err, "error parsing key"))
   236  	}
   237  	claims := jwt.MapClaims{}
   238  	claims["sub"] = "1234567890"
   239  	claims["exp"] = time.Now().Add(-time.Minute * 5).Unix()
   240  
   241  	token := jwt.NewWithClaims(jwt.SigningMethodPS256, claims)
   242  	tokenString, err := token.SignedString(parsedKey)
   243  	if err != nil {
   244  		log.Fatal(errors.Wrap(err, "error signing token"))
   245  	}
   246  	req.Headers["Authorization"] = fmt.Sprintf("Bearer %s", tokenString)
   247  	res = req.Get()
   248  	r.Equal(http.StatusUnauthorized, res.Code)
   249  	r.Contains(res.Body.String(), "Token is expired")
   250  
   251  	// valid token
   252  	claims["exp"] = time.Now().Add(time.Minute * 5).Unix()
   253  	token = jwt.NewWithClaims(jwt.SigningMethodPS256, claims)
   254  	tokenString, _ = token.SignedString(parsedKey)
   255  	req.Headers["Authorization"] = fmt.Sprintf("Bearer %s", tokenString)
   256  	res = req.Get()
   257  	r.Equal(http.StatusOK, res.Code)
   258  }