Example #1
0
func TestNewDefault(t *testing.T) {
	jm, err := ctxjwt.NewService()
	assert.NoError(t, err)
	assert.Equal(t, time.Hour, jm.Expire)

	assert.Nil(t, jm.Blacklist.Set("test", time.Hour))
	assert.False(t, jm.Blacklist.Has("test"))

	assert.Len(t, jm.JTI.Get(), uuidLen)

	testClaims := map[string]interface{}{
		"mascot": "gopher",
	}
	theToken, jti, err := jm.GenerateToken(testClaims)
	assert.NoError(t, err)
	assert.Empty(t, jti)
	assert.NotEmpty(t, theToken)

	haveToken, err := jm.Parse(theToken)
	assert.NoError(t, err)
	assert.True(t, haveToken.Valid)
	assert.Equal(t, "gopher", haveToken.Claims["mascot"])

	failedToken, err := jm.Parse(theToken + "c")
	assert.Error(t, err)
	assert.Nil(t, failedToken)

	jmRSA, err := ctxjwt.NewService(ctxjwt.WithRSAFromFile("invalid.key"))
	assert.Nil(t, jmRSA)
	assert.Contains(t, err.Error(), "open invalid.key: no such file or directory")
}
Example #2
0
func TestRSAEncryptedNoOrFailedPassword(t *testing.T) {
	jm, err := ctxjwt.NewService(ctxjwt.WithRSAFromFile(pkFile))
	assert.EqualError(t, err, ctxjwt.ErrPrivateKeyNoPassword.Error())
	assert.Nil(t, jm)

	jm2, err2 := ctxjwt.NewService(ctxjwt.WithRSAFromFile(pkFile, []byte(`adfasdf`)))
	assert.EqualError(t, err2, x509.IncorrectPasswordError.Error())
	assert.Nil(t, jm2)
}
Example #3
0
func TestWithParseAndValidateInBlackList(t *testing.T) {
	bl := &testRealBL{}
	jm, err := ctxjwt.NewService(
		ctxjwt.WithBlacklist(bl),
	)
	assert.NoError(t, err)

	theToken, _, err := jm.GenerateToken(nil)
	bl.token = theToken
	assert.NoError(t, err)
	assert.NotEmpty(t, theToken)

	req, err := http.NewRequest("GET", "http://auth.xyz", nil)
	assert.NoError(t, err)
	ctxjwt.SetHeaderAuthorization(req, theToken)

	finalHandler := ctxhttp.HandlerFunc(func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
		w.WriteHeader(http.StatusTeapot)
		return nil
	})
	authHandler := jm.WithParseAndValidate()(finalHandler)

	wRec := httptest.NewRecorder()
	assert.NoError(t, authHandler.ServeHTTPContext(context.Background(), wRec, req))

	assert.NotEqual(t, http.StatusTeapot, wRec.Code)
	assert.Equal(t, http.StatusUnauthorized, wRec.Code)
}
Example #4
0
func TestWithParseAndValidateSuccess(t *testing.T) {
	jm, err := ctxjwt.NewService()
	assert.NoError(t, err)

	theToken, _, err := jm.GenerateToken(map[string]interface{}{
		"xfoo": "bar",
		"zfoo": 4711,
	})
	assert.NoError(t, err)
	assert.NotEmpty(t, theToken)

	req, err := http.NewRequest("GET", "http://auth.xyz", nil)
	assert.NoError(t, err)
	ctxjwt.SetHeaderAuthorization(req, theToken)

	finalHandler := ctxhttp.HandlerFunc(func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
		w.WriteHeader(http.StatusTeapot)
		fmt.Fprintf(w, "I'm more of a coffee pot")

		ctxToken, err := ctxjwt.FromContext(ctx)
		assert.NoError(t, err)
		assert.NotNil(t, ctxToken)
		assert.Exactly(t, "bar", ctxToken.Claims["xfoo"].(string))

		return nil
	})
	authHandler := jm.WithParseAndValidate()(finalHandler)

	wRec := httptest.NewRecorder()
	assert.NoError(t, authHandler.ServeHTTPContext(context.Background(), wRec, req))
	assert.Equal(t, http.StatusTeapot, wRec.Code)
	assert.Equal(t, `I'm more of a coffee pot`, wRec.Body.String())
}
Example #5
0
// newApp creates a new application. function can only be called once
func newApp() *app {
	a := new(app)
	var err error

	// make sure env var CS_DSN is set and points to the appropriate database
	if a.dbc, err = csdb.Connect(); err != nil {
		log.Fatal("MySQL Connect", "err", err)
	}

	if err := config.TableCollection.Init(a.dbc.NewSession()); err != nil {
		log.Fatal("config.TableCollection.Init", "err", err)
	}
	if err := store.TableCollection.Init(a.dbc.NewSession()); err != nil {
		log.Fatal("store.TableCollection.Init", "err", err)
	}

	a.config = config.NewService(config.WithDBStorage(a.dbc.DB))

	// create JSON web token instance
	if a.jwtSrv, err = ctxjwt.NewService(); err != nil {
		log.Fatal("ctxjwt.NewService", "err", err)
	}
	a.jwtSrv.EnableJTI = true

	return a
}
Example #6
0
func TestWithRSAReaderFail(t *testing.T) {

	jm, err := ctxjwt.NewService(
		ctxjwt.WithRSA(bytes.NewReader([]byte(`invalid pem data`))),
	)
	assert.Nil(t, jm)
	assert.Equal(t, "Private Key from io.Reader no found", err.Error())

}
Example #7
0
func TestJTI(t *testing.T) {
	jm, err := ctxjwt.NewService()
	assert.NoError(t, err)
	jm.EnableJTI = true

	theToken, jti, err := jm.GenerateToken(nil)
	assert.NoError(t, err)
	assert.NotEmpty(t, jti)
	assert.NotEmpty(t, theToken)
	assert.Len(t, jti, uuidLen)
}
Example #8
0
func testRsaOption(t *testing.T, opt ctxjwt.Option) {
	jm, err := ctxjwt.NewService(opt)
	assert.NoError(t, err)
	assert.NotNil(t, jm)

	theToken, _, err := jm.GenerateToken(nil)
	assert.NoError(t, err)
	assert.NotEmpty(t, theToken)

	tk, err := jm.Parse(theToken)
	assert.NoError(t, err)
	assert.NotNil(t, tk)
	assert.True(t, tk.Valid)
}
Example #9
0
func testAuth(t *testing.T, errH ctxhttp.Handler, opts ...ctxjwt.Option) (ctxhttp.Handler, string) {
	jm, err := ctxjwt.NewService(opts...)
	assert.NoError(t, err)
	theToken, _, err := jm.GenerateToken(map[string]interface{}{
		"xfoo": "bar",
		"zfoo": 4711,
	})
	assert.NoError(t, err)

	final := ctxhttp.HandlerFunc(func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
		w.WriteHeader(http.StatusOK)
		return nil
	})
	authHandler := jm.WithParseAndValidate(errH)(final)
	return authHandler, theToken
}
Example #10
0
func TestPasswordFromConfig(t *testing.T) {

	cfg := config.NewMockGetter(
		config.WithMockValues(config.MockPV{
			scope.StrDefault.FQPathInt64(ctxjwt.PathJWTPassword): `Rump3lst!lzch3n`,
		}),
	)

	jm, err := ctxjwt.NewService(
		ctxjwt.WithPasswordFromConfig(cfg),
	)
	assert.NoError(t, err)

	theToken, _, err := jm.GenerateToken(nil)
	assert.NoError(t, err)
	assert.NotEmpty(t, theToken)

}
Example #11
0
func TestInvalidSigningMethod(t *testing.T) {
	password := []byte(`Rump3lst!lzch3n`)
	jm, err := ctxjwt.NewService(
		ctxjwt.WithPassword(password),
	)
	assert.NoError(t, err)

	tk := jwt.New(jwt.SigningMethodHS256)
	tk.Claims["exp"] = time.Now().Add(time.Hour).Unix()
	tk.Claims["iat"] = time.Now().Unix()
	tk.Header["alg"] = "HS384"
	malformedToken, err := tk.SignedString(password)
	assert.NoError(t, err)

	mt, err := jm.Parse(malformedToken)
	assert.EqualError(t, err, ctxjwt.ErrUnexpectedSigningMethod.Error())
	assert.Nil(t, mt)
}
Example #12
0
func TestLogout(t *testing.T) {

	tbl := &testBL{T: t}
	jm, err := ctxjwt.NewService(
		ctxjwt.WithBlacklist(tbl),
	)
	assert.NoError(t, err)

	theToken, _, err := jm.GenerateToken(nil)
	assert.NoError(t, err)

	tk, err := jm.Parse(theToken)
	assert.NoError(t, err)
	assert.NotNil(t, tk)

	assert.Nil(t, jm.Logout(nil))
	assert.Nil(t, jm.Logout(tk))
	assert.Equal(t, int(time.Hour.Seconds()), 1+int(tbl.exp.Seconds()))
	assert.Equal(t, theToken, tbl.theToken)
}
Example #13
0
func bmServeHTTP(b *testing.B, opts ...ctxjwt.Option) {
	service, err := ctxjwt.NewService(opts...)
	if err != nil {
		b.Error(err)
	}
	token, _, err := service.GenerateToken(map[string]interface{}{
		"xfoo": "bar",
		"zfoo": 4711,
	})
	if err != nil {
		b.Error(err)
	}

	final := ctxhttp.HandlerFunc(func(_ context.Context, w http.ResponseWriter, _ *http.Request) error {
		w.WriteHeader(http.StatusTeapot)
		return nil
	})
	jwtHandler := service.WithParseAndValidate()(final)

	req, err := http.NewRequest("GET", "http://abc.xyz", nil)
	if err != nil {
		b.Error(err)
	}
	ctxjwt.SetHeaderAuthorization(req, token)
	w := httptest.NewRecorder()
	ctx := context.Background()

	b.ReportAllocs()
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		if err := jwtHandler.ServeHTTPContext(ctx, w, req); err != nil {
			b.Error(err)
		}
		if w.Code != http.StatusTeapot {
			b.Errorf("Response Code want %d; have %d", http.StatusTeapot, w.Code)
		}
	}
}
func ExampleWithInitStoreByToken() {
	initStore()
	ctx := store.NewContextReader(context.Background(), testStoreService)

	jwtService, err := ctxjwt.NewService(ctxjwt.WithPassword([]byte(`GÒph3r`)))

	finalHandler := ctxhttp.Chain(
		ctxhttp.HandlerFunc(func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
			_, haveReqStore, err := store.FromContextReader(ctx)
			if err != nil {
				return err
			}
			// now we know that the current request depends on the store view DE.
			fmt.Fprintf(w, "StoreCode: %s\n", haveReqStore.StoreCode())
			return nil
		}), // 								  executed 3rd
		store.WithInitStoreByToken(),      // executed 2nd
		jwtService.WithParseAndValidate(), // executed 1st
	)

	ts := httptest.NewServer(ctxhttp.NewAdapter(ctx, finalHandler))
	defer ts.Close()

	// Setup GET request
	token, _, err := jwtService.GenerateToken(
		map[string]interface{}{
			// Despite default store for Website ID 1 is AT we are currently
			// in the store context of DE.
			store.ParamName: "de",
		},
	)
	if err != nil {
		log.Fatal("jwtService.GenerateToken", "err", err)
	}

	req, err := http.NewRequest("GET", ts.URL, nil)
	if err != nil {
		log.Fatal("http.Get", "err", err)
	}
	ctxjwt.SetHeaderAuthorization(req, token)

	res, err := http.DefaultClient.Do(req)
	if err != nil {
		log.Fatal("http.DefaultClient.Do", "err", err)
	}

	response, err := ioutil.ReadAll(res.Body)
	if errC := res.Body.Close(); errC != nil {
		log.Fatal("res.Body.Close", "err", errC)
	}

	if err != nil {
		log.Fatal("ioutil.ReadAll", "err", err)
	}

	fmt.Printf("Response: %s\n", response)
	fmt.Printf("Log: %s\n", testDebugLogBuf.String())
	// Output:
	// Response: StoreCode: de
	//
	// Log:
}