Skip to content

Commit

Permalink
Merge branch 'branch/v16' into bot/backport-50074-branch/v16
Browse files Browse the repository at this point in the history
  • Loading branch information
tigrato authored Dec 13, 2024
2 parents 532f6af + 02719be commit 81f5771
Show file tree
Hide file tree
Showing 11 changed files with 82 additions and 32 deletions.
12 changes: 0 additions & 12 deletions build.assets/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -35,19 +35,7 @@ ifneq ("$(KUBECONFIG)","")
DOCKERFLAGS := $(DOCKERFLAGS) -v $(KUBECONFIG):/mnt/kube/config -e KUBECONFIG=/mnt/kube/config -e TEST_KUBE=$(TEST_KUBE)
endif

# conditionally force the use of UID/GID 1000:1000 if we're running in Github Actions (in which case CI env var will be set)
ifeq ("$(CI)","true")
# The UID/GID of the runner user on ARC runners is 1001, not 1000
# This var is currently only set for ARC runners via https://github.com/gravitational/cloud-terraform/pull/2473
ifeq ("$(CI_SYSTEM)","ARC")
UID := 1001
GID := 1001
NOROOT := -u 1001:1001
else
UID := 1000
GID := 1000
NOROOT := -u 1000:1000
endif
# if running in CI and the GOCACHE environment variable is not set, set it to a sensible default
ifeq ("$(GOCACHE)",)
GOCACHE := /go/cache
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@ Terraform provider. The daemon stores its identity on the disk and refresh the t

- A Linux host that you wish to run the Teleport Terraform provider onto.

- A Linux user on that host that you wish Terraform and `tbot` to run as. In the guide,
we will use <Var name="teleport" /> for this.
- A Linux user on that host that you wish Terraform and `tbot` to run as.

## Step 1/4. Install `tbot` on your server

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ interactively and select the Teleport certificate that you exported when prompte
- Disables Network Level Authentication (NLA) for remote desktop services.
- Enables RemoteFX compression, if using Teleport version 15 or newer.

Note: in order for the Windows Local Security Authority (LSA) to load the Teleport DLL,
[LSA protection](https://learn.microsoft.com/en-us/windows-server/security/credentials-protection-and-management/configuring-additional-lsa-protection)
must be disabled.

{/*lint ignore ordered-list-marker-value*/}
5. Restart the computer.

Expand Down
4 changes: 4 additions & 0 deletions lib/srv/regular/sshserver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1071,6 +1071,10 @@ func TestX11Forward(t *testing.T) {
// TestRootX11ForwardPermissions tests that X11 forwarding sessions are set up
// with the connecting user's file permissions (where needed), rather than root.
func TestRootX11ForwardPermissions(t *testing.T) {
// TODO(Joerger): Fix CI issue related to github actions sometimes using
// UID 1001 - https://github.com/gravitational/teleport/pull/50176
t.Skip("This test is flaky")

utils.RequireRoot(t)
if os.Getenv("TELEPORT_XAUTH_TEST") == "" {
t.Skip("Skipping test as xauth is not enabled")
Expand Down
17 changes: 15 additions & 2 deletions lib/web/apiserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -938,7 +938,7 @@ func (h *Handler) bindDefaultEndpoints() {
// Device Trust.
// Do not enforce bearer token for /webconfirm, it is called from outside the
// Web UI.
h.GET("/webapi/devices/webconfirm", h.WithAuthCookieAndCSRF(h.deviceWebConfirm))
h.GET("/webapi/devices/webconfirm", h.WithSession(h.deviceWebConfirm))

// trusted clusters
h.POST("/webapi/trustedclusters/validate", h.WithUnauthenticatedLimiter(h.validateTrustedCluster))
Expand Down Expand Up @@ -4698,9 +4698,22 @@ func (h *Handler) WithMetaRedirect(fn redirectHandlerFunc) httprouter.Handle {
}

// WithAuth ensures that a request is authenticated.
// Authenticated requests require both a session cookie as well as a bearer token.
func (h *Handler) WithAuth(fn ContextHandler) httprouter.Handle {
return httplib.MakeHandler(func(w http.ResponseWriter, r *http.Request, p httprouter.Params) (interface{}, error) {
sctx, err := h.AuthenticateRequest(w, r, true)
sctx, err := h.AuthenticateRequest(w, r, true /* check bearer token */)
if err != nil {
return nil, trace.Wrap(err)
}
return fn(w, r, p, sctx)
})
}

// WithSession ensures that the request provides a session cookie.
// It does not check for a bearer token.
func (h *Handler) WithSession(fn ContextHandler) httprouter.Handle {
return httplib.MakeHandler(func(w http.ResponseWriter, r *http.Request, p httprouter.Params) (interface{}, error) {
sctx, err := h.AuthenticateRequest(w, r, false /* check bearer token */)
if err != nil {
return nil, trace.Wrap(err)
}
Expand Down
2 changes: 2 additions & 0 deletions lib/web/session/cookie.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ func SetCookie(w http.ResponseWriter, user, sid string) error {
Path: "/",
HttpOnly: true,
Secure: true,
SameSite: http.SameSiteLaxMode,
}
http.SetCookie(w, c)
return nil
Expand All @@ -80,6 +81,7 @@ func ClearCookie(w http.ResponseWriter) {
Path: "/",
HttpOnly: true,
Secure: true,
SameSite: http.SameSiteLaxMode,
})
}

Expand Down
4 changes: 2 additions & 2 deletions lib/web/session/cookie_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func TestCookies(t *testing.T) {
require.Len(t, setCookies, 2)

// SetCookie will store the encoded session in the cookie
require.Equal(t, "__Host-session=7b2275736572223a226c6c616d61222c22736964223a223938373635227d; Path=/; HttpOnly; Secure", setCookies[0])
require.Equal(t, "__Host-session=7b2275736572223a226c6c616d61222c22736964223a223938373635227d; Path=/; HttpOnly; Secure; SameSite=Lax", setCookies[0])
// ClearCookie will add an entry with the cookie value cleared out
require.Equal(t, "__Host-session=; Path=/; HttpOnly; Secure", setCookies[1])
require.Equal(t, "__Host-session=; Path=/; HttpOnly; Secure; SameSite=Lax", setCookies[1])
}
27 changes: 24 additions & 3 deletions web/packages/teleport/src/Bots/List/Bots.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,20 @@ import { render, screen, userEvent, waitFor } from 'design/utils/testing';

import api from 'teleport/services/api';
import { botsApiResponseFixture } from 'teleport/Bots/fixtures';
import { createTeleportContext } from 'teleport/mocks/contexts';
import {
allAccessAcl,
createTeleportContext,
noAccess,
} from 'teleport/mocks/contexts';
import { ContextProvider } from 'teleport/index';
import TeleportContext from 'teleport/teleportContext';

import { Bots } from './Bots';

function renderWithContext(element) {
const ctx = createTeleportContext();
function renderWithContext(element, ctx?: TeleportContext) {
if (!ctx) {
ctx = createTeleportContext();
}
return render(
<MemoryRouter>
<ContextProvider ctx={ctx}>{element}</ContextProvider>
Expand Down Expand Up @@ -57,6 +64,20 @@ test('shows empty state when bots are empty', async () => {
});
});

test('shows missing permissions error if user lacks permissions to list', async () => {
jest.spyOn(api, 'get').mockResolvedValue({ items: [] });
const ctx = createTeleportContext();
ctx.storeUser.setState({ acl: { ...allAccessAcl, bots: noAccess } });
renderWithContext(<Bots />, ctx);

await waitFor(() => {
expect(screen.getByTestId('bots-empty-state')).toBeInTheDocument();
});
expect(
screen.getByText(/You do not have permission to access Bots/i)
).toBeInTheDocument();
});

test('calls edit endpoint', async () => {
jest
.spyOn(api, 'get')
Expand Down
25 changes: 18 additions & 7 deletions web/packages/teleport/src/Bots/List/Bots.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,15 @@ export function Bots() {
const ctx = useTeleport();
const flags = ctx.getFeatureFlags();
const hasAddBotPermissions = flags.addBots;
const canListBots = flags.listBots;

const [bots, setBots] = useState<FlatBot[]>([]);
const [selectedBot, setSelectedBot] = useState<FlatBot>();
const [selectedRoles, setSelectedRoles] = useState<string[]>();
const { attempt: crudAttempt, run: crudRun } = useAttemptNext();
const { attempt: fetchAttempt, run: fetchRun } = useAttemptNext('processing');
const { attempt: fetchAttempt, run: fetchRun } = useAttemptNext(
canListBots ? 'processing' : 'success'
);

useEffect(() => {
const signal = new AbortController();
Expand All @@ -60,15 +63,17 @@ export function Bots() {
return await fetchBots(signal, flags);
}

fetchRun(() =>
bots(signal.signal).then(botRes => {
setBots(botRes.bots);
})
);
if (canListBots) {
fetchRun(() =>
bots(signal.signal).then(botRes => {
setBots(botRes.bots);
})
);
}
return () => {
signal.abort();
};
}, [ctx, fetchRun]);
}, [ctx, fetchRun, canListBots]);

async function fetchRoleNames(search: string): Promise<string[]> {
const flags = ctx.getFeatureFlags();
Expand Down Expand Up @@ -122,6 +127,12 @@ export function Bots() {
if (fetchAttempt.status === 'success' && bots.length === 0) {
return (
<FeatureBox>
{!canListBots && (
<Alert kind="info" mt={4}>
You do not have permission to access Bots. Missing role permissions:{' '}
<code>bot.list</code>
</Alert>
)}
<EmptyState />
</FeatureBox>
);
Expand Down
12 changes: 10 additions & 2 deletions web/packages/teleport/src/Bots/List/EmptyState/EmptyState.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -206,12 +206,20 @@ export const BotTiles = () => {
<PreviewBox>
<Flex>
{integrationsTop.map(integration => (
<DisplayTile icon={integration.icon} title={integration.title} />
<DisplayTile
key={integration.title}
icon={integration.icon}
title={integration.title}
/>
))}
</Flex>
<Flex>
{integrationsBottom.map(integration => (
<DisplayTile icon={integration.icon} title={integration.title} />
<DisplayTile
key={integration.title}
icon={integration.icon}
title={integration.title}
/>
))}
</Flex>
</PreviewBox>
Expand Down
4 changes: 2 additions & 2 deletions web/packages/teleport/src/features.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -221,8 +221,8 @@ export class FeatureBots implements TeleportFeature {
component: Bots,
};

hasAccess(flags: FeatureFlags) {
return flags.listBots;
hasAccess() {
return true;
}

navigationItem = {
Expand Down

0 comments on commit 81f5771

Please sign in to comment.