diff --git a/components/blobserve/leeway.Dockerfile b/components/blobserve/leeway.Dockerfile
index e1a57926db26c6..b62cff28e3da72 100644
--- a/components/blobserve/leeway.Dockerfile
+++ b/components/blobserve/leeway.Dockerfile
@@ -2,7 +2,7 @@
# Licensed under the GNU Affero General Public License (AGPL).
# See License.AGPL.txt in the project root for license information.
-FROM cgr.dev/chainguard/wolfi-base:latest@sha256:490977f0fd3d8596d173839dbb314153797312553b43f6a24b0e341cf2e8d473
+FROM cgr.dev/chainguard/wolfi-base:latest@sha256:5dcb7597e50978fc9dea77d96665bcd47ab0600386710c6e8dab35adf1102122
# Ensure latest packages are present, like security updates.
RUN apk upgrade --no-cache \
diff --git a/components/content-service/leeway.Dockerfile b/components/content-service/leeway.Dockerfile
index 472fa4c4ff9923..e2354082b4bbe6 100644
--- a/components/content-service/leeway.Dockerfile
+++ b/components/content-service/leeway.Dockerfile
@@ -2,7 +2,7 @@
# Licensed under the GNU Affero General Public License (AGPL).
# See License.AGPL.txt in the project root for license information.
-FROM cgr.dev/chainguard/wolfi-base:latest@sha256:490977f0fd3d8596d173839dbb314153797312553b43f6a24b0e341cf2e8d473
+FROM cgr.dev/chainguard/wolfi-base:latest@sha256:5dcb7597e50978fc9dea77d96665bcd47ab0600386710c6e8dab35adf1102122
# Ensure latest packages are present, like security updates.
RUN apk upgrade --no-cache \
diff --git a/components/dashboard/leeway.Dockerfile b/components/dashboard/leeway.Dockerfile
index e77ff4bb5c5ccd..08fa54be822bc9 100644
--- a/components/dashboard/leeway.Dockerfile
+++ b/components/dashboard/leeway.Dockerfile
@@ -2,7 +2,7 @@
# Licensed under the GNU Affero General Public License (AGPL).
# See License.AGPL.txt in the project root for license information.
-FROM cgr.dev/chainguard/wolfi-base:latest@sha256:490977f0fd3d8596d173839dbb314153797312553b43f6a24b0e341cf2e8d473 as compress
+FROM cgr.dev/chainguard/wolfi-base:latest@sha256:5dcb7597e50978fc9dea77d96665bcd47ab0600386710c6e8dab35adf1102122 as compress
RUN apk add brotli gzip
diff --git a/components/dashboard/src/components/InputWithCopy.tsx b/components/dashboard/src/components/InputWithCopy.tsx
index b3c29ead4a657a..080d574078e8d7 100644
--- a/components/dashboard/src/components/InputWithCopy.tsx
+++ b/components/dashboard/src/components/InputWithCopy.tsx
@@ -27,13 +27,11 @@ export function InputWithCopy(props: { value: string; tip?: string; className?:
type="text"
value={props.value}
/>
-
handleCopyToClipboard(props.value)}>
-
-
-
-
-
-
+
);
}
diff --git a/components/dashboard/src/data/featureflag-query.ts b/components/dashboard/src/data/featureflag-query.ts
index 84502dcb51d9a8..3c6cfdf34d9c31 100644
--- a/components/dashboard/src/data/featureflag-query.ts
+++ b/components/dashboard/src/data/featureflag-query.ts
@@ -24,6 +24,7 @@ const featureFlags = {
enableDedicatedOnboardingFlow: false,
usageDownload: false,
phoneVerificationByCall: false,
+ doRetryUserLoader: true,
};
export const useFeatureFlag = (featureFlag: keyof typeof featureFlags) => {
diff --git a/components/dashboard/src/hooks/use-user-loader.ts b/components/dashboard/src/hooks/use-user-loader.ts
index 0c2724f19092f8..918b4346803b38 100644
--- a/components/dashboard/src/hooks/use-user-loader.ts
+++ b/components/dashboard/src/hooks/use-user-loader.ts
@@ -11,9 +11,12 @@ import { trackLocation } from "../Analytics";
import { refreshSearchData } from "../components/RepositoryFinder";
import { useQuery } from "@tanstack/react-query";
import { noPersistence } from "../data/setup";
+import { ErrorCodes } from "@gitpod/gitpod-protocol/lib/messaging/error";
+import { useFeatureFlag } from "../data/featureflag-query";
export const useUserLoader = () => {
const { user, setUser } = useContext(UserContext);
+ const doRetryUserLoader = useFeatureFlag("doRetryUserLoader");
// For now, we're using the user context to store the user, but letting react-query handle the loading
// In the future, we should remove the user context and use react-query to access the user
@@ -27,8 +30,15 @@ export const useUserLoader = () => {
// We'll let an ErrorBoundary catch the error
useErrorBoundary: true,
// It's important we don't retry as we want to show the login screen as quickly as possible if a 401
- // TODO: In the future we can consider retrying for non 401 errors
- retry: false,
+ retry: (_failureCount: number, error: Error & { code?: number }) => {
+ if (!doRetryUserLoader) {
+ return false;
+ }
+ return error.code !== ErrorCodes.NOT_AUTHENTICATED;
+ },
+ // docs: https://tanstack.com/query/v4/docs/react/guides/query-retries
+ // backoff by doubling, max. 10s
+ retryDelay: (attemptIndex) => Math.min(1000 * 2 ** attemptIndex, 10000),
cacheTime: 1000 * 60 * 60 * 1, // 1 hour
staleTime: 1000 * 60 * 60 * 1, // 1 hour
onSuccess: (loadedUser) => {
diff --git a/components/dashboard/src/index.css b/components/dashboard/src/index.css
index db48bcdd27e2dd..d2783dd8fa2d09 100644
--- a/components/dashboard/src/index.css
+++ b/components/dashboard/src/index.css
@@ -55,6 +55,11 @@
button {
@apply cursor-pointer px-4 py-2 my-auto bg-green-600 dark:bg-green-700 hover:bg-green-700 dark:hover:bg-green-600 text-gray-100 dark:text-green-100 text-sm font-medium rounded-md focus:outline-none focus:ring transition ease-in-out;
}
+ button.reset {
+ @apply bg-transparent hover:bg-transparent font-normal rounded-none;
+ padding: unset;
+ text-align: start;
+ }
button.secondary {
@apply bg-gray-100 dark:bg-gray-700 hover:bg-gray-200 dark:hover:bg-gray-600 text-gray-500 dark:text-gray-100 hover:text-gray-600;
}
diff --git a/components/dashboard/src/teams/git-integrations/GitIntegrationModal.tsx b/components/dashboard/src/teams/git-integrations/GitIntegrationModal.tsx
index d76fb3ef6370c3..7f345182d0a7b6 100644
--- a/components/dashboard/src/teams/git-integrations/GitIntegrationModal.tsx
+++ b/components/dashboard/src/teams/git-integrations/GitIntegrationModal.tsx
@@ -42,19 +42,7 @@ export const GitIntegrationModal: FunctionComponent = (props) => {
const isNew = !savedProvider;
// This is a readonly value to copy and plug into external oauth config
- const redirectURL = useMemo(() => {
- let url = "";
-
- // Once it's saved, use what's stored
- if (!isNew) {
- url = savedProvider?.oauth.callBackUrl ?? url;
- } else {
- // Otherwise construct it w/ their provided host value or example
- url = callbackUrl(host || getPlaceholderForIntegrationType(type));
- }
-
- return url;
- }, [host, isNew, savedProvider?.oauth.callBackUrl, type]);
+ const redirectURL = callbackUrl();
// "bitbucket.org" is set as host value whenever "Bitbucket" is selected
useEffect(() => {
@@ -281,13 +269,8 @@ export const GitIntegrationModal: FunctionComponent = (props) => {
);
};
-const callbackUrl = (host: string) => {
- // Negative Lookahead (?!\/)
- // `\/` matches the character `/`
- // "https://foobar:80".replace(/:(?!\/)/, "_")
- // => 'https://foobar_80'
- host = host.replace(/:(?!\/)/, "_");
- const pathname = `/auth/${host}/callback`;
+const callbackUrl = () => {
+ const pathname = `/auth/callback`;
return gitpodHostUrl.with({ pathname }).toString();
};
diff --git a/components/dashboard/src/user-settings/Integrations.test.tsx b/components/dashboard/src/user-settings/Integrations.test.tsx
index c8ec9362642c49..f5d1887f5402b3 100644
--- a/components/dashboard/src/user-settings/Integrations.test.tsx
+++ b/components/dashboard/src/user-settings/Integrations.test.tsx
@@ -20,5 +20,5 @@ test("should update redirectURL preview", async () => {
const redirectURL = screen.getByLabelText(/Redirect/i);
// screen.debug(redirectURL);
- expect((redirectURL as HTMLInputElement).value).toEqual("http://localhost/auth/gitlab.gitpod.io_80/callback");
+ expect((redirectURL as HTMLInputElement).value).toEqual("http://localhost/auth/callback");
});
diff --git a/components/dashboard/src/user-settings/Integrations.tsx b/components/dashboard/src/user-settings/Integrations.tsx
index d396aef3b0d849..59a29096744c30 100644
--- a/components/dashboard/src/user-settings/Integrations.tsx
+++ b/components/dashboard/src/user-settings/Integrations.tsx
@@ -504,13 +504,8 @@ export function GitIntegrationModal(
onAuthorize?: (payload?: string) => void;
},
) {
- const callbackUrl = (host: string) => {
- // Negative Lookahead (?!\/)
- // `\/` matches the character `/`
- // "https://foobar:80".replace(/:(?!\/)/, "_")
- // => 'https://foobar_80'
- host = host.replace(/:(?!\/)/, "_");
- const pathname = `/auth/${host}/callback`;
+ const callbackUrl = () => {
+ const pathname = `/auth/callback`;
return gitpodHostUrl.with({ pathname }).toString();
};
@@ -519,7 +514,7 @@ export function GitIntegrationModal(
const [type, setType] = useState("GitLab");
const [host, setHost] = useState("");
- const [redirectURI, setRedirectURI] = useState(callbackUrl("gitlab.example.com"));
+ const [redirectURI, setRedirectURI] = useState(callbackUrl());
const [clientId, setClientId] = useState("");
const [clientSecret, setClientSecret] = useState("");
const [busy, setBusy] = useState(false);
@@ -632,7 +627,6 @@ export function GitIntegrationModal(
}
setHost(newHostValue);
- setRedirectURI(callbackUrl(newHostValue));
setErrorMessage(undefined);
}
};
diff --git a/components/ee/agent-smith/leeway.Dockerfile b/components/ee/agent-smith/leeway.Dockerfile
index 8ef77a703bb9d3..fd6b7a513ef8e6 100644
--- a/components/ee/agent-smith/leeway.Dockerfile
+++ b/components/ee/agent-smith/leeway.Dockerfile
@@ -4,7 +4,7 @@
-FROM cgr.dev/chainguard/wolfi-base:latest@sha256:490977f0fd3d8596d173839dbb314153797312553b43f6a24b0e341cf2e8d473
+FROM cgr.dev/chainguard/wolfi-base:latest@sha256:5dcb7597e50978fc9dea77d96665bcd47ab0600386710c6e8dab35adf1102122
RUN apk add --no-cache git bash ca-certificates
COPY components-ee-agent-smith--app/agent-smith /app/
diff --git a/components/ide-metrics/leeway.Dockerfile b/components/ide-metrics/leeway.Dockerfile
index 2049862165a369..538dbbd6155a4b 100644
--- a/components/ide-metrics/leeway.Dockerfile
+++ b/components/ide-metrics/leeway.Dockerfile
@@ -2,7 +2,7 @@
# Licensed under the GNU Affero General Public License (AGPL).
# See License.AGPL.txt in the project root for license information.
-FROM cgr.dev/chainguard/wolfi-base:latest@sha256:490977f0fd3d8596d173839dbb314153797312553b43f6a24b0e341cf2e8d473
+FROM cgr.dev/chainguard/wolfi-base:latest@sha256:5dcb7597e50978fc9dea77d96665bcd47ab0600386710c6e8dab35adf1102122
# Ensure latest packages are present, like security updates.
RUN apk upgrade --no-cache \
diff --git a/components/ide-proxy/Dockerfile b/components/ide-proxy/Dockerfile
index 0928bed2b76165..10ba37508e64c6 100644
--- a/components/ide-proxy/Dockerfile
+++ b/components/ide-proxy/Dockerfile
@@ -2,7 +2,7 @@
# Licensed under the GNU Affero General Public License (AGPL).
# See License.AGPL.txt in the project root for license information.
-FROM cgr.dev/chainguard/wolfi-base:latest@sha256:490977f0fd3d8596d173839dbb314153797312553b43f6a24b0e341cf2e8d473 as compress
+FROM cgr.dev/chainguard/wolfi-base:latest@sha256:5dcb7597e50978fc9dea77d96665bcd47ab0600386710c6e8dab35adf1102122 as compress
RUN apk add brotli gzip
diff --git a/components/ide-service/leeway.Dockerfile b/components/ide-service/leeway.Dockerfile
index a8c3efd5e3091a..8f964ff41e67ba 100644
--- a/components/ide-service/leeway.Dockerfile
+++ b/components/ide-service/leeway.Dockerfile
@@ -2,7 +2,7 @@
# Licensed under the GNU Affero General Public License (AGPL).
# See License.AGPL.txt in the project root for license information.
-FROM cgr.dev/chainguard/wolfi-base:latest@sha256:490977f0fd3d8596d173839dbb314153797312553b43f6a24b0e341cf2e8d473
+FROM cgr.dev/chainguard/wolfi-base:latest@sha256:5dcb7597e50978fc9dea77d96665bcd47ab0600386710c6e8dab35adf1102122
# Ensure latest packages are present, like security updates.
RUN apk upgrade --no-cache \
diff --git a/components/ide/jetbrains/backend-plugin/leeway.Dockerfile b/components/ide/jetbrains/backend-plugin/leeway.Dockerfile
index 3d90a059b1d819..7b727cc45a29a0 100644
--- a/components/ide/jetbrains/backend-plugin/leeway.Dockerfile
+++ b/components/ide/jetbrains/backend-plugin/leeway.Dockerfile
@@ -2,11 +2,11 @@
# Licensed under the GNU Affero General Public License (AGPL).
# See License.AGPL.txt in the project root for license information.
-FROM cgr.dev/chainguard/wolfi-base:latest@sha256:490977f0fd3d8596d173839dbb314153797312553b43f6a24b0e341cf2e8d473 as base_builder
+FROM cgr.dev/chainguard/wolfi-base:latest@sha256:5dcb7597e50978fc9dea77d96665bcd47ab0600386710c6e8dab35adf1102122 as base_builder
RUN mkdir /ide-desktop-plugins
# for debugging
-# FROM cgr.dev/chainguard/wolfi-base:latest@sha256:490977f0fd3d8596d173839dbb314153797312553b43f6a24b0e341cf2e8d473
+# FROM cgr.dev/chainguard/wolfi-base:latest@sha256:5dcb7597e50978fc9dea77d96665bcd47ab0600386710c6e8dab35adf1102122
FROM scratch
ARG JETBRAINS_BACKEND_QUALIFIER
# ensures right permissions for /ide-desktop-plugins
diff --git a/components/ide/jetbrains/image/leeway.Dockerfile b/components/ide/jetbrains/image/leeway.Dockerfile
index 220c026aed6740..4de82615f7bca9 100644
--- a/components/ide/jetbrains/image/leeway.Dockerfile
+++ b/components/ide/jetbrains/image/leeway.Dockerfile
@@ -2,11 +2,11 @@
# Licensed under the GNU Affero General Public License (AGPL).
# See License.AGPL.txt in the project root for license information.
-FROM cgr.dev/chainguard/wolfi-base:latest@sha256:490977f0fd3d8596d173839dbb314153797312553b43f6a24b0e341cf2e8d473 as base_builder
+FROM cgr.dev/chainguard/wolfi-base:latest@sha256:5dcb7597e50978fc9dea77d96665bcd47ab0600386710c6e8dab35adf1102122 as base_builder
RUN mkdir /ide-desktop
# for debugging
-# FROM cgr.dev/chainguard/wolfi-base:latest@sha256:490977f0fd3d8596d173839dbb314153797312553b43f6a24b0e341cf2e8d473
+# FROM cgr.dev/chainguard/wolfi-base:latest@sha256:5dcb7597e50978fc9dea77d96665bcd47ab0600386710c6e8dab35adf1102122
FROM scratch
ARG JETBRAINS_DOWNLOAD_QUALIFIER
ARG JETBRAINS_BACKEND_QUALIFIER
diff --git a/components/ide/jetbrains/launcher/leeway.Dockerfile b/components/ide/jetbrains/launcher/leeway.Dockerfile
index 7df86b5179633b..031ffaa9086dc2 100644
--- a/components/ide/jetbrains/launcher/leeway.Dockerfile
+++ b/components/ide/jetbrains/launcher/leeway.Dockerfile
@@ -2,11 +2,11 @@
# Licensed under the GNU Affero General Public License (AGPL).
# See License.AGPL.txt in the project root for license information.
-FROM cgr.dev/chainguard/wolfi-base:latest@sha256:490977f0fd3d8596d173839dbb314153797312553b43f6a24b0e341cf2e8d473 as base_builder
+FROM cgr.dev/chainguard/wolfi-base:latest@sha256:5dcb7597e50978fc9dea77d96665bcd47ab0600386710c6e8dab35adf1102122 as base_builder
RUN mkdir /ide-desktop
# for debugging
-# FROM cgr.dev/chainguard/wolfi-base:latest@sha256:490977f0fd3d8596d173839dbb314153797312553b43f6a24b0e341cf2e8d473
+# FROM cgr.dev/chainguard/wolfi-base:latest@sha256:5dcb7597e50978fc9dea77d96665bcd47ab0600386710c6e8dab35adf1102122
FROM scratch
ARG JETBRAINS_BACKEND_VERSION
# ensures right permissions for /ide-desktop
diff --git a/components/image-builder-mk3/leeway.Dockerfile b/components/image-builder-mk3/leeway.Dockerfile
index 1f8cc24bcdcdb8..2abe5a2998ae79 100644
--- a/components/image-builder-mk3/leeway.Dockerfile
+++ b/components/image-builder-mk3/leeway.Dockerfile
@@ -2,7 +2,7 @@
# Licensed under the GNU Affero General Public License (AGPL).
# See License.AGPL.txt in the project root for license information.
-FROM cgr.dev/chainguard/wolfi-base:latest@sha256:490977f0fd3d8596d173839dbb314153797312553b43f6a24b0e341cf2e8d473
+FROM cgr.dev/chainguard/wolfi-base:latest@sha256:5dcb7597e50978fc9dea77d96665bcd47ab0600386710c6e8dab35adf1102122
# Ensure latest packages are present, like security updates.
RUN apk upgrade --no-cache \
diff --git a/components/installation-telemetry/leeway.Dockerfile b/components/installation-telemetry/leeway.Dockerfile
index 131dc4fd2e54d0..25f9f54bc5cc29 100644
--- a/components/installation-telemetry/leeway.Dockerfile
+++ b/components/installation-telemetry/leeway.Dockerfile
@@ -2,7 +2,7 @@
# Licensed under the GNU Affero General Public License (AGPL).
# See License.AGPL.txt in the project root for license information.
-FROM cgr.dev/chainguard/wolfi-base:latest@sha256:490977f0fd3d8596d173839dbb314153797312553b43f6a24b0e341cf2e8d473
+FROM cgr.dev/chainguard/wolfi-base:latest@sha256:5dcb7597e50978fc9dea77d96665bcd47ab0600386710c6e8dab35adf1102122
COPY components-installation-telemetry--app/installation-telemetry /app/installation-telemetry
ENTRYPOINT [ "/app/installation-telemetry" ]
CMD [ "help" ]
diff --git a/components/leeway.Dockerfile b/components/leeway.Dockerfile
index 90321e291d0ab9..01c76a838b17fd 100644
--- a/components/leeway.Dockerfile
+++ b/components/leeway.Dockerfile
@@ -2,5 +2,5 @@
# Licensed under the GNU Affero General Public License (AGPL).
# See License.AGPL.txt in the project root for license information.
-FROM cgr.dev/chainguard/wolfi-base:latest@sha256:490977f0fd3d8596d173839dbb314153797312553b43f6a24b0e341cf2e8d473
+FROM cgr.dev/chainguard/wolfi-base:latest@sha256:5dcb7597e50978fc9dea77d96665bcd47ab0600386710c6e8dab35adf1102122
COPY components--all-docker/versions.yaml components--all-docker/provenance-bundle.jsonl /
diff --git a/components/local-app/leeway.Dockerfile b/components/local-app/leeway.Dockerfile
index 0e56aaabbc15b9..6bc5627b6ca68d 100644
--- a/components/local-app/leeway.Dockerfile
+++ b/components/local-app/leeway.Dockerfile
@@ -2,7 +2,7 @@
# Licensed under the GNU Affero General Public License (AGPL).
# See License.AGPL.txt in the project root for license information.
-FROM cgr.dev/chainguard/wolfi-base:latest@sha256:490977f0fd3d8596d173839dbb314153797312553b43f6a24b0e341cf2e8d473
+FROM cgr.dev/chainguard/wolfi-base:latest@sha256:5dcb7597e50978fc9dea77d96665bcd47ab0600386710c6e8dab35adf1102122
WORKDIR /app
COPY components-local-app--app/components-local-app--app-linux-amd64/local-app local-app-linux
diff --git a/components/node-labeler/leeway.Dockerfile b/components/node-labeler/leeway.Dockerfile
index d3c05fc02d1f28..842ead0923c1d8 100644
--- a/components/node-labeler/leeway.Dockerfile
+++ b/components/node-labeler/leeway.Dockerfile
@@ -2,7 +2,7 @@
# Licensed under the GNU Affero General Public License (AGPL).
# See License.AGPL.txt in the project root for license information.
-FROM cgr.dev/chainguard/wolfi-base:latest@sha256:490977f0fd3d8596d173839dbb314153797312553b43f6a24b0e341cf2e8d473
+FROM cgr.dev/chainguard/wolfi-base:latest@sha256:5dcb7597e50978fc9dea77d96665bcd47ab0600386710c6e8dab35adf1102122
COPY components-node-labeler--app/node-labeler /app/node-labeler
diff --git a/components/openvsx-proxy/leeway.Dockerfile b/components/openvsx-proxy/leeway.Dockerfile
index e9536ba580c474..59b3641eafaeb5 100644
--- a/components/openvsx-proxy/leeway.Dockerfile
+++ b/components/openvsx-proxy/leeway.Dockerfile
@@ -2,7 +2,7 @@
# Licensed under the GNU Affero General Public License (AGPL).
# See License.AGPL.txt in the project root for license information.
-FROM cgr.dev/chainguard/wolfi-base:latest@sha256:490977f0fd3d8596d173839dbb314153797312553b43f6a24b0e341cf2e8d473
+FROM cgr.dev/chainguard/wolfi-base:latest@sha256:5dcb7597e50978fc9dea77d96665bcd47ab0600386710c6e8dab35adf1102122
# Ensure latest packages are present, like security updates.
RUN apk upgrade --no-cache \
diff --git a/components/proxy/Dockerfile b/components/proxy/Dockerfile
index edc9c70cb8e214..db634b0996b019 100644
--- a/components/proxy/Dockerfile
+++ b/components/proxy/Dockerfile
@@ -22,7 +22,7 @@ RUN xcaddy build v2.6.3 \
--with github.com/gitpod-io/gitpod/proxy/plugins/sshtunnel=/plugins/sshtunnel \
--with github.com/gitpod-io/gitpod/proxy/plugins/frontend_dev=/plugins/frontend_dev
-FROM cgr.dev/chainguard/wolfi-base:latest@sha256:490977f0fd3d8596d173839dbb314153797312553b43f6a24b0e341cf2e8d473
+FROM cgr.dev/chainguard/wolfi-base:latest@sha256:5dcb7597e50978fc9dea77d96665bcd47ab0600386710c6e8dab35adf1102122
# Ensure latest packages are present, like security updates.
RUN apk upgrade --no-cache \
diff --git a/components/proxy/conf/Caddyfile b/components/proxy/conf/Caddyfile
index 97352e0482d10b..22f7e3cbfd8350 100644
--- a/components/proxy/conf/Caddyfile
+++ b/components/proxy/conf/Caddyfile
@@ -146,6 +146,13 @@
}
}
+# Internal configcat endpoint
+:9547 {
+ handle /configcat* {
+ gitpod.configcat
+ }
+}
+
# public-api
api.{$GITPOD_DOMAIN} {
log {
diff --git a/components/public-api-server/leeway.Dockerfile b/components/public-api-server/leeway.Dockerfile
index cfde6943d0eda0..d4846a6ddd41ee 100644
--- a/components/public-api-server/leeway.Dockerfile
+++ b/components/public-api-server/leeway.Dockerfile
@@ -2,7 +2,7 @@
# Licensed under the GNU Affero General Public License (AGPL).
# See License.AGPL.txt in the project root for license information.
-FROM cgr.dev/chainguard/wolfi-base:latest@sha256:490977f0fd3d8596d173839dbb314153797312553b43f6a24b0e341cf2e8d473
+FROM cgr.dev/chainguard/wolfi-base:latest@sha256:5dcb7597e50978fc9dea77d96665bcd47ab0600386710c6e8dab35adf1102122
# Ensure latest packages are present, like security updates.
RUN apk upgrade --no-cache \
diff --git a/components/registry-facade/leeway.Dockerfile b/components/registry-facade/leeway.Dockerfile
index 6f37cd2f0a0c9c..df09d09e13ea44 100644
--- a/components/registry-facade/leeway.Dockerfile
+++ b/components/registry-facade/leeway.Dockerfile
@@ -2,7 +2,7 @@
# Licensed under the GNU Affero General Public License (AGPL).
# See License.AGPL.txt in the project root for license information.
-FROM cgr.dev/chainguard/wolfi-base:latest@sha256:490977f0fd3d8596d173839dbb314153797312553b43f6a24b0e341cf2e8d473
+FROM cgr.dev/chainguard/wolfi-base:latest@sha256:5dcb7597e50978fc9dea77d96665bcd47ab0600386710c6e8dab35adf1102122
# Ensure latest packages are present, like security updates.
RUN apk upgrade --no-cache \
diff --git a/components/server/src/auth/auth-provider-service.ts b/components/server/src/auth/auth-provider-service.ts
index 69fa54d8c51ad3..2b61dfabe1e13f 100644
--- a/components/server/src/auth/auth-provider-service.ts
+++ b/components/server/src/auth/auth-provider-service.ts
@@ -175,7 +175,7 @@ export class AuthProviderService {
}
const oauth: AuthProviderEntry["oauth"] = {
...urls,
- callBackUrl: this.callbackUrl(host),
+ callBackUrl: this.callbackUrl(),
clientId: clientId!,
clientSecret: clientSecret!,
};
@@ -239,9 +239,8 @@ export class AuthProviderService {
}
}
- protected callbackUrl = (host: string) => {
- const safeHost = host.replace(":", "_");
- const pathname = `/auth/${safeHost}/callback`;
+ protected callbackUrl = () => {
+ const pathname = `/auth/callback`;
return this.config.hostUrl.with({ pathname }).toString();
};
diff --git a/components/server/src/auth/authenticator.ts b/components/server/src/auth/authenticator.ts
index d7032acb8d8286..3df3a4bbe57be9 100644
--- a/components/server/src/auth/authenticator.ts
+++ b/components/server/src/auth/authenticator.ts
@@ -12,7 +12,7 @@ import { log } from "@gitpod/gitpod-protocol/lib/util/logging";
import { TeamDB, UserDB } from "@gitpod/gitpod-db/lib";
import { Config } from "../config";
import { HostContextProvider } from "./host-context-provider";
-import { AuthProvider } from "./auth-provider";
+import { AuthFlow, AuthProvider } from "./auth-provider";
import { TokenProvider } from "../user/token-provider";
import { AuthProviderService } from "./auth-provider-service";
import { UserService } from "../user/user-service";
@@ -72,18 +72,59 @@ export class Authenticator {
});
}
protected async authCallbackHandler(req: express.Request, res: express.Response, next: express.NextFunction) {
- if (req.url.startsWith("/auth/")) {
- const hostContexts = this.hostContextProvider.getAll();
- for (const { authProvider } of hostContexts) {
- const authCallbackPath = authProvider.authCallbackPath;
- if (req.url.startsWith(authCallbackPath)) {
- log.info(`Auth Provider Callback. Path: ${authCallbackPath}`);
- await authProvider.callback(req, res, next);
- return;
+ // Should match:
+ // * /auth/callback
+ // * /auth//callback
+ if (req.path.startsWith("/auth/") && req.path.endsWith("/callback")) {
+ const stateParam = req.query.state;
+ try {
+ const flowState = await this.parseState(`${stateParam}`);
+ const host = flowState.host;
+ if (!host) {
+ throw new Error("Auth flow state is missing 'host' attribute.");
+ }
+ const hostContext = this.hostContextProvider.get(host);
+ if (!hostContext) {
+ throw new Error("No host context found.");
}
+
+ // remember parsed state to be availble in the auth provider implementation
+ req.authFlow = flowState;
+
+ log.info(`Auth Provider Callback. Host: ${host}`);
+ await hostContext.authProvider.callback(req, res, next);
+ } catch (error) {
+ log.error(`Failed to handle callback.`, error, { url: req.url });
}
+ } else {
+ // Otherwise proceed with other handlers
+ return next();
}
- return next();
+ }
+
+ private async parseState(state: string): Promise {
+ // In preview environments, we prepend the current development branch to the state, to allow
+ // our preview proxy to route the Auth callback appropriately.
+ // See https://github.com/gitpod-io/ops/pull/9398/files
+ //
+ // We need to strip the branch out of the state, if it's present
+ if (state.indexOf(",") >= 0) {
+ const [, actualState] = state.split(",", 2);
+ state = actualState;
+ }
+
+ return await this.signInJWT.verify(state as string);
+ }
+
+ private deriveAuthState(state: string): string {
+ // In preview environments, we prepend the current development branch to the state, to allow
+ // our preview proxy to route the Auth callback appropriately.
+ // See https://github.com/gitpod-io/ops/pull/9398/files
+ if (this.config.devBranch) {
+ return `${this.config.devBranch},${state}`;
+ }
+
+ return state;
}
protected async getAuthProviderForHost(host: string): Promise {
@@ -141,7 +182,7 @@ export class Authenticator {
});
// authenticate user
- authProvider.authorize(req, res, next, state);
+ authProvider.authorize(req, res, next, this.deriveAuthState(state));
}
async deauthorize(req: express.Request, res: express.Response, next: express.NextFunction) {
@@ -256,7 +297,7 @@ export class Authenticator {
// authorize Gitpod
log.info(`(doAuthorize) wanted scopes (${override ? "overriding" : "merging"}): ${wantedScopes.join(",")}`);
const state = await this.signInJWT.sign({ host, returnTo, overrideScopes: override });
- authProvider.authorize(req, res, next, state, wantedScopes);
+ authProvider.authorize(req, res, next, this.deriveAuthState(state), wantedScopes);
}
protected mergeScopes(a: string[], b: string[]) {
const set = new Set(a);
diff --git a/components/server/src/auth/generic-auth-provider.ts b/components/server/src/auth/generic-auth-provider.ts
index 90c3c853df27bf..7e4d4c823c71e0 100644
--- a/components/server/src/auth/generic-auth-provider.ts
+++ b/components/server/src/auth/generic-auth-provider.ts
@@ -13,7 +13,7 @@ import { AuthProviderInfo, Identity, Token, User } from "@gitpod/gitpod-protocol
import { log, LogContext } from "@gitpod/gitpod-protocol/lib/util/logging";
import { oauth2tokenCallback, OAuth2 } from "oauth";
import { URL } from "url";
-import { AuthFlow, AuthProvider, AuthUser } from "../auth/auth-provider";
+import { AuthProvider, AuthUser } from "../auth/auth-provider";
import { AuthProviderParams, AuthUserSetup } from "../auth/auth-provider";
import {
AuthException,
@@ -157,7 +157,8 @@ export abstract class GenericAuthProvider implements AuthProvider {
) {
const handler = passport.authenticate(this.getStrategy() as any, {
...this.defaultStrategyOptions,
- ...{ state: this.deriveAuthState(state), scope },
+ state,
+ scope,
});
handler(req, res, next);
@@ -277,14 +278,12 @@ export abstract class GenericAuthProvider implements AuthProvider {
return;
}
- let authFlow: AuthFlow;
- try {
- authFlow = await this.parseState(state as string);
- } catch (error) {
- log.error(cxt, `(${strategyName}) Failed to parse state JWT from request.`, { clientInfo });
- increaseLoginCounter("failed", this.host);
+ const authFlow = request.authFlow;
+ if (!authFlow) {
+ log.error(`(${strategyName}) Auth flow state is missing.`);
- response.redirect(this.getSorryUrl(`OAuth2 error. (${error})`));
+ increaseLoginCounter("failed", this.host);
+ response.redirect(this.getSorryUrl(`Auth flow state is missing.`));
return;
}
@@ -539,12 +538,10 @@ export abstract class GenericAuthProvider implements AuthProvider {
let currentGitpodUser: User | undefined = User.is(req.user) ? req.user : undefined;
let candidate: Identity;
- let authFlow: AuthFlow;
- try {
- authFlow = await this.parseState((req.query.state as string) || "");
- } catch (err) {
- log.error(`(${strategyName}) Failed to extract auth flow from state`, err);
- done(err, undefined);
+ const authFlow = req.authFlow;
+ if (!authFlow) {
+ log.error(`(${strategyName}) Auth flow state is missing.`);
+ done(AuthException.create("authflow-missing", "Auth flow state is missing.", {}), undefined);
return;
}
@@ -784,31 +781,6 @@ export abstract class GenericAuthProvider implements AuthProvider {
}
throw lastError;
};
-
- private deriveAuthState(state: string): string {
- // In preview environments, we prepend the current development branch to the state, to allow
- // our preview proxy to route the Auth callback appropriately.
- // See https://github.com/gitpod-io/ops/pull/9398/files
- if (this.config.devBranch) {
- return `${this.config.devBranch},${state}`;
- }
-
- return state;
- }
-
- private async parseState(state: string): Promise {
- // In preview environments, we prepend the current development branch to the state, to allow
- // our preview proxy to route the Auth callback appropriately.
- // See https://github.com/gitpod-io/ops/pull/9398/files
- //
- // We need to strip the branch out of the state, if it's present
- if (state.indexOf(",") >= 0) {
- const [, actualState] = state.split(",", 2);
- state = actualState;
- }
-
- return await this.signInJWT.verify(state as string);
- }
}
interface VerifyResult {
diff --git a/components/server/src/authorization/checks.ts b/components/server/src/authorization/checks.ts
index e08724a4433001..8e797498579036 100644
--- a/components/server/src/authorization/checks.ts
+++ b/components/server/src/authorization/checks.ts
@@ -31,3 +31,6 @@ export const WriteOrganizationInfo = check("user", "write_info", "organization")
export const ReadOrganizationMembers = check("user", "read_members", "organization");
export const WriteOrganizationMembers = check("user", "write_members", "organization");
+
+export const ReadOrganizationSettings = check("user", "read_settings", "organization");
+export const WriteOrganizationSettings = check("user", "write_settings", "organization");
diff --git a/components/server/src/authorization/definitions.ts b/components/server/src/authorization/definitions.ts
index 546e72eb2312c5..5a54f3001c431d 100644
--- a/components/server/src/authorization/definitions.ts
+++ b/components/server/src/authorization/definitions.ts
@@ -15,11 +15,12 @@ export type ProjectRelation = "org";
export type Relation = OrganizationRelation | ProjectRelation;
export type OrganizationPermission =
- | "membership"
| "read_info"
| "write_info"
| "read_members"
| "write_members"
+ | "read_settings"
+ | "write_settings"
| "create_project";
export type ProjectPermission = "write_info" | "read_info";
export type Permission = OrganizationPermission;
diff --git a/components/server/src/express.ts b/components/server/src/express.ts
index 84a835eda2848d..5589d4d6b13e74 100644
--- a/components/server/src/express.ts
+++ b/components/server/src/express.ts
@@ -5,10 +5,15 @@
*/
import { User as GitpodUser } from "@gitpod/gitpod-protocol";
+import { AuthFlow } from "./auth/auth-provider";
// use declaration merging (https://www.typescriptlang.org/docs/handbook/declaration-merging.html) to augment the standard passport/express definitions
declare global {
namespace Express {
export interface User extends GitpodUser {}
+
+ interface Request {
+ authFlow?: AuthFlow;
+ }
}
}
diff --git a/components/server/src/workspace/gitpod-server-impl.ts b/components/server/src/workspace/gitpod-server-impl.ts
index ade695e2cd1ff1..6c1ef1a63f2858 100644
--- a/components/server/src/workspace/gitpod-server-impl.ts
+++ b/components/server/src/workspace/gitpod-server-impl.ts
@@ -3043,7 +3043,7 @@ export class GitpodServerImpl implements GitpodServerWithTracing, Disposable {
async getOrgSettings(ctx: TraceContextWithSpan, orgId: string): Promise {
const user = await this.checkAndBlockUser("getOrgSettings");
traceAPIParams(ctx, { orgId, userId: user.id });
- await this.guardTeamOperation(orgId, "get", "not_implemented");
+ await this.guardTeamOperation(orgId, "get", "read_settings");
const settings = await this.teamDB.findOrgSettings(orgId);
// TODO: make a default in protocol
return settings ?? { workspaceSharingDisabled: false };
@@ -3056,7 +3056,7 @@ export class GitpodServerImpl implements GitpodServerWithTracing, Disposable {
): Promise {
const user = await this.checkAndBlockUser("updateOrgSettings");
traceAPIParams(ctx, { orgId, userId: user.id });
- await this.guardTeamOperation(orgId, "update", "not_implemented");
+ await this.guardTeamOperation(orgId, "update", "write_settings");
await this.teamDB.setOrgSettings(orgId, settings);
return (await this.teamDB.findOrgSettings(orgId))!;
}
diff --git a/components/service-waiter/leeway.Dockerfile b/components/service-waiter/leeway.Dockerfile
index 2aa1c4da02d018..83203ccc74c0f5 100644
--- a/components/service-waiter/leeway.Dockerfile
+++ b/components/service-waiter/leeway.Dockerfile
@@ -2,7 +2,7 @@
# Licensed under the GNU Affero General Public License (AGPL).
# See License.AGPL.txt in the project root for license information.
-FROM cgr.dev/chainguard/wolfi-base:latest@sha256:490977f0fd3d8596d173839dbb314153797312553b43f6a24b0e341cf2e8d473
+FROM cgr.dev/chainguard/wolfi-base:latest@sha256:5dcb7597e50978fc9dea77d96665bcd47ab0600386710c6e8dab35adf1102122
# Ensure latest packages are present, like security updates.
RUN apk upgrade --no-cache \
diff --git a/components/usage/leeway.Dockerfile b/components/usage/leeway.Dockerfile
index ab0c716f414c81..03075133b75dc3 100644
--- a/components/usage/leeway.Dockerfile
+++ b/components/usage/leeway.Dockerfile
@@ -2,7 +2,7 @@
# Licensed under the GNU Affero General Public License (AGPL).
# See License.AGPL.txt in the project root for license information.
-FROM cgr.dev/chainguard/wolfi-base:latest@sha256:490977f0fd3d8596d173839dbb314153797312553b43f6a24b0e341cf2e8d473
+FROM cgr.dev/chainguard/wolfi-base:latest@sha256:5dcb7597e50978fc9dea77d96665bcd47ab0600386710c6e8dab35adf1102122
# Ensure latest packages are present, like security updates.
RUN apk upgrade --no-cache \
diff --git a/components/ws-daemon/leeway.Dockerfile b/components/ws-daemon/leeway.Dockerfile
index edc6fe2ac0a69b..316d5069a6458f 100644
--- a/components/ws-daemon/leeway.Dockerfile
+++ b/components/ws-daemon/leeway.Dockerfile
@@ -2,7 +2,7 @@
# Licensed under the GNU Affero General Public License (AGPL).
# See License.AGPL.txt in the project root for license information.
-FROM cgr.dev/chainguard/wolfi-base:latest@sha256:490977f0fd3d8596d173839dbb314153797312553b43f6a24b0e341cf2e8d473 as dl
+FROM cgr.dev/chainguard/wolfi-base:latest@sha256:5dcb7597e50978fc9dea77d96665bcd47ab0600386710c6e8dab35adf1102122 as dl
WORKDIR /dl
RUN apk add --no-cache curl file \
&& curl -OsSL https://github.com/opencontainers/runc/releases/download/v1.1.7/runc.amd64 \
diff --git a/components/ws-daemon/seccomp-profile-installer/leeway.Dockerfile b/components/ws-daemon/seccomp-profile-installer/leeway.Dockerfile
index 0fa543e9340306..d79c2fa0fdf790 100644
--- a/components/ws-daemon/seccomp-profile-installer/leeway.Dockerfile
+++ b/components/ws-daemon/seccomp-profile-installer/leeway.Dockerfile
@@ -2,7 +2,7 @@
# Licensed under the GNU Affero General Public License (AGPL).
# See License.AGPL.txt in the project root for license information.
-FROM cgr.dev/chainguard/wolfi-base:latest@sha256:490977f0fd3d8596d173839dbb314153797312553b43f6a24b0e341cf2e8d473
+FROM cgr.dev/chainguard/wolfi-base:latest@sha256:5dcb7597e50978fc9dea77d96665bcd47ab0600386710c6e8dab35adf1102122
# Ensure latest packages are present, like security updates.
RUN apk upgrade --no-cache
diff --git a/components/ws-proxy/leeway.Dockerfile b/components/ws-proxy/leeway.Dockerfile
index 96ed2cb80408d0..105f22aa372ae9 100644
--- a/components/ws-proxy/leeway.Dockerfile
+++ b/components/ws-proxy/leeway.Dockerfile
@@ -2,7 +2,7 @@
# Licensed under the GNU Affero General Public License (AGPL).
# See License.AGPL.txt in the project root for license information.
-FROM cgr.dev/chainguard/wolfi-base:latest@sha256:490977f0fd3d8596d173839dbb314153797312553b43f6a24b0e341cf2e8d473
+FROM cgr.dev/chainguard/wolfi-base:latest@sha256:5dcb7597e50978fc9dea77d96665bcd47ab0600386710c6e8dab35adf1102122
# Ensure latest packages are present, like security updates.
RUN apk upgrade --no-cache \
diff --git a/dev/changelog/leeway.Dockerfile b/dev/changelog/leeway.Dockerfile
index e09f82ce984bdb..9543ec32b5fe06 100644
--- a/dev/changelog/leeway.Dockerfile
+++ b/dev/changelog/leeway.Dockerfile
@@ -2,7 +2,7 @@
# Licensed under the GNU Affero General Public License (AGPL).
# See License.AGPL.txt in the project root for license information.
-FROM cgr.dev/chainguard/wolfi-base:latest@sha256:490977f0fd3d8596d173839dbb314153797312553b43f6a24b0e341cf2e8d473
+FROM cgr.dev/chainguard/wolfi-base:latest@sha256:5dcb7597e50978fc9dea77d96665bcd47ab0600386710c6e8dab35adf1102122
# Ensure latest packages are present, like security updates.
RUN apk upgrade --no-cache \
diff --git a/install/installer/pkg/common/common.go b/install/installer/pkg/common/common.go
index cb46f65bd7beee..36df115023ebab 100644
--- a/install/installer/pkg/common/common.go
+++ b/install/installer/pkg/common/common.go
@@ -431,7 +431,7 @@ func ConfigcatEnv(ctx *RenderContext) []corev1.EnvVar {
},
{
Name: "CONFIGCAT_BASE_URL",
- Value: "https://" + ctx.Config.Domain + "/configcat",
+ Value: ClusterURL("http", ProxyComponent, ctx.Namespace, ProxyConfigcatPort) + "/configcat",
},
}
}
diff --git a/install/installer/pkg/common/constants.go b/install/installer/pkg/common/constants.go
index 81cfae0d129ce0..053621f5d5702f 100644
--- a/install/installer/pkg/common/constants.go
+++ b/install/installer/pkg/common/constants.go
@@ -28,6 +28,7 @@ const (
MinioServiceAPIPort = 9000
MonitoringChart = "monitoring"
ProxyComponent = "proxy"
+ ProxyConfigcatPort = 9547
ProxyContainerHTTPPort = 80
ProxyContainerHTTPName = "http"
ProxyContainerHTTPSPort = 443
@@ -61,6 +62,8 @@ const (
AnnotationConfigChecksum = "gitpod.io/checksum_config"
DatabaseConfigMountPath = "/secrets/database-config"
AuthPKISecretName = "auth-pki"
+ IDEServiceComponent = "ide-service"
+ OpenVSXProxyComponent = "openvsx-proxy"
)
var (
diff --git a/install/installer/pkg/components/ide-service/constants.go b/install/installer/pkg/components/ide-service/constants.go
index f8bd50f7b4d498..95c604fa9c7d35 100644
--- a/install/installer/pkg/components/ide-service/constants.go
+++ b/install/installer/pkg/components/ide-service/constants.go
@@ -4,8 +4,10 @@
package ide_service
+import "github.com/gitpod-io/gitpod/installer/pkg/common"
+
const (
- Component = "ide-service"
+ Component = common.IDEServiceComponent
VolumeConfig = "config"
GRPCPortName = "grpc"
diff --git a/install/installer/pkg/components/openvsx-proxy/constants.go b/install/installer/pkg/components/openvsx-proxy/constants.go
index 6c8755b5be20bc..02d14074a30fe4 100644
--- a/install/installer/pkg/components/openvsx-proxy/constants.go
+++ b/install/installer/pkg/components/openvsx-proxy/constants.go
@@ -4,8 +4,10 @@
package openvsx_proxy
+import "github.com/gitpod-io/gitpod/installer/pkg/common"
+
const (
- Component = "openvsx-proxy"
+ Component = common.OpenVSXProxyComponent
ContainerPort = 8080
ServicePort = 8080
PortName = "http"
diff --git a/install/installer/pkg/components/proxy/constants.go b/install/installer/pkg/components/proxy/constants.go
index 942fedd7a489d8..c9517d1bc3b970 100644
--- a/install/installer/pkg/components/proxy/constants.go
+++ b/install/installer/pkg/components/proxy/constants.go
@@ -24,4 +24,6 @@ const (
RegistryTLSCertSecret = common.RegistryTLSCertSecret
ContainerAnalyticsPort = 9546
ContainerAnalyticsName = "analytics"
+ ContainerConfigcatPort = common.ProxyConfigcatPort
+ ContainerConfigcatName = "configcat"
)
diff --git a/install/installer/pkg/components/proxy/deployment.go b/install/installer/pkg/components/proxy/deployment.go
index 66159efd1eec55..1dcf68d9f367bc 100644
--- a/install/installer/pkg/components/proxy/deployment.go
+++ b/install/installer/pkg/components/proxy/deployment.go
@@ -238,6 +238,9 @@ func deployment(ctx *common.RenderContext) ([]runtime.Object, error) {
}, prometheusPort, {
ContainerPort: ContainerAnalyticsPort,
Name: ContainerAnalyticsName,
+ }, {
+ ContainerPort: ContainerConfigcatPort,
+ Name: ContainerConfigcatName,
}},
SecurityContext: &corev1.SecurityContext{
Privileged: pointer.Bool(false),
diff --git a/install/installer/pkg/components/proxy/networkpolicy.go b/install/installer/pkg/components/proxy/networkpolicy.go
index 63d2ebf6922a80..bb9d49ce05274e 100644
--- a/install/installer/pkg/components/proxy/networkpolicy.go
+++ b/install/installer/pkg/components/proxy/networkpolicy.go
@@ -71,6 +71,36 @@ func networkpolicy(ctx *common.RenderContext) ([]runtime.Object, error) {
"component": common.WSProxyComponent,
}},
}},
+ }, {
+ Ports: []networkingv1.NetworkPolicyPort{{
+ Protocol: common.TCPProtocol,
+ Port: &intstr.IntOrString{IntVal: ContainerConfigcatPort},
+ }},
+ From: []networkingv1.NetworkPolicyPeer{{
+ PodSelector: &metav1.LabelSelector{MatchLabels: map[string]string{
+ "component": common.ServerComponent,
+ }},
+ }, {
+ PodSelector: &metav1.LabelSelector{MatchLabels: map[string]string{
+ "component": common.WSManagerBridgeComponent,
+ }},
+ }, {
+ PodSelector: &metav1.LabelSelector{MatchLabels: map[string]string{
+ "component": common.IDEServiceComponent,
+ }},
+ }, {
+ PodSelector: &metav1.LabelSelector{MatchLabels: map[string]string{
+ "component": common.PublicApiComponent,
+ }},
+ }, {
+ PodSelector: &metav1.LabelSelector{MatchLabels: map[string]string{
+ "component": common.UsageComponent,
+ }},
+ }, {
+ PodSelector: &metav1.LabelSelector{MatchLabels: map[string]string{
+ "component": common.OpenVSXProxyComponent,
+ }},
+ }},
}},
},
}}, nil
diff --git a/install/installer/pkg/components/proxy/service.go b/install/installer/pkg/components/proxy/service.go
index a29417cb60a2a2..d477d20e65e2a4 100644
--- a/install/installer/pkg/components/proxy/service.go
+++ b/install/installer/pkg/components/proxy/service.go
@@ -75,6 +75,11 @@ func service(ctx *common.RenderContext) ([]runtime.Object, error) {
ContainerPort: ContainerAnalyticsPort,
ServicePort: ContainerAnalyticsPort,
},
+ {
+ Name: ContainerConfigcatName,
+ ContainerPort: ContainerConfigcatPort,
+ ServicePort: ContainerConfigcatPort,
+ },
}
if ctx.Config.SSHGatewayHostKey != nil {
ports = append(ports, common.ServicePort{
diff --git a/install/installer/pkg/components/spicedb/data/schema.yaml b/install/installer/pkg/components/spicedb/data/schema.yaml
index fcb43965324242..13fc5bca64d3f2 100644
--- a/install/installer/pkg/components/spicedb/data/schema.yaml
+++ b/install/installer/pkg/components/spicedb/data/schema.yaml
@@ -6,23 +6,26 @@ schema: |-
definition user {}
definition organization {
- // Organization specific roles
- relation owner: user
+ // Every user in an organization is automatically a member
relation member: user
-
- // Membership is the union of all organization specific roles
- permission membership = owner + member
+ // Some users in an organization may additionally have the `owner` role
+ // granting them more privilidges with respect to the organization.
+ relation owner: user
// General operations on organization
- permission read_info = owner + member
+ permission read_info = member + owner
permission write_info = owner
// Operations on Organization's Members
- permission read_members = owner + member
- permission write_members = owner + member
+ permission read_members = member + owner
+ permission write_members = member + owner
// Only owners can create new projects
permission create_project = owner
+
+ // Only owners can change settings
+ permission read_settings = owner
+ permission write_settings = owner
}
definition project {
@@ -33,8 +36,8 @@ schema: |-
relation editor: user
// A subject is a viewer, if:
// * the user is directly assigned as a viewer
- // * the project has granted access to everyone who has membership in an organization
- relation viewer: user | organization#membership
+ // * the project has granted access to everyone in an organization
+ relation viewer: user | organization#member
// Project can be modified by:
// * Organization owners
@@ -49,6 +52,7 @@ schema: |-
# relationships to be used for assertions & validation
relationships: |-
// We have an organization org_1, which has some members & owners
+ organization:org_1#member@user:user_0
organization:org_1#owner@user:user_0
organization:org_1#member@user:user_1
organization:org_1#member@user:user_2
@@ -56,10 +60,11 @@ relationships: |-
// org_1 has a project
project:project_1#org@organization:org_1
// project_1 can be accessed by anyone in the organization - it's visibility is public
- project:project_1#viewer@organization:org_1#membership
+ project:project_1#viewer@organization:org_1#member
// We have another organization org_2, which has some users, some of which are also members of org_1
+ organization:org_2#member@user:user_0
organization:org_2#owner@user:user_0
organization:org_2#member@user:user_1
organization:org_2#member@user:user_10
@@ -73,36 +78,36 @@ relationships: |-
# assertions should assert that a particular permission holds, or not
assertions:
assertTrue:
- - "organization:org_1#read_info@user:user_0"
+ - organization:org_1#read_info@user:user_0
# user 0 can edit project_0, because they are the Org Owner
- - "project:project_1#write_info@user:user_0"
-
+ - project:project_1#write_info@user:user_0
+ - organization:org_1#write_settings@user:user_0
assertFalse:
# user 10 cannot access project_1
- - "project:project_1#read_info@user:user_10"
- - "project:project_2#write_info@user:user_10"
-
+ - project:project_1#read_info@user:user_10
+ - project:project_2#write_info@user:user_10
# non-member/owner cannot access organization
- - "organization:org1#read_info@user:user3"
- - "organization:org1#write_info@user:user3"
- - "organization:org1#read_members@user:user3"
- - "organization:org1#write_members@user:user3"
-
+ - organization:org_1#read_info@user:user_3
+ - organization:org_1#write_info@user:user_3
+ - organization:org_1#read_members@user:user_3
+ - organization:org_1#write_members@user:user_3
+ - organization:org_1#write_settings@user:user_1
# validation should assert that a particular relation exists between an entity, and a subject
# validations are not used to assert that a permission exists
validation:
organization:org_1#member:
- - "[user:user_1] is "
- - "[user:user_2] is "
- organization:org_1#membership:
- - "[user:user_0] is "
+ - "[user:user_0] is "
- "[user:user_1] is "
- "[user:user_2] is "
organization:org_1#owner:
- "[user:user_0] is "
- project:project_1#read_info:
- - "[organization:org_1#membership] is "
+ organization:org_1#read_settings:
+ - "[user:user_0] is "
+ organization:org_1#write_settings:
- "[user:user_0] is "
+ project:project_1#read_info:
+ - "[organization:org_1#member] is "
+ - "[user:user_0] is /"
- "[user:user_1] is "
- "[user:user_2] is "
project:project_2#read_info:
diff --git a/test/leeway.Dockerfile b/test/leeway.Dockerfile
index 04d623d7129a82..3cc703c702ace1 100644
--- a/test/leeway.Dockerfile
+++ b/test/leeway.Dockerfile
@@ -2,7 +2,7 @@
# Licensed under the GNU Affero General Public License (AGPL).
# See License.AGPL.txt in the project root for license information.
-FROM cgr.dev/chainguard/wolfi-base:latest@sha256:490977f0fd3d8596d173839dbb314153797312553b43f6a24b0e341cf2e8d473
+FROM cgr.dev/chainguard/wolfi-base:latest@sha256:5dcb7597e50978fc9dea77d96665bcd47ab0600386710c6e8dab35adf1102122
# Ensure latest packages are present, like security updates.
RUN apk upgrade --no-cache \