Skip to content

Commit

Permalink
Add upgrade tests for ACL
Browse files Browse the repository at this point in the history
  • Loading branch information
shivaji-dgraph authored and mangalaman93 committed Jun 12, 2023
1 parent 6ed8b5c commit 1a1ac36
Show file tree
Hide file tree
Showing 11 changed files with 1,618 additions and 1,785 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 @@ -58,7 +58,7 @@ const (

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

var (
Expand Down
106 changes: 54 additions & 52 deletions ee/acl/acl_curl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,58 +4,64 @@
/*
* Copyright 2023 Dgraph Labs, Inc. and Contributors
*
* Licensed under the Dgraph Community License (the "License"); you
* may not use this file except in compliance with the License. You
* may obtain a copy of the License at
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://github.com/dgraph-io/dgraph/blob/main/licenses/DCL.txt
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

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 (suite *AclTestSuite) TestCurlAuthorization() {
t := suite.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 := suite.dc.Client()
require.NoError(t, err)
defer cleanup()
require.NoError(t, gc.LoginIntoNamespace(ctx, dgraphtest.DefaultUser,
dgraphtest.DefaultPassword, x.GalaxyNamespace))

hc, err := suite.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 +74,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 +83,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 +93,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 := suite.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 1a1ac36

Please sign in to comment.