github.com/kisexp/xdchain@v0.0.0-20211206025815-490d6b732aa7/multitenancy/authorization_test.go (about)

     1  package multitenancy
     2  
     3  import (
     4  	"net/url"
     5  	"os"
     6  	"testing"
     7  
     8  	"github.com/kisexp/xdchain/common"
     9  	"github.com/kisexp/xdchain/core/types"
    10  	"github.com/kisexp/xdchain/log"
    11  	"github.com/jpmorganchase/quorum-security-plugin-sdk-go/proto"
    12  	"github.com/stretchr/testify/assert"
    13  )
    14  
    15  func init() {
    16  	log.Root().SetHandler(log.StreamHandler(os.Stdout, log.TerminalFormat(false)))
    17  }
    18  
    19  type testCase struct {
    20  	msg          string
    21  	granted      []string
    22  	ask          *PrivateStateSecurityAttribute
    23  	isAuthorized bool
    24  }
    25  
    26  func TestMatch_whenTypical(t *testing.T) {
    27  	granted, _ := url.Parse("psi://arbitrary.psi1?node.eoa=0xaaa")
    28  	ask, _ := url.Parse("psi://arbitrary.psi1?node.eoa=0xaaa")
    29  
    30  	assert.True(t, match(ask, granted))
    31  }
    32  
    33  func TestMatch_whenNoEOA(t *testing.T) {
    34  	granted, _ := url.Parse("psi://arbitrary.psi1")
    35  	ask, _ := url.Parse("psi://arbitrary.psi1")
    36  
    37  	assert.False(t, match(ask, granted))
    38  }
    39  
    40  func TestMatch_whenAskWithNoEOA(t *testing.T) {
    41  	granted, _ := url.Parse("psi://arbitrary.psi1?node.eoa=0xaaa")
    42  	ask, _ := url.Parse("psi://arbitrary.psi1")
    43  
    44  	assert.False(t, match(ask, granted))
    45  }
    46  
    47  func TestMatch_whenGrantWithNoEOA(t *testing.T) {
    48  	granted, _ := url.Parse("psi://arbitrary.psi1")
    49  	ask, _ := url.Parse("psi://arbitrary.psi1?node.eoa=0xaaa")
    50  
    51  	assert.False(t, match(ask, granted))
    52  }
    53  
    54  func TestMatch_whenGrantWithDifferentEOA(t *testing.T) {
    55  	granted, _ := url.Parse("psi://arbitrary.psi1?node.eoa=0xaaa")
    56  	ask, _ := url.Parse("psi://arbitrary.psi1?self.eoa=0xaaa")
    57  
    58  	assert.False(t, match(ask, granted))
    59  }
    60  
    61  func TestMatch_whenAskMultipleEOA(t *testing.T) {
    62  	granted, _ := url.Parse("psi://arbitrary.psi1?node.eoa=0xaaa")
    63  	ask, _ := url.Parse("psi://arbitrary.psi1?node.eoa=0xaaa&node.eoa=0xbbb")
    64  
    65  	assert.False(t, match(ask, granted))
    66  }
    67  
    68  func TestMatch_whenGrantMultipleEOA(t *testing.T) {
    69  	granted, _ := url.Parse("psi://arbitrary.psi1?node.eoa=0x111&self.eoa=0xaaa&self.eoa=0xbbb&self.eoa=0xccc")
    70  	ask, _ := url.Parse("psi://arbitrary.psi1?self.eoa=0xaaa&self.eoa=0xbbb")
    71  
    72  	assert.True(t, match(ask, granted))
    73  }
    74  
    75  func TestMatch_whenGrantWithWildCardEOA(t *testing.T) {
    76  	granted, _ := url.Parse("psi://arbitrary.psi1?node.eoa=0x0")
    77  	ask, _ := url.Parse("psi://arbitrary.psi1?node.eoa=0xaaa&node.eoa=0xbbb")
    78  
    79  	assert.True(t, match(ask, granted))
    80  }
    81  
    82  func TestMatch_whenDiffScheme(t *testing.T) {
    83  	granted, _ := url.Parse("rpc://eth_sendTransaction")
    84  	ask, _ := url.Parse("psi://arbitrary.psi1?node.eoa=0xaaa&node.eoa=0xbbb")
    85  
    86  	assert.False(t, match(ask, granted))
    87  }
    88  
    89  func TestMatch_whenDiffPSI(t *testing.T) {
    90  	granted, _ := url.Parse("psi://arbitrary.psi1?node.eoa=0x0")
    91  	ask, _ := url.Parse("psi://arbitrary.psi2?node.eoa=0xaaa&node.eoa=0xbbb")
    92  
    93  	assert.False(t, match(ask, granted))
    94  }
    95  
    96  func TestMatch_whenDiffPSIAndNoEOA(t *testing.T) {
    97  	granted, _ := url.Parse("psi://arbitrary.psi1")
    98  	ask, _ := url.Parse("psi://arbitrary.psi2")
    99  
   100  	assert.False(t, match(ask, granted))
   101  }
   102  
   103  func TestAuthorizePSI(t *testing.T) {
   104  	testCases := []struct {
   105  		msg          string
   106  		granted      []string
   107  		ask          types.PrivateStateIdentifier
   108  		isAuthorized bool
   109  	}{
   110  		{
   111  			msg: "Granting PSI with no EOA",
   112  			granted: []string{
   113  				"psi://arbitrary.ps1",
   114  			},
   115  			ask:          "arbitrary.ps1",
   116  			isAuthorized: true,
   117  		},
   118  		{
   119  			msg: "Granting PSI with EOA",
   120  			granted: []string{
   121  				"psi://arbitrary.ps1?node.eoa=0x0",
   122  			},
   123  			ask:          "arbitrary.ps1",
   124  			isAuthorized: true,
   125  		},
   126  		{
   127  			msg: "Different scheme",
   128  			granted: []string{
   129  				"rpc://arbitrary.ps1",
   130  			},
   131  			ask:          "arbitrary.ps1",
   132  			isAuthorized: false,
   133  		},
   134  	}
   135  
   136  	for _, tc := range testCases {
   137  		log.Debug("Test case :: " + tc.msg)
   138  		actual, err := IsPSIAuthorized(toToken(tc.granted), tc.ask)
   139  		assert.NoError(t, err, tc.msg)
   140  		assert.Equal(t, tc.isAuthorized, actual, tc.msg)
   141  	}
   142  }
   143  
   144  func TestAuthorize(t *testing.T) {
   145  	testCases := []testCase{
   146  		{
   147  			msg: "Granting PSI with no EOA",
   148  			granted: []string{
   149  				"psi://arbitrary.ps1",
   150  			},
   151  			ask: (&PrivateStateSecurityAttribute{}).
   152  				WithPSI("arbitrary.ps1").
   153  				WithNodeEOA(common.HexToAddress("0x000000000000000000000000000000000000aaaa")),
   154  			isAuthorized: false,
   155  		},
   156  		{
   157  			msg: "Granted with default wild card EOA, inadequate ask",
   158  			granted: []string{
   159  				"psi://arbitrary.ps1",
   160  			},
   161  			ask: (&PrivateStateSecurityAttribute{}).
   162  				WithPSI("arbitrary.ps1"),
   163  			isAuthorized: false,
   164  		},
   165  		{
   166  			msg: "Node-managed: Granted with wild card EOA, ask for specific",
   167  			granted: []string{
   168  				"psi://arbitrary.ps1?node.eoa=0x0&self.eoa=0x000000000000000000000000000000000000aaaa",
   169  			},
   170  			ask: (&PrivateStateSecurityAttribute{}).
   171  				WithPSI("arbitrary.ps1").
   172  				WithNodeEOA(common.StringToAddress("0xc")),
   173  			isAuthorized: true,
   174  		},
   175  		{
   176  			msg: "Different EOA grant",
   177  			granted: []string{
   178  				"psi://arbitrary.ps1?self.eoa=0x000000000000000000000000000000000000aaaa",
   179  			},
   180  			ask: (&PrivateStateSecurityAttribute{}).
   181  				WithPSI("arbitrary.ps1").
   182  				WithNodeEOA(common.StringToAddress("0xc")),
   183  			isAuthorized: false,
   184  		},
   185  		{
   186  			msg: "Self-managed: Granted with wild card EOA, ask for specific",
   187  			granted: []string{
   188  				"psi://arbitrary.ps1?self.eoa=0x0",
   189  			},
   190  			ask: (&PrivateStateSecurityAttribute{}).
   191  				WithPSI("arbitrary.ps1").
   192  				WithSelfEOA(common.StringToAddress("0xc")),
   193  			isAuthorized: true,
   194  		},
   195  		{
   196  			msg: "Not granted to a PSI",
   197  			granted: []string{
   198  				"psi://arbitrary.ps2?node.eoa=0x0&self.eoa=0x0",
   199  			},
   200  			ask: (&PrivateStateSecurityAttribute{}).
   201  				WithPSI("arbitrary.ps1").WithNodeEOA(common.StringToAddress("arbitrary")),
   202  			isAuthorized: false,
   203  		},
   204  	}
   205  
   206  	for _, tc := range testCases {
   207  		log.Debug("Test case :: " + tc.msg)
   208  		actual, err := IsAuthorized(toToken(tc.granted), tc.ask)
   209  		assert.NoError(t, err, tc.msg)
   210  		assert.Equal(t, tc.isAuthorized, actual, tc.msg)
   211  	}
   212  }
   213  
   214  func toToken(granted []string) *proto.PreAuthenticatedAuthenticationToken {
   215  	values := make([]*proto.GrantedAuthority, len(granted))
   216  	for i, g := range granted {
   217  		values[i] = &proto.GrantedAuthority{
   218  			Raw: g,
   219  		}
   220  	}
   221  	return &proto.PreAuthenticatedAuthenticationToken{
   222  		Authorities: values,
   223  	}
   224  }
   225  
   226  func TestExtractPSI_whenTypical(t *testing.T) {
   227  	psi, err := ExtractPSI(toToken([]string{
   228  		"psi://arbitrary.psi1",
   229  		"psi://arbitrary.psi1?node.eoa=0x0",
   230  		"rpc://eth_call",
   231  	}))
   232  
   233  	assert.NoError(t, err)
   234  	assert.Equal(t, types.ToPrivateStateIdentifier("arbitrary.psi1"), psi)
   235  }
   236  
   237  func TestExtractPSI_whenNotFound(t *testing.T) {
   238  	_, err := ExtractPSI(toToken([]string{
   239  		"rpc://eth_call",
   240  	}))
   241  
   242  	assert.EqualError(t, err, ErrPSINotFound.Error())
   243  }
   244  
   245  func TestExtractPSI_whenFoundMultiple(t *testing.T) {
   246  	_, err := ExtractPSI(toToken([]string{
   247  		"psi://arbitrary.psi1",
   248  		"psi://arbitrary.psi2",
   249  		"psi://arbitrary.psi3",
   250  	}))
   251  
   252  	assert.EqualError(t, err, ErrPSIFoundMultiple.Error())
   253  }