Skip to content

Commit

Permalink
test(acl): add upgrade tests for ee/acl package (#8792)
Browse files Browse the repository at this point in the history
This PR also adds HealthForInstance API to dgraphtest package for
checking health of Alpha through graphql.
  • Loading branch information
shivaji-kharse authored Jul 11, 2023
1 parent bfbbecb commit ed7af9c
Show file tree
Hide file tree
Showing 14 changed files with 1,611 additions and 1,782 deletions.
1 change: 0 additions & 1 deletion dgraphtest/acl.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,6 @@ func (hc *HTTPClient) CreateGroup(name string) (string, error) {
if err != nil {
return "", nil
}

type Response struct {
AddGroup struct {
Group []struct {
Expand Down
21 changes: 18 additions & 3 deletions dgraphtest/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -246,11 +246,27 @@ func (hc *HTTPClient) RunGraphqlQuery(params GraphQLParams, admin bool) ([]byte,
return nil, errors.Wrap(err, "error unmarshalling GQL response")
}
if len(gqlResp.Errors) > 0 {
return nil, errors.Wrapf(gqlResp.Errors, "error while running admin query")
return nil, errors.Wrapf(gqlResp.Errors, "error while running admin query, resp: %v", string(gqlResp.Data))
}
return gqlResp.Data, nil
}

func (hc *HTTPClient) HealthForInstance() ([]byte, error) {
const query = `query {
health {
instance
address
lastEcho
status
version
uptime
group
}
}`
params := GraphQLParams{Query: query}
return hc.RunGraphqlQuery(params, true)
}

// Backup creates a backup of dgraph at a given path
func (hc *HTTPClient) Backup(c Cluster, forceFull bool, backupPath string) error {
// backup API was made async in the commit d3bf7b7b2786bcb99f02e1641f3b656d0a98f7f4
Expand Down Expand Up @@ -531,13 +547,12 @@ func (gc *GrpcClient) DropPredicate(pred string) error {
}

// Mutate performs a given mutation in a txn
func (gc *GrpcClient) Mutate(rdfs string) (*api.Response, error) {
func (gc *GrpcClient) Mutate(mu *api.Mutation) (*api.Response, error) {
txn := gc.NewTxn()
defer func() { _ = txn.Discard(context.Background()) }()

ctx, cancel := context.WithTimeout(context.Background(), requestTimeout)
defer cancel()
mu := &api.Mutation{SetNquads: []byte(rdfs), CommitNow: true}
return txn.Mutate(ctx, mu)
}

Expand Down
1 change: 1 addition & 0 deletions dgraphtest/compose_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ func (c *ComposeCluster) Client() (*GrpcClient, func(), error) {
return &GrpcClient{Dgraph: client}, func() {}, nil
}

// HTTPClient creates an HTTP client
func (c *ComposeCluster) HTTPClient() (*HTTPClient, error) {
adminUrl := "http://" + testutil.SockAddrHttp + "/admin"
graphQLUrl := "http://" + testutil.SockAddrHttp + "/graphql"
Expand Down
2 changes: 1 addition & 1 deletion dgraphtest/dgraph.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ const (

localVersion = "local"
waitDurBeforeRetry = time.Second
requestTimeout = 90 * time.Second
requestTimeout = 120 * time.Second
)

var (
Expand Down
2 changes: 1 addition & 1 deletion dgraphtest/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ func runGitCheckout(gitRef string) error {
}

func buildDgraphBinary(dir, binaryDir, version string) error {
log.Printf("[INFO] building dgraph binary")
log.Printf("[INFO] building dgraph binary for version [%v]", version)

cmd := exec.Command("make", "dgraph")
cmd.Dir = filepath.Join(dir, "dgraph")
Expand Down
6 changes: 6 additions & 0 deletions dgraphtest/paths.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,10 @@ func init() {
binDir = filepath.Join(basePath, "binaries")
encKeyPath = filepath.Join(basePath, "data", "enc-key")
aclSecretPath = filepath.Join(basePath, "data", "hmac-secret")

log.Printf("[INFO] baseRepoDir: %v", baseRepoDir)
log.Printf("[INFO] repoDir: %v", repoDir)
log.Printf("[INFO] binDir: %v", binDir)
log.Printf("[INFO] encKeyPath: %v", encKeyPath)
log.Printf("[INFO] aclSecretPath: %v", aclSecretPath)
}
92 changes: 44 additions & 48 deletions ee/acl/acl_curl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,48 +14,48 @@
package acl

import (
"context"
"fmt"
"testing"
"time"

"github.com/golang/glog"
"github.com/stretchr/testify/require"

"github.com/dgraph-io/dgraph/dgraphtest"
"github.com/dgraph-io/dgraph/testutil"
"github.com/dgraph-io/dgraph/x"
)

var adminEndpoint string

func TestCurlAuthorization(t *testing.T) {
func (asuite *AclTestSuite) TestCurlAuthorization() {
t := asuite.T()
if testing.Short() {
t.Skip("skipping because -short=true")
}

glog.Infof("testing with port %s", testutil.SockAddr)
dg, err := testutil.DgraphClientWithGroot(testutil.SockAddr)
if err != nil {
t.Fatalf("Error while getting a dgraph client: %v", err)
}
createAccountAndData(t, dg)
ctx, cancel := context.WithTimeout(context.Background(), 100*time.Second)
defer cancel()
gc, cleanup, err := asuite.dc.Client()
require.NoError(t, err)
defer cleanup()
require.NoError(t, gc.LoginIntoNamespace(ctx, dgraphtest.DefaultUser,
dgraphtest.DefaultPassword, x.GalaxyNamespace))

hc, err := asuite.dc.HTTPClient()
require.NoError(t, err)
require.NoError(t, hc.LoginIntoNamespace(dgraphtest.DefaultUser,
dgraphtest.DefaultPassword, x.GalaxyNamespace))
createAccountAndData(t, gc, hc)

// test query through curl
token, err := testutil.HttpLogin(&testutil.LoginParams{
Endpoint: adminEndpoint,
UserID: userid,
Passwd: userpassword,
Namespace: x.GalaxyNamespace,
})
require.NoError(t, err, "login failed")

require.NoError(t, hc.LoginIntoNamespace(userid, userpassword, x.GalaxyNamespace))
// No ACL rules are specified, so query should return empty response,
// alter and mutate should fail.
queryArgs := func(jwt string) []string {
return []string{"-H", fmt.Sprintf("X-Dgraph-AccessToken:%s", jwt),
"-H", "Content-Type: application/dql",
"-d", query, testutil.SockAddrHttp + "/query"}
}
testutil.VerifyCurlCmd(t, queryArgs(token.AccessJwt), &testutil.CurlFailureConfig{
testutil.VerifyCurlCmd(t, queryArgs(hc.AccessJwt), &testutil.CurlFailureConfig{
ShouldFail: false,
})

Expand All @@ -68,7 +68,7 @@ func TestCurlAuthorization(t *testing.T) {

}

testutil.VerifyCurlCmd(t, mutateArgs(token.AccessJwt), &testutil.CurlFailureConfig{
testutil.VerifyCurlCmd(t, mutateArgs(hc.AccessJwt), &testutil.CurlFailureConfig{
ShouldFail: true,
DgraphErrMsg: "PermissionDenied",
})
Expand All @@ -77,7 +77,7 @@ func TestCurlAuthorization(t *testing.T) {
return []string{"-H", fmt.Sprintf("X-Dgraph-AccessToken:%s", jwt),
"-d", fmt.Sprintf(`%s: int .`, predicateToAlter), testutil.SockAddrHttp + "/alter"}
}
testutil.VerifyCurlCmd(t, alterArgs(token.AccessJwt), &testutil.CurlFailureConfig{
testutil.VerifyCurlCmd(t, alterArgs(hc.AccessJwt), &testutil.CurlFailureConfig{
ShouldFail: true,
DgraphErrMsg: "PermissionDenied",
})
Expand All @@ -87,68 +87,64 @@ func TestCurlAuthorization(t *testing.T) {
// JWT
glog.Infof("Sleeping for accessJwt to expire")
time.Sleep(expireJwtSleep)
testutil.VerifyCurlCmd(t, queryArgs(token.AccessJwt), &testutil.CurlFailureConfig{
testutil.VerifyCurlCmd(t, queryArgs(hc.AccessJwt), &testutil.CurlFailureConfig{
ShouldFail: true,
DgraphErrMsg: "Token is expired",
})
testutil.VerifyCurlCmd(t, mutateArgs(token.AccessJwt), &testutil.CurlFailureConfig{
testutil.VerifyCurlCmd(t, mutateArgs(hc.AccessJwt), &testutil.CurlFailureConfig{
ShouldFail: true,
DgraphErrMsg: "Token is expired",
})
testutil.VerifyCurlCmd(t, alterArgs(token.AccessJwt), &testutil.CurlFailureConfig{
testutil.VerifyCurlCmd(t, alterArgs(hc.AccessJwt), &testutil.CurlFailureConfig{
ShouldFail: true,
DgraphErrMsg: "Token is expired",
})
// login again using the refreshJwt
token, err = testutil.HttpLogin(&testutil.LoginParams{
Endpoint: adminEndpoint,
RefreshJwt: token.RefreshToken,
Namespace: x.GalaxyNamespace,
})
require.NoError(t, hc.LoginUsingToken(x.GalaxyNamespace))
require.NoError(t, err, fmt.Sprintf("login through refresh httpToken failed: %v", err))

createGroupAndAcls(t, unusedGroup, false)
hcWithGroot, err := asuite.dc.HTTPClient()
require.NoError(t, err)
require.NoError(t, hcWithGroot.LoginIntoNamespace(dgraphtest.DefaultUser,
dgraphtest.DefaultPassword, x.GalaxyNamespace))
createGroupAndAcls(t, unusedGroup, false, hcWithGroot)
time.Sleep(expireJwtSleep)
testutil.VerifyCurlCmd(t, queryArgs(token.AccessJwt), &testutil.CurlFailureConfig{
testutil.VerifyCurlCmd(t, queryArgs(hc.AccessJwt), &testutil.CurlFailureConfig{
ShouldFail: true,
DgraphErrMsg: "Token is expired",
})
// refresh the jwts again
token, err = testutil.HttpLogin(&testutil.LoginParams{
Endpoint: adminEndpoint,
RefreshJwt: token.RefreshToken,
})
require.NoError(t, hc.LoginUsingToken(x.GalaxyNamespace))

require.NoError(t, err, fmt.Sprintf("login through refresh httpToken failed: %v", err))
// verify that with an ACL rule defined, all the operations except query should
// does not have the required permissions be denied when the acsess JWT
testutil.VerifyCurlCmd(t, queryArgs(token.AccessJwt), &testutil.CurlFailureConfig{
testutil.VerifyCurlCmd(t, queryArgs(hc.AccessJwt), &testutil.CurlFailureConfig{
ShouldFail: false,
})
testutil.VerifyCurlCmd(t, mutateArgs(token.AccessJwt), &testutil.CurlFailureConfig{
testutil.VerifyCurlCmd(t, mutateArgs(hc.AccessJwt), &testutil.CurlFailureConfig{
ShouldFail: true,
DgraphErrMsg: "PermissionDenied",
})
testutil.VerifyCurlCmd(t, alterArgs(token.AccessJwt), &testutil.CurlFailureConfig{
testutil.VerifyCurlCmd(t, alterArgs(hc.AccessJwt), &testutil.CurlFailureConfig{
ShouldFail: true,
DgraphErrMsg: "PermissionDenied",
})

createGroupAndAcls(t, devGroup, true)
require.NoError(t, hcWithGroot.LoginIntoNamespace(dgraphtest.DefaultUser,
dgraphtest.DefaultPassword, x.GalaxyNamespace))
createGroupAndAcls(t, devGroup, true, hcWithGroot)
time.Sleep(defaultTimeToSleep)
// refresh the jwts again
token, err = testutil.HttpLogin(&testutil.LoginParams{
Endpoint: adminEndpoint,
RefreshJwt: token.RefreshToken,
})
require.NoError(t, hc.LoginUsingToken(x.GalaxyNamespace))

require.NoError(t, err, fmt.Sprintf("login through refresh httpToken failed: %v", err))
// verify that the operations should be allowed again through the dev group
testutil.VerifyCurlCmd(t, queryArgs(token.AccessJwt), &testutil.CurlFailureConfig{
testutil.VerifyCurlCmd(t, queryArgs(hc.AccessJwt), &testutil.CurlFailureConfig{
ShouldFail: false,
})
testutil.VerifyCurlCmd(t, mutateArgs(token.AccessJwt), &testutil.CurlFailureConfig{
testutil.VerifyCurlCmd(t, mutateArgs(hc.AccessJwt), &testutil.CurlFailureConfig{
ShouldFail: false,
})
testutil.VerifyCurlCmd(t, alterArgs(token.AccessJwt), &testutil.CurlFailureConfig{
testutil.VerifyCurlCmd(t, alterArgs(hc.AccessJwt), &testutil.CurlFailureConfig{
ShouldFail: false,
})
}
Loading

0 comments on commit ed7af9c

Please sign in to comment.