Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions lib/web/ui/usercontext.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ type access struct {
Edit bool `json:"edit"`
Create bool `json:"create"`
Delete bool `json:"remove"`
Use bool `json:"use"`
}

type accessStrategy struct {
Expand Down Expand Up @@ -95,6 +96,8 @@ type userACL struct {
License access `json:"license"`
// Plugins defines whether the user has access to manage hosted plugin instances
Plugins access `json:"plugins"`
// Integrations defines whether the user has access to manage integrations.
Integrations access `json:"integrations"`
}

type authType string
Expand Down Expand Up @@ -141,6 +144,7 @@ func newAccess(roleSet services.RoleSet, ctx *services.Context, kind string) acc
Edit: hasAccess(roleSet, ctx, kind, types.VerbUpdate),
Create: hasAccess(roleSet, ctx, kind, types.VerbCreate),
Delete: hasAccess(roleSet, ctx, kind, types.VerbDelete),
Use: hasAccess(roleSet, ctx, kind, types.VerbUse),
}
}

Expand Down Expand Up @@ -204,6 +208,7 @@ func NewUserContext(user types.User, userRoles services.RoleSet, features proto.
directorySharing := userRoles.DesktopDirectorySharing()
download := newAccess(userRoles, ctx, types.KindDownload)
license := newAccess(userRoles, ctx, types.KindLicense)
integrationsAccess := newAccess(userRoles, ctx, types.KindIntegration)

acl := userACL{
AccessRequests: requestAccess,
Expand All @@ -229,6 +234,7 @@ func NewUserContext(user types.User, userRoles services.RoleSet, features proto.
Download: download,
License: license,
Plugins: pluginsAccess,
Integrations: integrationsAccess,
}

// local user
Expand Down
49 changes: 28 additions & 21 deletions lib/web/ui/usercontext_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ func TestNewUserContext(t *testing.T) {
Resources: []string{types.KindWindowsDesktop},
Verbs: services.RW(),
},
{
Resources: []string{types.KindIntegration},
Verbs: append(services.RW(), types.VerbUse),
},
})

// not setting the rule, or explicitly denying, both denies access
Expand Down Expand Up @@ -76,13 +80,13 @@ func TestNewUserContext(t *testing.T) {
userContext, err := NewUserContext(user, roleSet, proto.Features{}, true)
require.NoError(t, err)

allowed := access{true, true, true, true, true}
denied := access{false, false, false, false, false}
allowedRW := access{true, true, true, true, true, false}
denied := access{false, false, false, false, false, false}

// test user name and acl
require.Equal(t, userContext.Name, "root")
require.Empty(t, cmp.Diff(userContext.ACL.AuthConnectors, allowed))
require.Empty(t, cmp.Diff(userContext.ACL.TrustedClusters, allowed))
require.Empty(t, cmp.Diff(userContext.ACL.AuthConnectors, allowedRW))
require.Empty(t, cmp.Diff(userContext.ACL.TrustedClusters, allowedRW))
require.Empty(t, cmp.Diff(userContext.ACL.AppServers, denied))
require.Empty(t, cmp.Diff(userContext.ACL.DBServers, denied))
require.Empty(t, cmp.Diff(userContext.ACL.KubeServers, denied))
Expand All @@ -94,7 +98,7 @@ func TestNewUserContext(t *testing.T) {
require.Empty(t, cmp.Diff(userContext.ACL.Nodes, denied))
require.Empty(t, cmp.Diff(userContext.ACL.AccessRequests, denied))
require.Empty(t, cmp.Diff(userContext.ACL.ConnectionDiagnostic, denied))
require.Empty(t, cmp.Diff(userContext.ACL.Desktops, allowed))
require.Empty(t, cmp.Diff(userContext.ACL.Desktops, allowedRW))
require.Empty(t, cmp.Diff(userContext.AccessStrategy, accessStrategy{
Type: types.RequestStrategyOptional,
Prompt: "",
Expand All @@ -106,6 +110,9 @@ func TestNewUserContext(t *testing.T) {
require.Empty(t, cmp.Diff(userContext.ACL.License, denied))
require.Empty(t, cmp.Diff(userContext.ACL.Download, denied))

// test enabling of the 'Use' verb
require.Empty(t, cmp.Diff(userContext.ACL.Integrations, access{true, true, true, true, true, true}))

// test local auth type
require.Equal(t, userContext.AuthType, authLocal)

Expand All @@ -117,7 +124,7 @@ func TestNewUserContext(t *testing.T) {

userContext, err = NewUserContext(user, roleSet, proto.Features{Cloud: true}, true)
require.NoError(t, err)
require.Empty(t, cmp.Diff(userContext.ACL.Billing, access{true, true, false, false, false}))
require.Empty(t, cmp.Diff(userContext.ACL.Billing, access{true, true, false, false, false, false}))

// test that desktopRecordingEnabled being false overrides the roleSet.RecordDesktopSession() returning true
userContext, err = NewUserContext(user, roleSet, proto.Features{}, false)
Expand Down Expand Up @@ -148,24 +155,24 @@ func TestNewUserContextCloud(t *testing.T) {

roleSet := []types.Role{role}

allowed := access{true, true, true, true, true}
allowedRW := access{true, true, true, true, true, false}

userContext, err := NewUserContext(user, roleSet, proto.Features{Cloud: true}, true)
require.NoError(t, err)

require.Equal(t, userContext.Name, "root")
require.Empty(t, cmp.Diff(userContext.ACL.AuthConnectors, allowed))
require.Empty(t, cmp.Diff(userContext.ACL.TrustedClusters, allowed))
require.Empty(t, cmp.Diff(userContext.ACL.AppServers, allowed))
require.Empty(t, cmp.Diff(userContext.ACL.DBServers, allowed))
require.Empty(t, cmp.Diff(userContext.ACL.KubeServers, allowed))
require.Empty(t, cmp.Diff(userContext.ACL.Events, allowed))
require.Empty(t, cmp.Diff(userContext.ACL.RecordedSessions, allowed))
require.Empty(t, cmp.Diff(userContext.ACL.Roles, allowed))
require.Empty(t, cmp.Diff(userContext.ACL.Users, allowed))
require.Empty(t, cmp.Diff(userContext.ACL.Tokens, allowed))
require.Empty(t, cmp.Diff(userContext.ACL.Nodes, allowed))
require.Empty(t, cmp.Diff(userContext.ACL.AccessRequests, allowed))
require.Empty(t, cmp.Diff(userContext.ACL.AuthConnectors, allowedRW))
require.Empty(t, cmp.Diff(userContext.ACL.TrustedClusters, allowedRW))
require.Empty(t, cmp.Diff(userContext.ACL.AppServers, allowedRW))
require.Empty(t, cmp.Diff(userContext.ACL.DBServers, allowedRW))
require.Empty(t, cmp.Diff(userContext.ACL.KubeServers, allowedRW))
require.Empty(t, cmp.Diff(userContext.ACL.Events, allowedRW))
require.Empty(t, cmp.Diff(userContext.ACL.RecordedSessions, allowedRW))
require.Empty(t, cmp.Diff(userContext.ACL.Roles, allowedRW))
require.Empty(t, cmp.Diff(userContext.ACL.Users, allowedRW))
require.Empty(t, cmp.Diff(userContext.ACL.Tokens, allowedRW))
require.Empty(t, cmp.Diff(userContext.ACL.Nodes, allowedRW))
require.Empty(t, cmp.Diff(userContext.ACL.AccessRequests, allowedRW))
require.Empty(t, cmp.Diff(userContext.AccessStrategy, accessStrategy{
Type: types.RequestStrategyOptional,
Prompt: "",
Expand All @@ -175,6 +182,6 @@ func TestNewUserContextCloud(t *testing.T) {
require.Equal(t, userContext.ACL.DesktopSessionRecording, true)

// cloud-specific asserts
require.Empty(t, cmp.Diff(userContext.ACL.Billing, allowed))
require.Empty(t, cmp.Diff(userContext.ACL.Desktops, allowed))
require.Empty(t, cmp.Diff(userContext.ACL.Billing, allowedRW))
require.Empty(t, cmp.Diff(userContext.ACL.Desktops, allowedRW))
}
2 changes: 1 addition & 1 deletion web/packages/teleport/src/mocks/contexts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export const fullAcl: Acl = {
license: fullAccess,
download: fullAccess,
plugins: fullAccess,
integrations: fullAccess,
integrations: { ...fullAccess, use: true },
};

export const userContext = makeUserContext({
Expand Down
9 changes: 7 additions & 2 deletions web/packages/teleport/src/services/user/makeAcl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ export default function makeAcl(json): Acl {
const plugins = json.plugins || defaultAccess;
// TODO(lisa): requires backend changes to user context.
// Feature is off until all TODO related to integrations is done.
// const integrations = json.integrations || defaultAccess;
const integrations = defaultAccess;
// const integrations = json.integrations || defaultAccessWithUse;
const integrations = defaultAccessWithUse;
const dbServers = json.dbServers || defaultAccess;
const db = json.db || defaultAccess;
const desktops = json.desktops || defaultAccess;
Expand Down Expand Up @@ -93,3 +93,8 @@ export const defaultAccess = {
create: false,
remove: false,
};

export const defaultAccessWithUse = {
...defaultAccess,
use: false,
};
6 changes: 5 additions & 1 deletion web/packages/teleport/src/services/user/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ export interface Access {
remove: boolean;
}

export interface AccessWithUse extends Access {
use: boolean;
}

export interface Acl {
directorySharingEnabled: boolean;
desktopSessionRecordingEnabled: boolean;
Expand All @@ -71,7 +75,7 @@ export interface Acl {
license: Access;
download: Access;
plugins: Access;
integrations: Access;
integrations: AccessWithUse;
}

export interface User {
Expand Down
1 change: 1 addition & 0 deletions web/packages/teleport/src/services/user/user.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ test('undefined values in context response gives proper default values', async (
edit: false,
create: false,
remove: false,
use: false,
},
roles: {
list: false,
Expand Down