github.com/gravitational/teleport/api@v0.0.0-20240507183017-3110591cbafc/types/session_tracker.go (about) 1 /* 2 Copyright 2021 Gravitational, Inc. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package types 18 19 import ( 20 "slices" 21 "time" 22 23 "github.com/gravitational/trace" 24 25 "github.com/gravitational/teleport/api/defaults" 26 ) 27 28 const ( 29 SSHSessionKind SessionKind = "ssh" 30 KubernetesSessionKind SessionKind = "k8s" 31 DatabaseSessionKind SessionKind = "db" 32 AppSessionKind SessionKind = "app" 33 WindowsDesktopSessionKind SessionKind = "desktop" 34 SessionObserverMode SessionParticipantMode = "observer" 35 SessionModeratorMode SessionParticipantMode = "moderator" 36 SessionPeerMode SessionParticipantMode = "peer" 37 ) 38 39 // SessionKind is a type of session. 40 type SessionKind string 41 42 // SessionParticipantMode is the mode that determines what you can do when you join a session. 43 type SessionParticipantMode string 44 45 // SessionTracker is a resource which tracks an active session. 46 type SessionTracker interface { 47 Resource 48 49 // GetSessionID returns the ID of the session. 50 GetSessionID() string 51 52 // GetSessionKind returns the kind of the session. 53 GetSessionKind() SessionKind 54 55 // GetState returns the state of the session. 56 GetState() SessionState 57 58 // SetState sets the state of the session. 59 SetState(SessionState) error 60 61 // SetCreated sets the time at which the session was created. 62 SetCreated(time.Time) 63 64 // GetCreated returns the time at which the session was created. 65 GetCreated() time.Time 66 67 // GetExpires return the time at which the session expires. 68 GetExpires() time.Time 69 70 // GetReason returns the reason for the session. 71 GetReason() string 72 73 // GetInvited returns a list of people invited to the session. 74 GetInvited() []string 75 76 // GetHostname returns the hostname of the session target. 77 GetHostname() string 78 79 // GetAddress returns the address of the session target. 80 GetAddress() string 81 82 // GetClusterName returns the name of the Teleport cluster. 83 GetClusterName() string 84 85 // GetLogin returns the target machine username used for this session. 86 GetLogin() string 87 88 // GetParticipants returns the list of participants in the session. 89 GetParticipants() []Participant 90 91 // AddParticipant adds a participant to the session tracker. 92 AddParticipant(Participant) 93 94 // RemoveParticipant removes a participant from the session tracker. 95 RemoveParticipant(string) error 96 97 // UpdatePresence updates presence timestamp of a participant. 98 UpdatePresence(string, time.Time) error 99 100 // GetKubeCluster returns the name of the kubernetes cluster the session is running in. 101 GetKubeCluster() string 102 103 // GetDesktopName returns the name of the Windows desktop the session is running in. 104 GetDesktopName() string 105 106 // GetAppName returns the name of the app being accessed. 107 GetAppName() string 108 109 // GetDatabaseName returns the name of the database being accessed. 110 GetDatabaseName() string 111 112 // GetHostUser fetches the user marked as the "host" of the session. 113 // Things like RBAC policies are determined from this user. 114 GetHostUser() string 115 116 // GetHostPolicySets returns a list of policy sets held by the host user at the time of session creation. 117 // This a subset of a role that contains some versioning and naming information in addition to the require policies 118 GetHostPolicySets() []*SessionTrackerPolicySet 119 120 // GetLastActive returns the time at which the session was last active (i.e used by any participant). 121 GetLastActive() time.Time 122 123 // HostID is the target host id that created the session tracker. 124 GetHostID() string 125 126 // GetTargetSubKind returns the sub kind of the target server. 127 GetTargetSubKind() string 128 129 // GetCommand returns the command that initiated the session. 130 GetCommand() []string 131 } 132 133 func NewSessionTracker(spec SessionTrackerSpecV1) (SessionTracker, error) { 134 session := &SessionTrackerV1{ 135 ResourceHeader: ResourceHeader{ 136 Metadata: Metadata{ 137 Name: spec.SessionID, 138 }, 139 }, 140 Spec: spec, 141 } 142 143 if err := session.CheckAndSetDefaults(); err != nil { 144 return nil, trace.Wrap(err) 145 } 146 147 return session, nil 148 } 149 150 // setStaticFields sets static resource header and metadata fields. 151 func (s *SessionTrackerV1) setStaticFields() { 152 s.Kind = KindSessionTracker 153 s.Version = V1 154 } 155 156 // CheckAndSetDefaults sets defaults for the session resource. 157 func (s *SessionTrackerV1) CheckAndSetDefaults() error { 158 s.setStaticFields() 159 160 if err := s.Metadata.CheckAndSetDefaults(); err != nil { 161 return trace.Wrap(err) 162 } 163 164 if s.GetCreated().IsZero() { 165 s.SetCreated(time.Now()) 166 } 167 168 if s.Expiry().IsZero() { 169 // By default, resource expiration should match session expiration. 170 expiry := s.GetExpires() 171 if expiry.IsZero() { 172 expiry = s.GetCreated().Add(defaults.SessionTrackerTTL) 173 } 174 s.SetExpiry(expiry) 175 } 176 177 return nil 178 } 179 180 // GetSessionID returns the ID of the session. 181 func (s *SessionTrackerV1) GetSessionID() string { 182 return s.Spec.SessionID 183 } 184 185 // GetSessionKind returns the kind of the session. 186 func (s *SessionTrackerV1) GetSessionKind() SessionKind { 187 return SessionKind(s.Spec.Kind) 188 } 189 190 // GetState returns the state of the session. 191 func (s *SessionTrackerV1) GetState() SessionState { 192 return s.Spec.State 193 } 194 195 // SetState sets the state of the session. 196 func (s *SessionTrackerV1) SetState(state SessionState) error { 197 switch state { 198 case SessionState_SessionStateRunning, SessionState_SessionStatePending, SessionState_SessionStateTerminated: 199 s.Spec.State = state 200 return nil 201 default: 202 return trace.BadParameter("invalid session state: %v", state) 203 } 204 } 205 206 // GetCreated returns the time at which the session was created. 207 func (s *SessionTrackerV1) GetCreated() time.Time { 208 return s.Spec.Created 209 } 210 211 // SetCreated returns the time at which the session was created. 212 func (s *SessionTrackerV1) SetCreated(created time.Time) { 213 s.Spec.Created = created 214 } 215 216 // GetExpires return the time at which the session expires. 217 func (s *SessionTrackerV1) GetExpires() time.Time { 218 return s.Spec.Expires 219 } 220 221 // GetReason returns the reason for the session. 222 func (s *SessionTrackerV1) GetReason() string { 223 return s.Spec.Reason 224 } 225 226 // GetInvited returns a list of people invited to the session. 227 func (s *SessionTrackerV1) GetInvited() []string { 228 return s.Spec.Invited 229 } 230 231 // GetHostname returns the hostname of the session target. 232 func (s *SessionTrackerV1) GetHostname() string { 233 return s.Spec.Hostname 234 } 235 236 // GetAddress returns the address of the session target. 237 func (s *SessionTrackerV1) GetAddress() string { 238 return s.Spec.Address 239 } 240 241 // GetClustername returns the name of the cluster the session is running in. 242 func (s *SessionTrackerV1) GetClusterName() string { 243 return s.Spec.ClusterName 244 } 245 246 // GetLogin returns the target machine username used for this session. 247 func (s *SessionTrackerV1) GetLogin() string { 248 return s.Spec.Login 249 } 250 251 // GetParticipants returns a list of participants in the session. 252 func (s *SessionTrackerV1) GetParticipants() []Participant { 253 return s.Spec.Participants 254 } 255 256 // AddParticipant adds a participant to the session tracker. 257 func (s *SessionTrackerV1) AddParticipant(participant Participant) { 258 s.Spec.Participants = append(s.Spec.Participants, participant) 259 } 260 261 // RemoveParticipant removes a participant from the session tracker. 262 func (s *SessionTrackerV1) RemoveParticipant(id string) error { 263 for i, participant := range s.Spec.Participants { 264 if participant.ID == id { 265 s.Spec.Participants[i], s.Spec.Participants = s.Spec.Participants[len(s.Spec.Participants)-1], s.Spec.Participants[:len(s.Spec.Participants)-1] 266 return nil 267 } 268 } 269 270 return trace.NotFound("participant %v not found", id) 271 } 272 273 // GetKubeCluster returns the name of the kubernetes cluster the session is running in. 274 // 275 // This is only valid for kubernetes sessions. 276 func (s *SessionTrackerV1) GetKubeCluster() string { 277 return s.Spec.KubernetesCluster 278 } 279 280 // HostID is the target host id that created the session tracker. 281 func (s *SessionTrackerV1) GetHostID() string { 282 return s.Spec.HostID 283 } 284 285 // GetDesktopName returns the name of the Windows desktop the session is running in. 286 // 287 // This is only valid for Windows desktop sessions. 288 func (s *SessionTrackerV1) GetDesktopName() string { 289 return s.Spec.DesktopName 290 } 291 292 // GetAppName returns the name of the app being accessed in the session. 293 // 294 // This is only valid for app sessions. 295 func (s *SessionTrackerV1) GetAppName() string { 296 return s.Spec.AppName 297 } 298 299 // GetDatabaseName returns the name of the database being accessed in the session. 300 // 301 // This is only valid for database sessions. 302 func (s *SessionTrackerV1) GetDatabaseName() string { 303 return s.Spec.DatabaseName 304 } 305 306 // GetHostUser fetches the user marked as the "host" of the session. 307 // Things like RBAC policies are determined from this user. 308 func (s *SessionTrackerV1) GetHostUser() string { 309 return s.Spec.HostUser 310 } 311 312 // UpdatePresence updates presence timestamp of a participant. 313 func (s *SessionTrackerV1) UpdatePresence(user string, t time.Time) error { 314 idx := slices.IndexFunc(s.Spec.Participants, func(participant Participant) bool { 315 return participant.User == user 316 }) 317 318 if idx < 0 { 319 return trace.NotFound("participant %v not found", user) 320 } 321 322 s.Spec.Participants[idx].LastActive = t 323 return nil 324 } 325 326 // GetHostPolicySets returns a list of policy sets held by the host user at the time of session creation. 327 // This a subset of a role that contains some versioning and naming information in addition to the require policies 328 func (s *SessionTrackerV1) GetHostPolicySets() []*SessionTrackerPolicySet { 329 return s.Spec.HostPolicies 330 } 331 332 // GetLastActive returns the time at which the session was last active (i.e used by any participant). 333 func (s *SessionTrackerV1) GetLastActive() time.Time { 334 var last time.Time 335 336 for _, participant := range s.Spec.Participants { 337 if participant.LastActive.After(last) { 338 last = participant.LastActive 339 } 340 } 341 342 return last 343 } 344 345 // GetTargetSubKind returns the sub kind of the target server. 346 func (s *SessionTrackerV1) GetTargetSubKind() string { 347 return s.Spec.TargetSubKind 348 } 349 350 // GetCommand returns command that intiated the session. 351 func (s *SessionTrackerV1) GetCommand() []string { 352 return s.Spec.InitialCommand 353 } 354 355 // Match checks if a given session tracker matches this filter. 356 func (f *SessionTrackerFilter) Match(s SessionTracker) bool { 357 if f.Kind != "" && string(s.GetSessionKind()) != f.Kind { 358 return false 359 } 360 if f.State != nil && s.GetState() != f.State.State { 361 return false 362 } 363 if f.DesktopName != "" && s.GetDesktopName() != f.DesktopName { 364 return false 365 } 366 return true 367 }