github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/apiserver/common/permissions_test.go (about)

     1  // Copyright 2016 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package common_test
     5  
     6  import (
     7  	"github.com/juju/errors"
     8  	jc "github.com/juju/testing/checkers"
     9  	gc "gopkg.in/check.v1"
    10  	"gopkg.in/juju/names.v2"
    11  
    12  	"github.com/juju/juju/apiserver/common"
    13  	"github.com/juju/juju/permission"
    14  	"github.com/juju/juju/testing"
    15  )
    16  
    17  type PermissionSuite struct {
    18  	testing.BaseSuite
    19  }
    20  
    21  var _ = gc.Suite(&PermissionSuite{})
    22  
    23  type fakeUserAccess struct {
    24  	subjects []names.UserTag
    25  	objects  []names.Tag
    26  	access   permission.Access
    27  	err      error
    28  }
    29  
    30  func (f *fakeUserAccess) call(subject names.UserTag, object names.Tag) (permission.Access, error) {
    31  	f.subjects = append(f.subjects, subject)
    32  	f.objects = append(f.objects, object)
    33  	return f.access, f.err
    34  }
    35  
    36  func (r *PermissionSuite) TestNoUserTagLacksPermission(c *gc.C) {
    37  	nonUser := names.NewModelTag("beef1beef1-0000-0000-000011112222")
    38  	target := names.NewModelTag("beef1beef2-0000-0000-000011112222")
    39  	hasPermission, err := common.HasPermission((&fakeUserAccess{}).call, nonUser, permission.ReadAccess, target)
    40  	c.Assert(hasPermission, jc.IsFalse)
    41  	c.Assert(err, jc.ErrorIsNil)
    42  }
    43  
    44  func (r *PermissionSuite) TestHasPermission(c *gc.C) {
    45  	testCases := []struct {
    46  		title            string
    47  		userGetterAccess permission.Access
    48  		user             names.UserTag
    49  		target           names.Tag
    50  		access           permission.Access
    51  		expected         bool
    52  	}{
    53  		{
    54  			title:            "user has lesser permissions than required",
    55  			userGetterAccess: permission.ReadAccess,
    56  			user:             names.NewUserTag("validuser"),
    57  			target:           names.NewModelTag("beef1beef2-0000-0000-000011112222"),
    58  			access:           permission.WriteAccess,
    59  			expected:         false,
    60  		},
    61  		{
    62  			title:            "user has equal permission than required",
    63  			userGetterAccess: permission.WriteAccess,
    64  			user:             names.NewUserTag("validuser"),
    65  			target:           names.NewModelTag("beef1beef2-0000-0000-000011112222"),
    66  			access:           permission.WriteAccess,
    67  			expected:         true,
    68  		},
    69  		{
    70  			title:            "user has greater permission than required",
    71  			userGetterAccess: permission.AdminAccess,
    72  			user:             names.NewUserTag("validuser"),
    73  			target:           names.NewModelTag("beef1beef2-0000-0000-000011112222"),
    74  			access:           permission.WriteAccess,
    75  			expected:         true,
    76  		},
    77  		{
    78  			title:            "user requests model permission on controller",
    79  			userGetterAccess: permission.AdminAccess,
    80  			user:             names.NewUserTag("validuser"),
    81  			target:           names.NewModelTag("beef1beef2-0000-0000-000011112222"),
    82  			access:           permission.AddModelAccess,
    83  			expected:         false,
    84  		},
    85  		{
    86  			title:            "user requests controller permission on model",
    87  			userGetterAccess: permission.AdminAccess,
    88  			user:             names.NewUserTag("validuser"),
    89  			target:           names.NewControllerTag("beef1beef2-0000-0000-000011112222"),
    90  			access:           permission.AdminAccess, // notice user has this permission for model.
    91  			expected:         false,
    92  		},
    93  		{
    94  			title:            "controller permissions also work",
    95  			userGetterAccess: permission.SuperuserAccess,
    96  			user:             names.NewUserTag("validuser"),
    97  			target:           names.NewControllerTag("beef1beef2-0000-0000-000011112222"),
    98  			access:           permission.SuperuserAccess,
    99  			expected:         true,
   100  		},
   101  		{
   102  			title:            "cloud permissions work",
   103  			userGetterAccess: permission.AddModelAccess,
   104  			user:             names.NewUserTag("validuser"),
   105  			target:           names.NewCloudTag("mycloud"),
   106  			access:           permission.AddModelAccess,
   107  			expected:         true,
   108  		},
   109  		{
   110  			title:            "user has lesser cloud permissions than required",
   111  			userGetterAccess: permission.NoAccess,
   112  			user:             names.NewUserTag("validuser"),
   113  			target:           names.NewCloudTag("mycloud"),
   114  			access:           permission.AddModelAccess,
   115  			expected:         false,
   116  		},
   117  		{
   118  			title:            "user has lesser offer permissions than required",
   119  			userGetterAccess: permission.ReadAccess,
   120  			user:             names.NewUserTag("validuser"),
   121  			target:           names.NewApplicationOfferTag("hosted-mysql"),
   122  			access:           permission.WriteAccess,
   123  			expected:         false,
   124  		},
   125  		{
   126  			title:            "user has equal offer permission than required",
   127  			userGetterAccess: permission.ConsumeAccess,
   128  			user:             names.NewUserTag("validuser"),
   129  			target:           names.NewApplicationOfferTag("hosted-mysql"),
   130  			access:           permission.ConsumeAccess,
   131  			expected:         true,
   132  		},
   133  		{
   134  			title:            "user has greater offer permission than required",
   135  			userGetterAccess: permission.AdminAccess,
   136  			user:             names.NewUserTag("validuser"),
   137  			target:           names.NewApplicationOfferTag("hosted-mysql"),
   138  			access:           permission.ConsumeAccess,
   139  			expected:         true,
   140  		},
   141  		{
   142  			title:            "user requests controller permission on offer",
   143  			userGetterAccess: permission.ReadAccess,
   144  			user:             names.NewUserTag("validuser"),
   145  			target:           names.NewApplicationOfferTag("hosted-mysql"),
   146  			access:           permission.AddModelAccess,
   147  			expected:         false,
   148  		},
   149  	}
   150  	for i, t := range testCases {
   151  		userGetter := &fakeUserAccess{
   152  			access: t.userGetterAccess,
   153  		}
   154  		c.Logf("HasPermission test n %d: %s", i, t.title)
   155  		hasPermission, err := common.HasPermission(userGetter.call, t.user, t.access, t.target)
   156  		c.Assert(hasPermission, gc.Equals, t.expected)
   157  		c.Assert(err, jc.ErrorIsNil)
   158  	}
   159  
   160  }
   161  
   162  func (r *PermissionSuite) TestUserGetterErrorReturns(c *gc.C) {
   163  	user := names.NewUserTag("validuser")
   164  	target := names.NewModelTag("beef1beef2-0000-0000-000011112222")
   165  	userGetter := &fakeUserAccess{
   166  		access: permission.NoAccess,
   167  		err:    errors.NotFoundf("a user"),
   168  	}
   169  	hasPermission, err := common.HasPermission(userGetter.call, user, permission.ReadAccess, target)
   170  	c.Assert(err, jc.ErrorIsNil)
   171  	c.Assert(hasPermission, jc.IsFalse)
   172  	c.Assert(userGetter.subjects, gc.HasLen, 1)
   173  	c.Assert(userGetter.subjects[0], gc.DeepEquals, user)
   174  	c.Assert(userGetter.objects, gc.HasLen, 1)
   175  	c.Assert(userGetter.objects[0], gc.DeepEquals, target)
   176  }
   177  
   178  type fakeEveryoneUserAccess struct {
   179  	user     permission.Access
   180  	everyone permission.Access
   181  }
   182  
   183  func (f *fakeEveryoneUserAccess) call(subject names.UserTag, object names.Tag) (permission.Access, error) {
   184  	if subject.Id() == common.EveryoneTagName {
   185  		return f.everyone, nil
   186  	}
   187  	return f.user, nil
   188  }
   189  
   190  func (r *PermissionSuite) TestEveryoneAtExternal(c *gc.C) {
   191  	testCases := []struct {
   192  		title            string
   193  		userGetterAccess permission.Access
   194  		everyoneAccess   permission.Access
   195  		user             names.UserTag
   196  		target           names.Tag
   197  		access           permission.Access
   198  		expected         bool
   199  	}{
   200  		{
   201  			title:            "user has lesser permissions than everyone",
   202  			userGetterAccess: permission.LoginAccess,
   203  			everyoneAccess:   permission.SuperuserAccess,
   204  			user:             names.NewUserTag("validuser@external"),
   205  			target:           names.NewControllerTag("beef1beef2-0000-0000-000011112222"),
   206  			access:           permission.SuperuserAccess,
   207  			expected:         true,
   208  		},
   209  		{
   210  			title:            "user has greater permissions than everyone",
   211  			userGetterAccess: permission.SuperuserAccess,
   212  			everyoneAccess:   permission.LoginAccess,
   213  			user:             names.NewUserTag("validuser@external"),
   214  			target:           names.NewControllerTag("beef1beef2-0000-0000-000011112222"),
   215  			access:           permission.SuperuserAccess,
   216  			expected:         true,
   217  		},
   218  		{
   219  			title:            "everibody not considered if user is local",
   220  			userGetterAccess: permission.LoginAccess,
   221  			everyoneAccess:   permission.SuperuserAccess,
   222  			user:             names.NewUserTag("validuser"),
   223  			target:           names.NewControllerTag("beef1beef2-0000-0000-000011112222"),
   224  			access:           permission.SuperuserAccess,
   225  			expected:         false,
   226  		},
   227  	}
   228  
   229  	for i, t := range testCases {
   230  		userGetter := &fakeEveryoneUserAccess{
   231  			user:     t.userGetterAccess,
   232  			everyone: t.everyoneAccess,
   233  		}
   234  		c.Logf(`HasPermission "everyone" test n %d: %s`, i, t.title)
   235  		hasPermission, err := common.HasPermission(userGetter.call, t.user, t.access, t.target)
   236  		c.Assert(err, jc.ErrorIsNil)
   237  		c.Assert(hasPermission, gc.Equals, t.expected)
   238  	}
   239  }