示例#1
0
// Authorise tests auth
func (a *simpleAuthoriser) Authorise(req *Request) errors.Error {

	// If we require neither a role or a user, then there is no need to authorise
	if !a.requireUser && !a.requireRole {
		log.Debugf("Skipping auth from %s to %s, as neither user or role required", req.From(), req.Destination())
		return nil
	}

	// Otherwise, authorise this request
	scope := req.Auth()
	log.Tracef("Scope user: %v", scope.AuthUser())
	if a.requireUser && !scope.IsAuth() {
		return errors.Forbidden("com.hailocab.kernel.auth.notsignedin", fmt.Sprintf("Must be signed in to call this endpoint[endpoint=%s, service=%s, from=%s]",
			req.Endpoint(), req.Service(), req.From()), "201")
	}
	if a.requireRole {
		matchesRole := false
		for _, r := range a.roles {
			if scope.HasAccess(r) {
				matchesRole = true
				break
			}
		}
		if !matchesRole {
			if scope.HasTriedAuth() {
				return errors.Forbidden("com.hailocab.kernel.auth.badrole", fmt.Sprintf("Must be signed in to call this endpoint[endpoint=%s, service=%s, from=%s]",
					req.Endpoint(), req.Service(), req.From()), "201")
			}
			// Instrument when service to service auth fails
			inst.Counter(1.0, "auth.servicetoservice.failed", 1)
			return BadRoleError(req)
		}
	}
	return nil
}
示例#2
0
func TestErrorCaller(t *testing.T) {
	err := errors.Forbidden("foo.bar.baz", "Oh noes!")
	caller := ErrorCaller(err)

	e := caller(nil, nil)
	if e == nil {
		t.Fatalf("ErrorCaller should have returned the error we gave it")
	}
	if e.Code() != "foo.bar.baz" {
		t.Errorf("Error code should be foo.bar.baz")
	}
}
示例#3
0
// TestAuthHappyCaseValid tests when things work, and when the credentials are bad
func (suite *sessionRecoverySuite) TestAuthHappyCaseInvalid() {
	t := suite.T()

	scope := New().(*realScope)
	scope.userCache = newTestCache()

	mock := multiclient.NewMock()
	stub := &multiclient.Stub{
		Service:  loginService,
		Endpoint: authEndpoint,
		Error:    errors.Forbidden("com.hailocab.service.login.auth.badCredentials", "Bad credentials"),
	}
	mock.Stub(stub)
	multiclient.SetCaller(mock.Caller())

	testMech, testDeviceType := "h2", "cli"
	testUsername, testPassword := "******", "Securez1"
	testCreds := map[string]string{
		"username": testUsername,
		"password": testPassword,
	}

	err := scope.Auth(testMech, testDeviceType, testCreds)
	if err == nil {
		t.Fatal("Expecting auth error")
	}
	if err != BadCredentialsError {
		t.Errorf("Expecting auth error to be BadCredentialsError; got %v", err)
	}
	if scope.IsAuth() {
		t.Error("Expecting scope to be IsAuth==false after bad credentials auth")
	}
	if !scope.HasTriedAuth() {
		t.Error("Expecting scope to have HasTriedAuth()==true after bad credentials auth")
	}
	if u := scope.AuthUser(); u != nil {
		t.Error("Expecting AuthUser()==nil after bad credentials auth")
	}

	// verify we made correct request(s)
	if stub.CountCalls() != 1 {
		t.Fatalf("Expecting 1 call to auth; got %v", stub.CountCalls())
	}
}
示例#4
0
func (suite *multiClientSuite) TestSetCallerAndReset() {
	cl := &defClient{
		requests:  make(map[string]*client.Request),
		responses: make(map[string]proto.Message),
		errors:    &errorsImpl{},
	}

	c := ErrorCaller(errors.Forbidden("bad.person", "Much forbid"))

	cl.SetCaller(c)
	suite.Assertions.NotNil(cl.caller, "Set caller did not update caller :(")

	// do a call!
	cl.AddScopedReq(&ScopedReq{
		Service:  "com.hailocab.service.foo",
		Endpoint: "health",
		Req:      &hcproto.Request{},
		Rsp:      &hcproto.Response{},
	})
	cl.Execute()

	err := cl.Succeeded("")
	suite.Assertions.NotNil(err, "Error caller we set did not result in error!")
	suite.Assertions.Equal("bad.person", err.Code())

	// now we should be able to RESET this, and use the _same_ caller again
	suite.Assertions.True(cl.AnyErrors(), "Expecting us to HAVE errors, before we reset")
	suite.Assertions.False(cl.Reset().AnyErrors(), "Expecting us NOT to have errors, after we reset")

	// make same call -- crucial point is that the SetCaller thing shouldn't be reset
	cl.AddScopedReq(&ScopedReq{
		Service:  "com.hailocab.service.foo",
		Endpoint: "health",
		Req:      &hcproto.Request{},
		Rsp:      &hcproto.Response{},
	})
	cl.Execute()

	err = cl.Succeeded("")
	suite.Assertions.NotNil(err, "Error caller we set did not result in error!")
	suite.Assertions.Equal("bad.person", err.Code())
}
示例#5
0
func (suite *multiClientSuite) TestSucceeded() {
	cl := &defClient{
		requests:  make(map[string]*client.Request),
		responses: make(map[string]proto.Message),
		errors:    &errorsImpl{},
	}
	cl.SetCaller(ErrorCaller(errors.Forbidden("bad.person", "Much forbid")))

	// A single request should not add any context to the code
	cl.DefaultScopeFrom(ExplicitScoper().SetContext("prefixy"))
	cl.AddScopedReq(&ScopedReq{
		Service:  "com.hailocab.service.foo",
		Endpoint: "health",
		Req:      &hcproto.Request{},
		Rsp:      &hcproto.Response{},
	})
	cl.Execute()
	err := cl.Succeeded("")
	suite.Assertions.NotNil(err)
	suite.Assertions.True(errors.IsForbidden(err))
	suite.Assertions.Equal("bad.person", err.Code())
	suite.Assertions.Equal("Much forbid", err.Description())
}
示例#6
0
func (suite *multiClientSuite) TestPlatformError() {
	cl := &defClient{
		requests:  make(map[string]*client.Request),
		responses: make(map[string]proto.Message),
		errors:    &errorsImpl{},
	}
	cl.SetCaller(ErrorCaller(errors.Forbidden("bad.person", "Much forbid")))

	// A single request should not add the suffix provided to PlatformError() but return it verbatim
	cl.AddScopedReq(&ScopedReq{
		Service:  "com.hailocab.service.foo",
		Endpoint: "health",
		Req:      &hcproto.Request{},
		Rsp:      &hcproto.Response{},
	})
	cl.Execute()
	err := cl.PlatformError("suffixy")
	suite.Assertions.NotNil(err)
	suite.Assertions.True(errors.IsForbidden(err))
	suite.Assertions.Equal("bad.person", err.Code())
	suite.Assertions.Equal("Much forbid", err.Description())

	// Multiple errors should use the suffix provided
	cl.Reset()
	cl.AddScopedReq(&ScopedReq{
		Uid:      "uid1",
		Service:  "com.hailocab.service.foo",
		Endpoint: "health",
		Req:      &hcproto.Request{},
		Rsp:      &hcproto.Response{},
	})
	cl.AddScopedReq(&ScopedReq{
		Uid:      "uid2",
		Service:  "com.hailocab.service.foo",
		Endpoint: "bar",
		Req:      &hcproto.Request{},
		Rsp:      &hcproto.Response{},
	})
	cl.Execute()
	err = cl.PlatformError("suffixy")
	suite.Assertions.NotNil(err)
	suite.Assertions.True(errors.IsInternalServerError(err))
	suite.Assertions.Equal("suffixy", err.Code())

	// Multiple errors with a defaultScopeFrom should join the two
	cl.Reset()
	cl.DefaultScopeFrom(ExplicitScoper().SetContext("prefixy"))
	cl.AddScopedReq(&ScopedReq{
		Uid:      "uid1",
		Service:  "com.hailocab.service.foo",
		Endpoint: "health",
		Req:      &hcproto.Request{},
		Rsp:      &hcproto.Response{},
	})
	cl.AddScopedReq(&ScopedReq{
		Uid:      "uid2",
		Service:  "com.hailocab.service.foo",
		Endpoint: "bar",
		Req:      &hcproto.Request{},
		Rsp:      &hcproto.Response{},
	})
	cl.Execute()
	err = cl.PlatformError("suffixy")
	suite.Assertions.NotNil(err)
	suite.Assertions.True(errors.IsInternalServerError(err))
	suite.Assertions.Equal("prefixy.suffixy", err.Code())
}
示例#7
0
// Given a request, returns a "bad role" error. This is used both by Authorise() and is useful within services which do
// row-level permission checking.
func BadRoleError(req *Request) errors.Error {
	return errors.Forbidden("com.hailocab.kernel.auth.badrole", fmt.Sprintf("Must have the correct role to call this "+
		"endpoint [endpoint=%s, service=%s, from=%s]", req.Endpoint(), req.Service(), req.From()), "5")
}