From d01d6442505f6cb5edfc03fb05888c6068fc5752 Mon Sep 17 00:00:00 2001 From: Sasha Klizhentas Date: Mon, 17 Apr 2017 16:57:36 -0700 Subject: [PATCH] allow user to read their roles --- lib/auth/apiserver_test.go | 49 +++++++++++++++++++++++++++++++++++++ lib/auth/auth_with_roles.go | 12 ++++++++- 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/lib/auth/apiserver_test.go b/lib/auth/apiserver_test.go index 80576b6c45bd8..3d3a29c0ff6f0 100644 --- a/lib/auth/apiserver_test.go +++ b/lib/auth/apiserver_test.go @@ -142,6 +142,55 @@ func createUserAndRole(clt clt, username string, allowedLogins []string) (servic return user, role } +func createUserAndRoleWithoutRoles(clt clt, username string, allowedLogins []string) (services.User, services.Role) { + user, err := services.NewUser(username) + if err != nil { + panic(err) + } + role := services.RoleForUser(user) + role.RemoveResource(services.KindRole) + role.SetLogins([]string{user.GetName()}) + err = clt.UpsertRole(role, backend.Forever) + if err != nil { + panic(err) + } + user.AddRole(role.GetName()) + err = clt.UpsertUser(user) + if err != nil { + panic(err) + } + return user, role +} + +// TestOwnRole tests that user can read roles assigned to them +func (s *APISuite) TestReadOwnRole(c *C) { + + user1, userRole := createUserAndRoleWithoutRoles(s.clt, "user1", []string{"user1"}) + user2, _ := createUserAndRoleWithoutRoles(s.clt, "user2", []string{"user2"}) + err := s.clt.UpsertPassword(user1.GetName(), []byte("abc1231")) + c.Assert(err, IsNil) + err = s.clt.UpsertPassword(user2.GetName(), []byte("abc1232")) + c.Assert(err, IsNil) + + // user should be able to read their own roles + authorizer, err := NewUserAuthorizer("user1", s.WebS, s.AccessS) + c.Assert(err, IsNil) + authServer, userClient := s.newServerWithAuthorizer(c, authorizer) + defer authServer.Close() + + _, err = userClient.GetRole(userRole.GetName()) + c.Assert(err, IsNil) + + // user2 can't read user1 role + authorizer, err = NewUserAuthorizer("user2", s.WebS, s.AccessS) + c.Assert(err, IsNil) + authServer2, userClient2 := s.newServerWithAuthorizer(c, authorizer) + defer authServer2.Close() + + _, err = userClient2.GetRole(userRole.GetName()) + c.Assert(err, NotNil) +} + func (s *APISuite) TestGenerateKeysAndCerts(c *C) { priv, pub, err := s.clt.GenerateKeyPair("") c.Assert(err, IsNil) diff --git a/lib/auth/auth_with_roles.go b/lib/auth/auth_with_roles.go index d076d3ac7a710..1f40ad287a3c1 100644 --- a/lib/auth/auth_with_roles.go +++ b/lib/auth/auth_with_roles.go @@ -26,7 +26,9 @@ import ( "github.com/gravitational/teleport/lib/events" "github.com/gravitational/teleport/lib/services" "github.com/gravitational/teleport/lib/session" + "github.com/gravitational/teleport/lib/utils" + log "github.com/Sirupsen/logrus" "github.com/gravitational/trace" "github.com/tstranex/u2f" ) @@ -582,7 +584,15 @@ func (a *AuthWithRoles) UpsertRole(role services.Role, ttl time.Duration) error // GetRole returns role by name func (a *AuthWithRoles) GetRole(name string) (services.Role, error) { if err := a.action(defaults.Namespace, services.KindRole, services.ActionRead); err != nil { - return nil, trace.Wrap(err) + // allow user to read roles assigned to them + user, err := a.authServer.Identity.GetUser(a.user) + if err != nil { + return nil, trace.Wrap(err) + } + log.Infof("%v %v %v", user, user.GetRoles(), name) + if !utils.SliceContainsStr(user.GetRoles(), name) { + return nil, trace.Wrap(err) + } } return a.authServer.GetRole(name) }