mirror of
https://github.com/gravitational/teleport.git
synced 2026-10-31 20:39:37 +08:00
* Add GetType() to Plugin * Add Plugins feature flag to web * Run prettier * Update e_imports.go with slack plugin subpackage Respective enterprise changes imports a new subpackage, which pulls new dependencies.
254 lines
9.4 KiB
Go
254 lines
9.4 KiB
Go
/*
|
|
Copyright 2015 Gravitational, Inc.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package ui
|
|
|
|
import (
|
|
"github.com/gravitational/teleport/api/client/proto"
|
|
apidefaults "github.com/gravitational/teleport/api/defaults"
|
|
"github.com/gravitational/teleport/api/types"
|
|
"github.com/gravitational/teleport/lib/services"
|
|
)
|
|
|
|
type access struct {
|
|
List bool `json:"list"`
|
|
Read bool `json:"read"`
|
|
Edit bool `json:"edit"`
|
|
Create bool `json:"create"`
|
|
Delete bool `json:"remove"`
|
|
}
|
|
|
|
type accessStrategy struct {
|
|
// Type determines how a user should access teleport resources.
|
|
// ie: does the user require a request to access resources?
|
|
Type types.RequestStrategy `json:"type"`
|
|
// Prompt is the optional dialog shown to user,
|
|
// when the access strategy type requires a reason.
|
|
Prompt string `json:"prompt"`
|
|
}
|
|
|
|
// AccessCapabilities defines allowable access request rules defined in a user's roles.
|
|
type AccessCapabilities struct {
|
|
// RequestableRoles is a list of roles that the user can select when requesting access.
|
|
RequestableRoles []string `json:"requestableRoles"`
|
|
// SuggestedReviewers is a list of reviewers that the user can select when creating a request.
|
|
SuggestedReviewers []string `json:"suggestedReviewers"`
|
|
}
|
|
|
|
type userACL struct {
|
|
// RecordedSessions defines access to recorded sessions.
|
|
RecordedSessions access `json:"recordedSessions"`
|
|
// ActiveSessions defines access to active sessions.
|
|
ActiveSessions access `json:"activeSessions"`
|
|
// AuthConnectors defines access to auth.connectors.
|
|
AuthConnectors access `json:"authConnectors"`
|
|
// Roles defines access to roles.
|
|
Roles access `json:"roles"`
|
|
// Users defines access to users.
|
|
Users access `json:"users"`
|
|
// TrustedClusters defines access to trusted clusters.
|
|
TrustedClusters access `json:"trustedClusters"`
|
|
// Events defines access to audit logs.
|
|
Events access `json:"events"`
|
|
// Tokens defines access to tokens.
|
|
Tokens access `json:"tokens"`
|
|
// Nodes defines access to nodes.
|
|
Nodes access `json:"nodes"`
|
|
// AppServers defines access to application servers
|
|
AppServers access `json:"appServers"`
|
|
// DBServers defines access to database servers.
|
|
DBServers access `json:"dbServers"`
|
|
// DB defines access to database resource.
|
|
DB access `json:"db"`
|
|
// KubeServers defines access to kubernetes servers.
|
|
KubeServers access `json:"kubeServers"`
|
|
// Desktops defines access to desktops.
|
|
Desktops access `json:"desktops"`
|
|
// AccessRequests defines access to access requests.
|
|
AccessRequests access `json:"accessRequests"`
|
|
// Billing defines access to billing information.
|
|
Billing access `json:"billing"`
|
|
// ConnectionDiagnostic defines access to connection diagnostics.
|
|
ConnectionDiagnostic access `json:"connectionDiagnostic"`
|
|
// Clipboard defines whether the user can use a shared clipboard during windows desktop sessions.
|
|
Clipboard bool `json:"clipboard"`
|
|
// DesktopSessionRecording defines whether the user's desktop sessions are being recorded.
|
|
DesktopSessionRecording bool `json:"desktopSessionRecording"`
|
|
// DirectorySharing defines whether a user is permitted to share a directory during windows desktop sessions.
|
|
DirectorySharing bool `json:"directorySharing"`
|
|
// Download defines whether the user has access to download Teleport Enterprise Binaries
|
|
Download access `json:"download"`
|
|
// Download defines whether the user has access to download the license
|
|
License access `json:"license"`
|
|
// Plugins defines whether the user has access to manage hosted plugin instances
|
|
Plugins access `json:"plugins"`
|
|
}
|
|
|
|
type authType string
|
|
|
|
const (
|
|
authLocal authType = "local"
|
|
authSSO authType = "sso"
|
|
)
|
|
|
|
// UserContext describes user settings and access to various resources.
|
|
type UserContext struct {
|
|
// AuthType is auth method of this user.
|
|
AuthType authType `json:"authType"`
|
|
// Name is this user name.
|
|
Name string `json:"userName"`
|
|
// ACL contains user access control list.
|
|
ACL userACL `json:"userAcl"`
|
|
// Cluster contains cluster detail for this user's context.
|
|
Cluster *Cluster `json:"cluster"`
|
|
// AccessStrategy describes how a user should access teleport resources.
|
|
AccessStrategy accessStrategy `json:"accessStrategy"`
|
|
// AccessCapabilities defines allowable access request rules defined in a user's roles.
|
|
AccessCapabilities AccessCapabilities `json:"accessCapabilities"`
|
|
// ConsumedAccessRequestID is the request ID of the access request from which the assumed role was
|
|
// obtained
|
|
ConsumedAccessRequestID string `json:"accessRequestId,omitempty"`
|
|
}
|
|
|
|
func hasAccess(roleSet services.RoleSet, ctx *services.Context, kind string, verbs ...string) bool {
|
|
for _, verb := range verbs {
|
|
// Since this check occurs often and does not imply the caller is trying to
|
|
// access any resource, silence any logging done on the proxy.
|
|
if err := roleSet.GuessIfAccessIsPossible(ctx, apidefaults.Namespace, kind, verb, true); err != nil {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
func newAccess(roleSet services.RoleSet, ctx *services.Context, kind string) access {
|
|
return access{
|
|
List: hasAccess(roleSet, ctx, kind, types.VerbList),
|
|
Read: hasAccess(roleSet, ctx, kind, types.VerbRead),
|
|
Edit: hasAccess(roleSet, ctx, kind, types.VerbUpdate),
|
|
Create: hasAccess(roleSet, ctx, kind, types.VerbCreate),
|
|
Delete: hasAccess(roleSet, ctx, kind, types.VerbDelete),
|
|
}
|
|
}
|
|
|
|
func getAccessStrategy(roleset services.RoleSet) accessStrategy {
|
|
strategy := types.RequestStrategyOptional
|
|
prompt := ""
|
|
|
|
for _, role := range roleset {
|
|
options := role.GetOptions()
|
|
|
|
if options.RequestAccess == types.RequestStrategyReason {
|
|
strategy = types.RequestStrategyReason
|
|
prompt = options.RequestPrompt
|
|
break
|
|
}
|
|
|
|
if options.RequestAccess == types.RequestStrategyAlways {
|
|
strategy = types.RequestStrategyAlways
|
|
}
|
|
}
|
|
|
|
return accessStrategy{
|
|
Type: strategy,
|
|
Prompt: prompt,
|
|
}
|
|
}
|
|
|
|
// NewUserContext returns user context
|
|
func NewUserContext(user types.User, userRoles services.RoleSet, features proto.Features, desktopRecordingEnabled bool) (*UserContext, error) {
|
|
ctx := &services.Context{User: user}
|
|
recordedSessionAccess := newAccess(userRoles, ctx, types.KindSession)
|
|
activeSessionAccess := newAccess(userRoles, ctx, types.KindSSHSession)
|
|
roleAccess := newAccess(userRoles, ctx, types.KindRole)
|
|
authConnectors := newAccess(userRoles, ctx, types.KindAuthConnector)
|
|
trustedClusterAccess := newAccess(userRoles, ctx, types.KindTrustedCluster)
|
|
eventAccess := newAccess(userRoles, ctx, types.KindEvent)
|
|
userAccess := newAccess(userRoles, ctx, types.KindUser)
|
|
tokenAccess := newAccess(userRoles, ctx, types.KindToken)
|
|
nodeAccess := newAccess(userRoles, ctx, types.KindNode)
|
|
appServerAccess := newAccess(userRoles, ctx, types.KindAppServer)
|
|
dbServerAccess := newAccess(userRoles, ctx, types.KindDatabaseServer)
|
|
dbAccess := newAccess(userRoles, ctx, types.KindDatabase)
|
|
kubeServerAccess := newAccess(userRoles, ctx, types.KindKubeServer)
|
|
requestAccess := newAccess(userRoles, ctx, types.KindAccessRequest)
|
|
desktopAccess := newAccess(userRoles, ctx, types.KindWindowsDesktop)
|
|
cnDiagnosticAccess := newAccess(userRoles, ctx, types.KindConnectionDiagnostic)
|
|
|
|
var billingAccess access
|
|
if features.Cloud {
|
|
billingAccess = newAccess(userRoles, ctx, types.KindBilling)
|
|
}
|
|
|
|
var pluginsAccess access
|
|
if features.Plugins {
|
|
pluginsAccess = newAccess(userRoles, ctx, types.KindPlugin)
|
|
}
|
|
|
|
accessStrategy := getAccessStrategy(userRoles)
|
|
clipboard := userRoles.DesktopClipboard()
|
|
desktopSessionRecording := desktopRecordingEnabled && userRoles.RecordDesktopSession()
|
|
directorySharing := userRoles.DesktopDirectorySharing()
|
|
download := newAccess(userRoles, ctx, types.KindDownload)
|
|
license := newAccess(userRoles, ctx, types.KindLicense)
|
|
|
|
acl := userACL{
|
|
AccessRequests: requestAccess,
|
|
AppServers: appServerAccess,
|
|
DBServers: dbServerAccess,
|
|
DB: dbAccess,
|
|
KubeServers: kubeServerAccess,
|
|
Desktops: desktopAccess,
|
|
AuthConnectors: authConnectors,
|
|
TrustedClusters: trustedClusterAccess,
|
|
RecordedSessions: recordedSessionAccess,
|
|
ActiveSessions: activeSessionAccess,
|
|
Roles: roleAccess,
|
|
Events: eventAccess,
|
|
Users: userAccess,
|
|
Tokens: tokenAccess,
|
|
Nodes: nodeAccess,
|
|
Billing: billingAccess,
|
|
ConnectionDiagnostic: cnDiagnosticAccess,
|
|
Clipboard: clipboard,
|
|
DesktopSessionRecording: desktopSessionRecording,
|
|
DirectorySharing: directorySharing,
|
|
Download: download,
|
|
License: license,
|
|
Plugins: pluginsAccess,
|
|
}
|
|
|
|
// local user
|
|
authType := authLocal
|
|
|
|
// check for any SSO identities
|
|
isSSO := len(user.GetOIDCIdentities()) > 0 ||
|
|
len(user.GetGithubIdentities()) > 0 ||
|
|
len(user.GetSAMLIdentities()) > 0
|
|
|
|
if isSSO {
|
|
// SSO user
|
|
authType = authSSO
|
|
}
|
|
|
|
return &UserContext{
|
|
Name: user.GetName(),
|
|
ACL: acl,
|
|
AuthType: authType,
|
|
AccessStrategy: accessStrategy,
|
|
}, nil
|
|
}
|