github.com/unigraph-dev/dgraph@v1.1.1-0.20200923154953-8b52b426f765/ee/acl/acl_curl_test.go (about)

     1  // +build !oss
     2  
     3  /*
     4   * Copyright 2018 Dgraph Labs, Inc. and Contributors
     5   *
     6   * Licensed under the Dgraph Community License (the "License"); you
     7   * may not use this file except in compliance with the License. You
     8   * may obtain a copy of the License at
     9   *
    10   *     https://github.com/dgraph-io/dgraph/blob/master/licenses/DCL.txt
    11   */
    12  
    13  package acl
    14  
    15  import (
    16  	"fmt"
    17  	"testing"
    18  	"time"
    19  
    20  	"github.com/dgraph-io/dgraph/testutil"
    21  	"github.com/golang/glog"
    22  	"github.com/stretchr/testify/require"
    23  )
    24  
    25  var loginEndpoint = "http://" + testutil.SockAddrHttp + "/login"
    26  
    27  func TestCurlAuthorization(t *testing.T) {
    28  	if testing.Short() {
    29  		t.Skip("skipping because -short=true")
    30  	}
    31  
    32  	glog.Infof("testing with port %s", testutil.SockAddr)
    33  	dg := testutil.DgraphClientWithGroot(testutil.SockAddr)
    34  	createAccountAndData(t, dg)
    35  
    36  	// test query through curl
    37  	accessJwt, refreshJwt, err := testutil.HttpLogin(&testutil.LoginParams{
    38  		Endpoint: loginEndpoint,
    39  		UserID:   userid,
    40  		Passwd:   userpassword,
    41  	})
    42  	require.NoError(t, err, "login failed")
    43  
    44  	// test fail open with the accessJwt
    45  	queryArgs := func(jwt string) []string {
    46  		return []string{"-H", fmt.Sprintf("X-Dgraph-AccessToken:%s", jwt),
    47  			"-H", "Content-Type: application/graphql+-",
    48  			"-d", query, curlQueryEndpoint}
    49  	}
    50  	testutil.VerifyCurlCmd(t, queryArgs(accessJwt), &testutil.CurlFailureConfig{
    51  		ShouldFail: false,
    52  	})
    53  
    54  	mutateArgs := func(jwt string) []string {
    55  		return []string{"-H", fmt.Sprintf("X-Dgraph-AccessToken:%s", jwt),
    56  			"-H", "Content-Type: application/rdf",
    57  			"-d", fmt.Sprintf(`{ set {
    58  	   _:a <%s>  "string" .
    59  	   }}`, predicateToWrite), curlMutateEndpoint}
    60  
    61  	}
    62  
    63  	testutil.VerifyCurlCmd(t, mutateArgs(accessJwt), &testutil.CurlFailureConfig{
    64  		ShouldFail: false,
    65  	})
    66  
    67  	alterArgs := func(jwt string) []string {
    68  		return []string{"-H", fmt.Sprintf("X-Dgraph-AccessToken:%s", jwt),
    69  			"-d", fmt.Sprintf(`%s: int .`, predicateToAlter), curlAlterEndpoint}
    70  	}
    71  	testutil.VerifyCurlCmd(t, alterArgs(accessJwt), &testutil.CurlFailureConfig{
    72  		ShouldFail: false,
    73  	})
    74  
    75  	// sleep long enough (longer than 10s, the access JWT TTL defined in the docker-compose.yml
    76  	// in this directory) for the accessJwt to expire, in order to test auto login through refresh
    77  	// JWT
    78  	glog.Infof("Sleeping for 4 seconds for accessJwt to expire")
    79  	time.Sleep(4 * time.Second)
    80  	testutil.VerifyCurlCmd(t, queryArgs(accessJwt), &testutil.CurlFailureConfig{
    81  		ShouldFail:   true,
    82  		DgraphErrMsg: "Token is expired",
    83  	})
    84  	testutil.VerifyCurlCmd(t, mutateArgs(accessJwt), &testutil.CurlFailureConfig{
    85  		ShouldFail:   true,
    86  		DgraphErrMsg: "Token is expired",
    87  	})
    88  	testutil.VerifyCurlCmd(t, alterArgs(accessJwt), &testutil.CurlFailureConfig{
    89  		ShouldFail:   true,
    90  		DgraphErrMsg: "Token is expired",
    91  	})
    92  	// login again using the refreshJwt
    93  	accessJwt, refreshJwt, err = testutil.HttpLogin(&testutil.LoginParams{
    94  		Endpoint:   loginEndpoint,
    95  		RefreshJwt: refreshJwt,
    96  	})
    97  	require.NoError(t, err, fmt.Sprintf("login through refresh token failed: %v", err))
    98  	// verify that the query works again with the new access jwt
    99  	testutil.VerifyCurlCmd(t, queryArgs(accessJwt), &testutil.CurlFailureConfig{
   100  		ShouldFail: false,
   101  	})
   102  
   103  	createGroupAndAcls(t, unusedGroup, false)
   104  	// wait for 6 seconds to ensure the new acl have reached all acl caches
   105  	glog.Infof("Sleeping for 6 seconds for acl caches to be refreshed")
   106  	time.Sleep(6 * time.Second)
   107  	testutil.VerifyCurlCmd(t, queryArgs(accessJwt), &testutil.CurlFailureConfig{
   108  		ShouldFail:   true,
   109  		DgraphErrMsg: "Token is expired",
   110  	})
   111  	// refresh the jwts again
   112  	accessJwt, refreshJwt, err = testutil.HttpLogin(&testutil.LoginParams{
   113  		Endpoint:   loginEndpoint,
   114  		RefreshJwt: refreshJwt,
   115  	})
   116  	require.NoError(t, err, fmt.Sprintf("login through refresh token failed: %v", err))
   117  	// verify that with an ACL rule defined, all the operations should be denied when the acsess JWT
   118  	// does not have the required permissions
   119  	testutil.VerifyCurlCmd(t, queryArgs(accessJwt), &testutil.CurlFailureConfig{
   120  		ShouldFail:   true,
   121  		DgraphErrMsg: "PermissionDenied",
   122  	})
   123  	testutil.VerifyCurlCmd(t, mutateArgs(accessJwt), &testutil.CurlFailureConfig{
   124  		ShouldFail:   true,
   125  		DgraphErrMsg: "PermissionDenied",
   126  	})
   127  	testutil.VerifyCurlCmd(t, alterArgs(accessJwt), &testutil.CurlFailureConfig{
   128  		ShouldFail:   true,
   129  		DgraphErrMsg: "PermissionDenied",
   130  	})
   131  
   132  	createGroupAndAcls(t, devGroup, true)
   133  	glog.Infof("Sleeping for 6 seconds for acl caches to be refreshed")
   134  	time.Sleep(6 * time.Second)
   135  	// refresh the jwts again
   136  	accessJwt, _, err = testutil.HttpLogin(&testutil.LoginParams{
   137  		Endpoint:   loginEndpoint,
   138  		RefreshJwt: refreshJwt,
   139  	})
   140  	require.NoError(t, err, fmt.Sprintf("login through refresh token failed: %v", err))
   141  	// verify that the operations should be allowed again through the dev group
   142  	testutil.VerifyCurlCmd(t, queryArgs(accessJwt), &testutil.CurlFailureConfig{
   143  		ShouldFail: false,
   144  	})
   145  	testutil.VerifyCurlCmd(t, mutateArgs(accessJwt), &testutil.CurlFailureConfig{
   146  		ShouldFail: false,
   147  	})
   148  	testutil.VerifyCurlCmd(t, alterArgs(accessJwt), &testutil.CurlFailureConfig{
   149  		ShouldFail: false,
   150  	})
   151  }
   152  
   153  const (
   154  	curlLoginEndpoint  = "localhost:8180/login"
   155  	curlQueryEndpoint  = "localhost:8180/query"
   156  	curlMutateEndpoint = "localhost:8180/mutate"
   157  	curlAlterEndpoint  = "localhost:8180/alter"
   158  )