github.com/hellofresh/janus@v0.0.0-20230925145208-ce8de8183c67/pkg/plugin/oauth2/middleware_access_rules_test.go (about)

     1  package oauth2
     2  
     3  import (
     4  	"fmt"
     5  	"net/http"
     6  	"testing"
     7  	"time"
     8  
     9  	basejwt "github.com/dgrijalva/jwt-go"
    10  	"github.com/hellofresh/janus/pkg/jwt"
    11  	"github.com/hellofresh/janus/pkg/test"
    12  	"github.com/stretchr/testify/assert"
    13  	"github.com/stretchr/testify/require"
    14  )
    15  
    16  const signingAlg = "HS256"
    17  
    18  func TestBlockJWTByCountry(t *testing.T) {
    19  	secret := "secret"
    20  
    21  	revokeRules := []*AccessRule{
    22  		{Predicate: "country == 'de'", Action: "deny"},
    23  	}
    24  
    25  	parser := jwt.NewParser(jwt.NewParserConfig(0, jwt.SigningMethod{Alg: signingAlg, Key: secret}))
    26  
    27  	mw := NewRevokeRulesMiddleware(parser, revokeRules)
    28  	token, err := generateToken(signingAlg, secret)
    29  	require.NoError(t, err)
    30  
    31  	w, err := test.Record(
    32  		"GET",
    33  		"/",
    34  		map[string]string{
    35  			"Content-Type":  "application/json",
    36  			"Authorization": fmt.Sprintf("Bearer %s", token),
    37  		},
    38  		mw(http.HandlerFunc(test.Ping)),
    39  	)
    40  	assert.NoError(t, err)
    41  	assert.Equal(t, http.StatusUnauthorized, w.Code)
    42  }
    43  
    44  func TestBlockJWTByUsername(t *testing.T) {
    45  	secret := "secret"
    46  
    47  	revokeRules := []*AccessRule{
    48  		{Predicate: "username == 'test@hellofresh.com'", Action: "deny"},
    49  	}
    50  
    51  	parser := jwt.NewParser(jwt.NewParserConfig(0, jwt.SigningMethod{Alg: signingAlg, Key: secret}))
    52  
    53  	mw := NewRevokeRulesMiddleware(parser, revokeRules)
    54  	token, err := generateToken(signingAlg, secret)
    55  	require.NoError(t, err)
    56  
    57  	w, err := test.Record(
    58  		"GET",
    59  		"/",
    60  		map[string]string{
    61  			"Content-Type":  "application/json",
    62  			"Authorization": fmt.Sprintf("Bearer %s", token),
    63  		},
    64  		mw(http.HandlerFunc(test.Ping)),
    65  	)
    66  	assert.NoError(t, err)
    67  	assert.Equal(t, http.StatusUnauthorized, w.Code)
    68  }
    69  
    70  func TestBlockJWTByIssueDate(t *testing.T) {
    71  	secret := "secret"
    72  
    73  	revokeRules := []*AccessRule{
    74  		{Predicate: fmt.Sprintf("iat < %d", time.Now().Add(1*time.Hour).Unix()), Action: "deny"},
    75  	}
    76  
    77  	parser := jwt.NewParser(jwt.NewParserConfig(0, jwt.SigningMethod{Alg: signingAlg, Key: secret}))
    78  
    79  	mw := NewRevokeRulesMiddleware(parser, revokeRules)
    80  	token, err := generateToken(signingAlg, secret)
    81  	require.NoError(t, err)
    82  
    83  	w, err := test.Record(
    84  		"GET",
    85  		"/",
    86  		map[string]string{
    87  			"Content-Type":  "application/json",
    88  			"Authorization": fmt.Sprintf("Bearer %s", token),
    89  		},
    90  		mw(http.HandlerFunc(test.Ping)),
    91  	)
    92  	assert.NoError(t, err)
    93  	assert.Equal(t, http.StatusUnauthorized, w.Code)
    94  }
    95  
    96  func TestBlockJWTByCountryAndIssueDate(t *testing.T) {
    97  	secret := "secret"
    98  
    99  	revokeRules := []*AccessRule{
   100  		{Predicate: fmt.Sprintf("country == 'de' && iat < %d", time.Now().Add(1*time.Hour).Unix()), Action: "deny"},
   101  	}
   102  
   103  	parser := jwt.NewParser(jwt.NewParserConfig(0, jwt.SigningMethod{Alg: signingAlg, Key: secret}))
   104  
   105  	mw := NewRevokeRulesMiddleware(parser, revokeRules)
   106  	token, err := generateToken(signingAlg, secret)
   107  	require.NoError(t, err)
   108  
   109  	w, err := test.Record(
   110  		"GET",
   111  		"/",
   112  		map[string]string{
   113  			"Content-Type":  "application/json",
   114  			"Authorization": fmt.Sprintf("Bearer %s", token),
   115  		},
   116  		mw(http.HandlerFunc(test.Ping)),
   117  	)
   118  	assert.NoError(t, err)
   119  	assert.Equal(t, http.StatusUnauthorized, w.Code)
   120  }
   121  
   122  func generateToken(alg, key string) (string, error) {
   123  	token := basejwt.NewWithClaims(basejwt.GetSigningMethod(alg), basejwt.MapClaims{
   124  		"country":  "de",
   125  		"username": "test@hellofresh.com",
   126  		"iat":      time.Now().Unix(),
   127  	})
   128  
   129  	return token.SignedString([]byte(key))
   130  }
   131  
   132  func TestEmptyAccessRules(t *testing.T) {
   133  	secret := "secret"
   134  
   135  	revokeRules := []*AccessRule{}
   136  
   137  	parser := jwt.NewParser(jwt.NewParserConfig(0, jwt.SigningMethod{Alg: signingAlg, Key: secret}))
   138  
   139  	mw := NewRevokeRulesMiddleware(parser, revokeRules)
   140  
   141  	w, err := test.Record(
   142  		"GET",
   143  		"/",
   144  		nil,
   145  		mw(http.HandlerFunc(test.Ping)),
   146  	)
   147  	require.NoError(t, err)
   148  	assert.Equal(t, http.StatusOK, w.Code)
   149  }
   150  
   151  func TestWrongJWT(t *testing.T) {
   152  	revokeRules := []*AccessRule{
   153  		{Predicate: fmt.Sprintf("country == 'de' && iat < %d", time.Now().Add(1*time.Hour).Unix()), Action: "deny"},
   154  	}
   155  
   156  	parser := jwt.NewParser(jwt.NewParserConfig(0, jwt.SigningMethod{Alg: signingAlg, Key: "wrong secret"}))
   157  
   158  	mw := NewRevokeRulesMiddleware(parser, revokeRules)
   159  	token, err := generateToken(signingAlg, "secret")
   160  	require.NoError(t, err)
   161  
   162  	w, err := test.Record(
   163  		"GET",
   164  		"/",
   165  		map[string]string{
   166  			"Content-Type":  "application/json",
   167  			"Authorization": fmt.Sprintf("Bearer %s", token),
   168  		},
   169  		mw(http.HandlerFunc(test.Ping)),
   170  	)
   171  	assert.NoError(t, err)
   172  	assert.Equal(t, http.StatusOK, w.Code)
   173  }
   174  
   175  func TestWrongRule(t *testing.T) {
   176  	secret := "secret"
   177  
   178  	revokeRules := []*AccessRule{
   179  		{Predicate: "country == 'wrong'", Action: "deny"},
   180  	}
   181  
   182  	parser := jwt.NewParser(jwt.NewParserConfig(0, jwt.SigningMethod{Alg: signingAlg, Key: secret}))
   183  
   184  	mw := NewRevokeRulesMiddleware(parser, revokeRules)
   185  	token, err := generateToken(signingAlg, secret)
   186  	require.NoError(t, err)
   187  
   188  	w, err := test.Record(
   189  		"GET",
   190  		"/",
   191  		map[string]string{
   192  			"Content-Type":  "application/json",
   193  			"Authorization": fmt.Sprintf("Bearer %s", token),
   194  		},
   195  		mw(http.HandlerFunc(test.Ping)),
   196  	)
   197  	assert.NoError(t, err)
   198  	assert.Equal(t, http.StatusOK, w.Code)
   199  }