From be9c7083e3a266701f3628a1989176352612e5e2 Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 12 Apr 2023 16:26:57 -0500 Subject: [PATCH] [web] Add isModeratedSession flag to web ssh session (#24238) * Add isModeratedSession flag to web ssh session * Fix lint * Change to snakecase * Change to moderated --- lib/session/session.go | 2 ++ lib/web/apiserver.go | 14 ++++++++++++-- .../src/Console/DocumentSsh/DocumentSsh.story.tsx | 1 + .../teleport/src/Sessions/fixtures/index.ts | 5 +++++ .../teleport/src/services/session/makeSession.ts | 2 ++ .../teleport/src/services/session/types.ts | 2 ++ 6 files changed, 24 insertions(+), 2 deletions(-) diff --git a/lib/session/session.go b/lib/session/session.go index eb1d63a9ae25a..fdf6960e85e08 100644 --- a/lib/session/session.go +++ b/lib/session/session.go @@ -106,6 +106,8 @@ type Session struct { AppName string `json:"app_name"` // Owner is the name of the session owner, ie the one who created the session. Owner string `json:"owner"` + // Moderated is true if the session requires moderation. + Moderated bool `json:"moderated"` } // Participants returns the usernames of the current session participants. diff --git a/lib/web/apiserver.go b/lib/web/apiserver.go index 95a32dea89bad..35588626c9115 100644 --- a/lib/web/apiserver.go +++ b/lib/web/apiserver.go @@ -2435,7 +2435,7 @@ func (h *Handler) siteNodeConnect( if req.SessionID.IsZero() { // An existing session ID was not provided so we need to create a new one. - sessionData, err = h.generateSession(ctx, clt, req, clusterName, sessionCtx.cfg.User) + sessionData, err = h.generateSession(ctx, clt, req, clusterName, sessionCtx) if err != nil { h.log.WithError(err).Debug("Unable to generate new ssh session.") return nil, trace.Wrap(err) @@ -2503,12 +2503,13 @@ func (h *Handler) siteNodeConnect( return nil, nil } -func (h *Handler) generateSession(ctx context.Context, clt auth.ClientI, req *TerminalRequest, clusterName string, owner string) (session.Session, error) { +func (h *Handler) generateSession(ctx context.Context, clt auth.ClientI, req *TerminalRequest, clusterName string, scx *SessionContext) (session.Session, error) { var ( id string host string port int ) + owner := scx.cfg.User h.log.Infof("Generating new session for %s\n", clusterName) if _, err := uuid.Parse(req.Server); err != nil { @@ -2596,6 +2597,12 @@ func (h *Handler) generateSession(ctx context.Context, clt auth.ClientI, req *Te port = 0 id = req.Server } + accessChecker, err := scx.GetUserAccessChecker() + if err != nil { + return session.Session{}, trace.Wrap(err) + } + policySets := accessChecker.SessionPolicySets() + accessEvaluator := auth.NewSessionAccessEvaluator(policySets, types.SSHSessionKind, owner) return session.Session{ Login: req.Login, @@ -2603,6 +2610,7 @@ func (h *Handler) generateSession(ctx context.Context, clt auth.ClientI, req *Te ClusterName: clusterName, ServerHostname: host, ServerHostPort: port, + Moderated: accessEvaluator.IsModerated(), ID: session.NewID(), Created: time.Now().UTC(), LastActive: time.Now().UTC(), @@ -2709,6 +2717,7 @@ func trackerToLegacySession(tracker types.SessionTracker, clusterName string) se // note: we don't populate the RemoteAddr field since it isn't used and we don't have an equivalent value }) } + accessEvaluator := auth.NewSessionAccessEvaluator(tracker.GetHostPolicySets(), types.SSHSessionKind, tracker.GetHostUser()) return session.Session{ Kind: tracker.GetSessionKind(), @@ -2729,6 +2738,7 @@ func trackerToLegacySession(tracker types.SessionTracker, clusterName string) se KubernetesClusterName: tracker.GetKubeCluster(), DesktopName: tracker.GetDesktopName(), AppName: tracker.GetAppName(), + Moderated: accessEvaluator.IsModerated(), DatabaseName: tracker.GetDatabaseName(), Owner: tracker.GetHostUser(), } diff --git a/web/packages/teleport/src/Console/DocumentSsh/DocumentSsh.story.tsx b/web/packages/teleport/src/Console/DocumentSsh/DocumentSsh.story.tsx index d1be0cecc7269..0e7d185017b89 100644 --- a/web/packages/teleport/src/Console/DocumentSsh/DocumentSsh.story.tsx +++ b/web/packages/teleport/src/Console/DocumentSsh/DocumentSsh.story.tsx @@ -99,4 +99,5 @@ const session: Session = { parties: [], addr: '1.1.1.1:1111', participantModes: ['observer', 'moderator', 'peer'], + moderated: false, }; diff --git a/web/packages/teleport/src/Sessions/fixtures/index.ts b/web/packages/teleport/src/Sessions/fixtures/index.ts index 3e99f21420e38..2952abdb98557 100644 --- a/web/packages/teleport/src/Sessions/fixtures/index.ts +++ b/web/packages/teleport/src/Sessions/fixtures/index.ts @@ -34,6 +34,7 @@ export const sessions: Session[] = [ clusterId: 'im-a-cluster-name', resourceName: 'minikube', participantModes: ['observer', 'moderator', 'peer'], + moderated: false, }, { kind: 'ssh', @@ -52,6 +53,7 @@ export const sessions: Session[] = [ addr: 'd5d6d695-97c5-4bef-b052-0f5c6203d7a1', clusterId: 'im-a-cluster-name', participantModes: ['observer', 'moderator'], + moderated: false, }, { kind: 'desktop', @@ -70,6 +72,7 @@ export const sessions: Session[] = [ addr: 'd5d6d695-97c5-4bef-b052-0f5c6203d7a1', clusterId: 'im-a-cluster-name', participantModes: ['observer', 'moderator', 'peer'], + moderated: false, }, { kind: 'db', @@ -88,6 +91,7 @@ export const sessions: Session[] = [ addr: 'd5d6d695-97c5-4bef-b052-0f5c6203d7a1', clusterId: 'im-a-cluster-name', participantModes: ['observer'], + moderated: false, }, { kind: 'app', @@ -106,5 +110,6 @@ export const sessions: Session[] = [ addr: 'd5d6d695-97c5-4bef-b052-0f5c6203d7a1', clusterId: 'im-a-cluster-name', participantModes: ['observer', 'moderator', 'peer'], + moderated: false, }, ]; diff --git a/web/packages/teleport/src/services/session/makeSession.ts b/web/packages/teleport/src/services/session/makeSession.ts index 85e54574ca1d1..6661dd0372f22 100644 --- a/web/packages/teleport/src/services/session/makeSession.ts +++ b/web/packages/teleport/src/services/session/makeSession.ts @@ -38,6 +38,7 @@ export default function makeSession(json): Session { server_addr, parties, participantModes, + moderated, } = json; const createdDate = created ? new Date(created) : null; @@ -58,6 +59,7 @@ export default function makeSession(json): Session { parties: parties ? parties.map(p => makeParticipant(p)) : [], addr: server_addr ? server_addr.replace(PORT_REGEX, '') : '', participantModes: participantModes ?? [], + moderated, }; } diff --git a/web/packages/teleport/src/services/session/types.ts b/web/packages/teleport/src/services/session/types.ts index 46ce9b2ee3688..f422bafeaad8e 100644 --- a/web/packages/teleport/src/services/session/types.ts +++ b/web/packages/teleport/src/services/session/types.ts @@ -39,6 +39,8 @@ export interface Session { resourceName: string; // participantModes are the participant modes that are available to the user listing this session. participantModes: ParticipantMode[]; + // whether this session requires moderation or not. this is NOT if the session is currently being actively moderated + moderated: boolean; } export type SessionMetadata = {