Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[wip] maySetTimeout: introduce ogranizationId as argument #18743

Closed
wants to merge 1 commit into from
Closed
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
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,26 @@
import { useQuery } from "@tanstack/react-query";
import { getGitpodService } from "../../service/service";
import { useCurrentUser } from "../../user-context";
import { useCurrentOrg } from "../organizations/orgs-query";

export const useUserMaySetTimeout = () => {
export const useMaySetTimeout = () => {
const user = useCurrentUser();
const org = useCurrentOrg();

return useQuery<boolean>({
queryKey: getUserMaySetTimeoutQueryKey(user?.id ?? ""),
queryKey: getMaySetTimeoutQueryKey(user?.id ?? "", org.data?.id ?? ""),
queryFn: async () => {
if (!user) {
throw new Error("No current user");
}
if (!org.data) {
throw new Error("No current org");
}

return !!(await getGitpodService().server.maySetTimeout());
return !!(await getGitpodService().server.maySetTimeout({ organizationId: org.data.id }));
},
enabled: !!user,
enabled: !!user && !!org.data,
});
};

export const getUserMaySetTimeoutQueryKey = (userId: string) => ["may-set-timeout", { userId }];
export const getMaySetTimeoutQueryKey = (userId: string, orgId: string) => ["may-set-timeout", { userId }, { orgId }];
8 changes: 5 additions & 3 deletions components/dashboard/src/user-settings/Preferences.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { ThemeSelector } from "../components/ThemeSelector";
import Alert from "../components/Alert";
import { Link } from "react-router-dom";
import { Heading2, Heading3, Subheading } from "../components/typography/headings";
import { useUserMaySetTimeout } from "../data/current-user/may-set-timeout-query";
import { useMaySetTimeout } from "../data/current-user/may-set-timeout-query";
import { Button } from "../components/Button";
import SelectIDE from "./SelectIDE";
import { InputField } from "../components/forms/InputField";
Expand All @@ -26,7 +26,7 @@ export type IDEChangedTrackLocation = "workspace_list" | "workspace_start" | "pr
export default function Preferences() {
const { toast } = useToast();
const { user, setUser } = useContext(UserContext);
const maySetTimeout = useUserMaySetTimeout();
const maySetTimeout = useMaySetTimeout();
const updateDotfileRepo = useUpdateCurrentUserDotfileRepoMutation();

const [dotfileRepo, setDotfileRepo] = useState<string>(user?.additionalData?.dotfileRepo || "");
Expand Down Expand Up @@ -57,7 +57,9 @@ export default function Preferences() {
const updatedUser = await getGitpodService().server.getLoggedInUser();
setUser(updatedUser);

toast("Your default workspace timeout was updated.");
toast(
"Your default workspace timeout was updated. Note that this will only affect workspaces in paid organizations.",
);
} catch (e) {
// TODO: Convert this to an error style toast
alert("Cannot set custom workspace timeout: " + e.message);
Expand Down
2 changes: 1 addition & 1 deletion components/gitpod-protocol/src/gitpod-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ export interface GitpodServer extends JsonRpcServer<GitpodClient>, AdminServer,
reportErrorBoundary(url: string, message: string): Promise<void>;

getSupportedWorkspaceClasses(): Promise<SupportedWorkspaceClass[]>;
maySetTimeout(): Promise<boolean>;
maySetTimeout(opts?: { organizationId?: string }): Promise<boolean>;
updateWorkspaceTimeoutSetting(setting: Partial<WorkspaceTimeoutSetting>): Promise<void>;

/**
Expand Down
2 changes: 1 addition & 1 deletion components/server/src/billing/entitlement-service-ubp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ export class EntitlementServiceUBP implements EntitlementService {
}
}

// TODO(gpl) Remove everything below once organizations are fully rolled out
// TODO(gpl) Remove everything below once organizationId is always passed
// This is the old behavior, stemming from our transition to PAYF, where our API did-/doesn't pass organizationId, yet
// Member of paid team?
const teams = await this.teamDB.findTeamsByUser(userId);
Expand Down
9 changes: 0 additions & 9 deletions components/server/src/user/user-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import { CreateUserParams } from "./user-authentication";
import { IAnalyticsWriter } from "@gitpod/gitpod-protocol/lib/analytics";
import { TransactionalContext } from "@gitpod/gitpod-db/lib/typeorm/transactional-db-impl";
import { RelationshipUpdater } from "../authorization/relationship-updater";
import { EntitlementService } from "../billing/entitlement-service";

@injectable()
export class UserService {
Expand All @@ -33,7 +32,6 @@ export class UserService {
@inject(Authorizer) private readonly authorizer: Authorizer,
@inject(IAnalyticsWriter) private readonly analytics: IAnalyticsWriter,
@inject(RelationshipUpdater) private readonly relationshipUpdater: RelationshipUpdater,
@inject(EntitlementService) private readonly entitlementService: EntitlementService,
) {}

public async createUser(
Expand Down Expand Up @@ -144,13 +142,6 @@ export class UserService {
}
}

if (!(await this.entitlementService.maySetTimeout(targetUserId))) {
throw new ApplicationError(
ErrorCodes.PERMISSION_DENIED,
"Configure workspace timeout only available for paid user.",
);
}

const user = await this.findUserById(userId, targetUserId);
AdditionalUserData.set(user, setting);
await this.userDb.updateUserPartial(user);
Expand Down
10 changes: 7 additions & 3 deletions components/server/src/workspace/gitpod-server-impl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -650,12 +650,16 @@ export class GitpodServerImpl implements GitpodServerWithTracing, Disposable {
return updatedUser;
}

public async maySetTimeout(ctx: TraceContext): Promise<boolean> {
const user = await this.checkUser("maySetTimeout");
public async maySetTimeout(ctx: TraceContext, opts?: { organizationId?: string }): Promise<boolean> {
const user = await this.checkUser("maySetTimeout", opts);
await this.guardAccess({ kind: "user", subject: user }, "get");
// TODO(gpl) Remove once organizationId is mandatory
await this.auth.checkPermissionOnUser(user.id, "read_info", user.id);
if (opts?.organizationId) {
await this.auth.checkPermissionOnOrganization(user.id, "read_info", opts.organizationId);
}

return await this.entitlementService.maySetTimeout(user.id);
return await this.entitlementService.maySetTimeout(user.id, opts?.organizationId);
}

public async updateWorkspaceTimeoutSetting(
Expand Down
Loading