github.com/mwhudson/juju@v0.0.0-20160512215208-90ff01f3497f/apiserver/client_auth_root_test.go (about) 1 // Copyright 2015 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package apiserver 5 6 import ( 7 "reflect" 8 9 "github.com/juju/errors" 10 "github.com/juju/juju/apiserver/common" 11 "github.com/juju/juju/testing/factory" 12 13 jc "github.com/juju/testing/checkers" 14 gc "gopkg.in/check.v1" 15 16 "github.com/juju/juju/rpc/rpcreflect" 17 "github.com/juju/juju/state" 18 "github.com/juju/juju/state/testing" 19 ) 20 21 type clientAuthRootSuite struct { 22 testing.StateSuite 23 } 24 25 var _ = gc.Suite(&clientAuthRootSuite{}) 26 27 func (*clientAuthRootSuite) AssertCallGood(c *gc.C, client *clientAuthRoot, rootName string, version int, methodName string) { 28 caller, err := client.FindMethod(rootName, version, methodName) 29 c.Check(err, jc.ErrorIsNil) 30 c.Assert(caller, gc.NotNil) 31 } 32 33 func (*clientAuthRootSuite) AssertCallNotImplemented(c *gc.C, client *clientAuthRoot, rootName string, version int, methodName string) { 34 caller, err := client.FindMethod(rootName, version, methodName) 35 c.Check(errors.Cause(err), jc.Satisfies, isCallNotImplementedError) 36 c.Assert(caller, gc.IsNil) 37 } 38 39 func (s *clientAuthRootSuite) AssertCallErrPerm(c *gc.C, client *clientAuthRoot, rootName string, version int, methodName string) { 40 caller, err := client.FindMethod(rootName, version, methodName) 41 c.Check(errors.Cause(err), gc.Equals, common.ErrPerm) 42 c.Assert(caller, gc.IsNil) 43 } 44 45 func (s *clientAuthRootSuite) TestNormalUser(c *gc.C) { 46 envUser := s.Factory.MakeModelUser(c, nil) 47 client := newClientAuthRoot(&fakeFinder{}, envUser) 48 s.AssertCallGood(c, client, "Service", 3, "Deploy") 49 s.AssertCallGood(c, client, "UserManager", 1, "UserInfo") 50 s.AssertCallNotImplemented(c, client, "Client", 1, "Unknown") 51 s.AssertCallNotImplemented(c, client, "Unknown", 1, "Method") 52 } 53 54 func (s *clientAuthRootSuite) TestReadOnlyUser(c *gc.C) { 55 envUser := s.Factory.MakeModelUser(c, &factory.ModelUserParams{Access: state.ModelReadAccess}) 56 client := newClientAuthRoot(&fakeFinder{}, envUser) 57 // deploys are bad 58 s.AssertCallErrPerm(c, client, "Service", 3, "Deploy") 59 // read only commands are fine 60 s.AssertCallGood(c, client, "Client", 1, "FullStatus") 61 // calls on the restricted root is also fine 62 s.AssertCallGood(c, client, "UserManager", 1, "AddUser") 63 s.AssertCallNotImplemented(c, client, "Client", 1, "Unknown") 64 s.AssertCallNotImplemented(c, client, "Unknown", 1, "Method") 65 } 66 67 func isCallNotImplementedError(err error) bool { 68 _, ok := err.(*rpcreflect.CallNotImplementedError) 69 return ok 70 } 71 72 type fakeFinder struct{} 73 74 // FindMethod is the only thing we need to implement rpc.MethodFinder. 75 func (f *fakeFinder) FindMethod(rootName string, version int, methodName string) (rpcreflect.MethodCaller, error) { 76 _, _, err := lookupMethod(rootName, version, methodName) 77 if err != nil { 78 return nil, err 79 } 80 // Just return a valid caller. 81 return &fakeCaller{}, nil 82 } 83 84 // fakeCaller implements a rpcreflect.MethodCaller. We don't care what the 85 // actual reflect.Types or values actually are, the caller just has to be 86 // valid. 87 type fakeCaller struct{} 88 89 func (*fakeCaller) ParamsType() reflect.Type { 90 return reflect.TypeOf("") 91 } 92 93 func (*fakeCaller) ResultType() reflect.Type { 94 return reflect.TypeOf("") 95 } 96 97 func (*fakeCaller) Call(_ /*objId*/ string, _ /*arg*/ reflect.Value) (reflect.Value, error) { 98 return reflect.ValueOf(""), nil 99 }