Skip to content

Commit

Permalink
move server implementation to a subpackage
Browse files Browse the repository at this point in the history
  • Loading branch information
espadolini committed Jan 16, 2025
1 parent d0943ca commit 2553ef3
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 32 deletions.
19 changes: 16 additions & 3 deletions lib/auth/grpcserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ import (
"github.com/gravitational/teleport/lib/auth/machineid/workloadidentityv1"
"github.com/gravitational/teleport/lib/auth/notifications/notificationsv1"
"github.com/gravitational/teleport/lib/auth/presence/presencev1"
"github.com/gravitational/teleport/lib/auth/stableunixusers"
"github.com/gravitational/teleport/lib/auth/trust/trustv1"
"github.com/gravitational/teleport/lib/auth/userloginstate/userloginstatev1"
"github.com/gravitational/teleport/lib/auth/userpreferences/userpreferencesv1"
Expand Down Expand Up @@ -5281,13 +5282,24 @@ func NewGRPCServer(cfg GRPCServerConfig) (*GRPCServer, error) {
}
dbobjectv1pb.RegisterDatabaseObjectServiceServer(server, dbObjectService)

stableUNIXUsersServiceServerInstance, err := newStableUNIXUsersServiceServer(cfg.Authorizer, cfg.AuthServer)
stableUNIXUsersServiceServer, err := stableunixusers.New(stableunixusers.Params{
Authorizer: cfg.Authorizer,

Backend: cfg.AuthServer.bk,
ReadOnlyCache: cfg.AuthServer.ReadOnlyCache,

StableUNIXUsers: cfg.AuthServer.Services.StableUNIXUsersInternal,
ClusterConfiguration: cfg.AuthServer.Services.ClusterConfiguration,

CacheClock: cfg.AuthServer.clock,
CacheContext: cfg.AuthServer.closeCtx,
})
if err != nil {
return nil, trace.Wrap(err, "creating stable UNIX user service")
}
stableunixusersv1.RegisterStableUNIXUsersServiceServer(
server,
stableUNIXUsersServiceServerInstance,
stableUNIXUsersServiceServer,
)

authServer := &GRPCServer{
Expand Down Expand Up @@ -5520,7 +5532,8 @@ func NewGRPCServer(cfg GRPCServerConfig) (*GRPCServer, error) {
autoupdatev1pb.RegisterAutoUpdateServiceServer(server, autoUpdateServiceServer)

identityCenterService, err := local.NewIdentityCenterService(local.IdentityCenterServiceConfig{
Backend: cfg.AuthServer.bk})
Backend: cfg.AuthServer.bk,
})
if err != nil {
return nil, trace.Wrap(err)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,14 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

package auth
package stableunixusers

import (
"context"
"time"

"github.com/gravitational/trace"
"github.com/jonboulle/clockwork"
"google.golang.org/protobuf/proto"

stableunixusersv1 "github.com/gravitational/teleport/api/gen/proto/go/teleport/stableunixusers/v1"
Expand All @@ -32,38 +33,56 @@ import (
"github.com/gravitational/teleport/lib/utils"
)

// newStableUNIXUsersServiceServer returns a [stableUNIXUsersServiceServer]
// using the given authorizer and server.
func newStableUNIXUsersServiceServer(authorizer authz.Authorizer, server *Server) (*stableUNIXUsersServiceServer, error) {
const uidCacheTTL = 30 * time.Second

// Params contains the parameters for [New].
type Params struct {
Authorizer authz.Authorizer

Backend backend.Backend
ReadOnlyCache *readonly.Cache

StableUNIXUsers services.StableUNIXUsersInternal
ClusterConfiguration services.ClusterConfigurationInternal

// CacheClock, if set, is used by the internal time-based UID cache.
CacheClock clockwork.Clock
// CacheContext, if set, is used as the context for the operations spawned
// by the internal time-based UID cache.
CacheContext context.Context
}

// New returns the auth server implementation for the stable UNIX users service,
// including the gRPC interface, authz enforcement, and business logic.
func New(params Params) (stableunixusersv1.StableUNIXUsersServiceServer, error) {
uidCache, err := utils.NewFnCache(utils.FnCacheConfig{
TTL: 30 * time.Second,
Clock: server.clock,
Context: server.closeCtx,
TTL: uidCacheTTL,
Clock: params.CacheClock,
Context: params.CacheContext,
ReloadOnErr: true,
})
if err != nil {
return nil, trace.Wrap(err)
}

return &stableUNIXUsersServiceServer{
authorizer: authorizer,
return &server{
authorizer: params.Authorizer,

backend: server.bk,
readOnlyCache: server.ReadOnlyCache,
backend: params.Backend,
readOnlyCache: params.ReadOnlyCache,

stableUNIXUsers: server.Services.StableUNIXUsersInternal,
clusterConfiguration: server.Services.ClusterConfiguration,
stableUNIXUsers: params.StableUNIXUsers,
clusterConfiguration: params.ClusterConfiguration,

uidCache: uidCache,

writerSem: make(chan struct{}, 1),
}, nil
}

// stableUNIXUsersServiceServer is the auth server implementation for the stable
// UNIX users service, including the gRPC interface, authz enforcement, and
// business logic.
type stableUNIXUsersServiceServer struct {
// server is the [stableunixusersv1.StableUNIXUsersServiceServer] returned by
// [New].
type server struct {
stableunixusersv1.UnsafeStableUNIXUsersServiceServer

authorizer authz.Authorizer
Expand All @@ -84,10 +103,8 @@ type stableUNIXUsersServiceServer struct {
writerSem chan struct{}
}

var _ stableunixusersv1.StableUNIXUsersServiceServer = (*stableUNIXUsersServiceServer)(nil)

// ListStableUNIXUsers implements [stableunixusersv1.StableUNIXUsersServiceServer].
func (s *stableUNIXUsersServiceServer) ListStableUNIXUsers(ctx context.Context, req *stableunixusersv1.ListStableUNIXUsersRequest) (*stableunixusersv1.ListStableUNIXUsersResponse, error) {
func (s *server) ListStableUNIXUsers(ctx context.Context, req *stableunixusersv1.ListStableUNIXUsersRequest) (*stableunixusersv1.ListStableUNIXUsersResponse, error) {
authCtx, err := s.authorizer.Authorize(ctx)
if err != nil {
return nil, trace.Wrap(err)
Expand All @@ -100,7 +117,7 @@ func (s *stableUNIXUsersServiceServer) ListStableUNIXUsers(ctx context.Context,
return s.listStableUNIXUsers(ctx, req)
}

func (s *stableUNIXUsersServiceServer) listStableUNIXUsers(ctx context.Context, req *stableunixusersv1.ListStableUNIXUsersRequest) (*stableunixusersv1.ListStableUNIXUsersResponse, error) {
func (s *server) listStableUNIXUsers(ctx context.Context, req *stableunixusersv1.ListStableUNIXUsersRequest) (*stableunixusersv1.ListStableUNIXUsersResponse, error) {
users, nextPageToken, err := s.stableUNIXUsers.ListStableUNIXUsers(ctx, int(req.GetPageSize()), req.GetPageToken())
if err != nil {
return nil, trace.Wrap(err)
Expand All @@ -121,7 +138,7 @@ func (s *stableUNIXUsersServiceServer) listStableUNIXUsers(ctx context.Context,
}

// ObtainUIDForUsername implements [stableunixusersv1.StableUNIXUsersServiceServer].
func (s *stableUNIXUsersServiceServer) ObtainUIDForUsername(ctx context.Context, req *stableunixusersv1.ObtainUIDForUsernameRequest) (*stableunixusersv1.ObtainUIDForUsernameResponse, error) {
func (s *server) ObtainUIDForUsername(ctx context.Context, req *stableunixusersv1.ObtainUIDForUsernameRequest) (*stableunixusersv1.ObtainUIDForUsernameResponse, error) {
authCtx, err := s.authorizer.Authorize(ctx)
if err != nil {
return nil, trace.Wrap(err)
Expand All @@ -141,9 +158,12 @@ func (s *stableUNIXUsersServiceServer) ObtainUIDForUsername(ctx context.Context,
}.Build(), nil
}

// obtainUIDForUsernameCached calls [obtainUIDForUsernameUncached] through the UID FnCache.
func (s *stableUNIXUsersServiceServer) obtainUIDForUsernameCached(ctx context.Context, username string) (int32, error) {
// obtainUIDForUsernameCached calls [*server.obtainUIDForUsernameUncached]
// through the UID FnCache.
func (s *server) obtainUIDForUsernameCached(ctx context.Context, username string) (int32, error) {
uid, err := utils.FnCacheGet(ctx, s.uidCache, username, func(ctx context.Context) (int32, error) {
ctx, cancel := context.WithTimeout(ctx, uidCacheTTL)
defer cancel()
return s.obtainUIDForUsernameUncached(ctx, username)
})
if err != nil {
Expand All @@ -153,7 +173,7 @@ func (s *stableUNIXUsersServiceServer) obtainUIDForUsernameCached(ctx context.Co
}

// obtainUIDForUsernameUncached reads or creates the stable UID for the given username.
func (s *stableUNIXUsersServiceServer) obtainUIDForUsernameUncached(ctx context.Context, username string) (int32, error) {
func (s *server) obtainUIDForUsernameUncached(ctx context.Context, username string) (int32, error) {
if username == "" {
return 0, trace.BadParameter("username must not be empty")
}
Expand Down Expand Up @@ -224,7 +244,7 @@ func (s *stableUNIXUsersServiceServer) obtainUIDForUsernameUncached(ctx context.

// createNewStableUNIXUser will search the configured UID range for a free UID
// and it will store an entry for the given username with that UID.
func (s *stableUNIXUsersServiceServer) createNewStableUNIXUser(ctx context.Context, username string, authPref readonly.AuthPreference) (int32, error) {
func (s *server) createNewStableUNIXUser(ctx context.Context, username string, authPref readonly.AuthPreference) (int32, error) {
cfg := authPref.GetStableUNIXUserConfig()
if cfg == nil || !cfg.Enabled {
return 0, trace.LimitExceeded("stable UNIX users are not enabled")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

package auth
package stableunixusers

import (
"context"
Expand Down Expand Up @@ -51,7 +51,7 @@ func TestStableUNIXUsers(t *testing.T) {
})
require.NoError(t, err)

svc := &stableUNIXUsersServiceServer{
svc := &server{
authorizer: nil,

backend: bk,
Expand Down Expand Up @@ -108,7 +108,7 @@ func TestStableUNIXUsers(t *testing.T) {
require.Equal(t, firstUID+3, uid4)

_, err = svc.obtainUIDForUsernameUncached(ctx, "user5")
require.ErrorAs(t, err, new(*trace.NotFoundError))
require.ErrorAs(t, err, new(*trace.LimitExceededError))

resp, err := svc.listStableUNIXUsers(ctx, stableunixusersv1.ListStableUNIXUsersRequest_builder{
PageSize: proto.Int32(2),
Expand Down

0 comments on commit 2553ef3

Please sign in to comment.