Skip to content

Commit 14b9121

Browse files
chore(tests): Unit test for edgraph/validateToken () (#8470)
## Problem Missing unit tests for validateToken (), getAcessJwt (), getRefreshJwt () of edgraph package ## Solution TestValidateToken (), TestGetAccessJwt () and TestRefreshJwt () generates a signed JSON Web token using the static data defined in the test file, using the helper function generateJWT (). The generated token includes the token expiry time which is passed as an argument to the helper function. TestValidateToken () calls validateToken and extracts data from the signed token which is then compared to validate with the original data. TestGetAccessJwt() and TestRefreshJwt () are direct wrappers over jwt.NewWithClaims () but with their predefined expiry duration. Co-authored-by: Anurag <[email protected]>
1 parent bc71dc3 commit 14b9121

File tree

2 files changed

+140
-0
lines changed

2 files changed

+140
-0
lines changed

edgraph/access_ee.go

+12
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,18 @@ func validateToken(jwtStr string) (*userData, error) {
195195
return nil, errors.Errorf("userid in claims is not a string:%v", userId)
196196
}
197197

198+
/*
199+
* Since, JSON numbers follow JavaScript's double-precision floating-point
200+
* format . . .
201+
* -- references: https://restfulapi.net/json-data-types/
202+
* -- https://www.tutorialspoint.com/json/json_data_types.htm
203+
* . . . and fraction in IEEE 754 double precision binary floating-point
204+
* format has 52 bits, . . .
205+
* -- references: https://en.wikipedia.org/wiki/Double-precision_floating-point_format
206+
* . . . the namespace field of the struct userData below can
207+
* only accomodate a maximum value of (1 << 52) despite it being declared as
208+
* uint64. Numbers bigger than this are likely to fail the test.
209+
*/
198210
namespace, ok := claims["namespace"].(float64)
199211
if !ok {
200212
return nil, errors.Errorf("namespace in claims is not valid:%v", namespace)

edgraph/access_ee_test.go

+128
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
//go:build !oss
2+
//+build !oss
3+
4+
/*
5+
* Copyright 2022 Dgraph Labs, Inc. All rights reserved.
6+
*
7+
* Licensed under the Dgraph Community License (the "License"); you
8+
* may not use this file except in compliance with the License. You
9+
* may obtain a copy of the License at
10+
*
11+
* https://github.com/dgraph-io/dgraph/blob/master/licenses/DCL.txt
12+
*/
13+
14+
package edgraph
15+
16+
import (
17+
"testing"
18+
"time"
19+
20+
"github.com/dgraph-io/dgraph/ee/acl"
21+
"github.com/dgraph-io/dgraph/worker"
22+
23+
"github.com/stretchr/testify/require"
24+
jwt "github.com/dgrijalva/jwt-go"
25+
)
26+
27+
func generateJWT(namespace uint64, userId string, groupIds []string, expiry int64) string {
28+
claims := jwt.MapClaims{"namespace": namespace, "userid": userId, "exp": expiry}
29+
if groupIds != nil {
30+
claims["groups"] = groupIds
31+
}
32+
token := jwt.NewWithClaims(jwt.SigningMethodHS256, &claims)
33+
34+
tokenString, _ := token.SignedString([]byte(worker.Config.HmacSecret))
35+
36+
return tokenString
37+
}
38+
39+
func sliceCompare(x, y []string) bool {
40+
if len(x) != len(y) {
41+
return false
42+
}
43+
44+
for i := range x {
45+
if x[i] != y[i] {
46+
return false
47+
}
48+
}
49+
50+
return true
51+
}
52+
53+
func TestValidateToken(t *testing.T) {
54+
expiry := time.Now().Add(time.Minute * 30).Unix()
55+
userDataList := []userData{
56+
{1234567890, "user1", []string{"701", "702"}},
57+
{2345678901, "user2", []string{"703", "701"}},
58+
{3456789012, "user3", []string{"702", "703"}},
59+
}
60+
61+
for _, userdata := range userDataList {
62+
tokenString := generateJWT(userdata.namespace, userdata.userId, userdata.groupIds, expiry)
63+
ud, err := validateToken(tokenString)
64+
require.Nil(t, err)
65+
if ud.namespace != userdata.namespace || ud.userId != userdata.userId || !sliceCompare(ud.groupIds, userdata.groupIds) {
66+
t.Errorf("Actual output %+v is not equal to the expected output %+v", userdata, ud)
67+
}
68+
}
69+
}
70+
71+
func TestGetAccessJwt(t *testing.T) {
72+
73+
grpLst := []acl.Group{
74+
{
75+
Uid: "100",
76+
GroupID: "1001",
77+
Users: []acl.User{},
78+
Rules: []acl.Acl{},
79+
},
80+
{
81+
Uid: "101",
82+
GroupID: "1011",
83+
Users: []acl.User{},
84+
Rules: []acl.Acl{},
85+
},
86+
{
87+
Uid: "102",
88+
GroupID: "1021",
89+
Users: []acl.User{},
90+
Rules: []acl.Acl{},
91+
},
92+
}
93+
94+
g := acl.GetGroupIDs(grpLst)
95+
userDataList := []userData{
96+
{1234567890, "user1", []string{"701", "702"}},
97+
{2345678901, "user2", []string{"703", "701"}},
98+
{3456789012, "user3", []string{"702", "703"}},
99+
}
100+
101+
for _, userdata := range userDataList {
102+
jwtstr, _ := getAccessJwt(userdata.userId, grpLst, userdata.namespace)
103+
ud, err := validateToken (jwtstr)
104+
require.Nil(t, err)
105+
if ud.namespace != userdata.namespace || ud.userId != userdata.userId || !sliceCompare(ud.groupIds, g) {
106+
t.Errorf("Actual output {%v %v %v} is not equal to the output %v generated from"+
107+
" getAccessJwt() token", userdata.namespace, userdata.userId, grpLst, ud)
108+
}
109+
}
110+
}
111+
112+
func TestGetRefreshJwt(t *testing.T) {
113+
userDataList := []userData{
114+
{1234567890, "user1", []string{"701", "702"}},
115+
{2345678901, "user2", []string{"703", "701"}},
116+
{3456789012, "user3", []string{"702", "703"}},
117+
}
118+
119+
for _, userdata := range userDataList {
120+
jwtstr, _ := getRefreshJwt(userdata.userId, userdata.namespace)
121+
ud, err := validateToken (jwtstr)
122+
require.Nil(t, err)
123+
if ud.namespace != userdata.namespace || ud.userId != userdata.userId {
124+
t.Errorf("Actual output {%v %v} is not equal to the output {%v %v} generated from"+
125+
"getRefreshJwt() token", userdata.namespace, userdata.userId, ud.namespace, ud.userId)
126+
}
127+
}
128+
}

0 commit comments

Comments
 (0)