Skip to content

Commit 3055c58

Browse files
committed
relax param validation on updateAuthProvider
allow to update clientId or clientSecret separately.
1 parent 9316a9a commit 3055c58

File tree

4 files changed

+78
-15
lines changed

4 files changed

+78
-15
lines changed

components/gitpod-protocol/src/protocol.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1577,14 +1577,16 @@ export namespace AuthProviderEntry {
15771577
clientId?: string;
15781578
clientSecret?: string;
15791579
};
1580-
export type UpdateEntry = Pick<AuthProviderEntry, "id" | "ownerId"> &
1581-
Pick<OAuth2Config, "clientId" | "clientSecret">;
1580+
export type UpdateEntry = Pick<AuthProviderEntry, "id" | "ownerId"> & {
1581+
clientId?: string;
1582+
clientSecret?: string;
1583+
};
15821584
export type NewOrgEntry = NewEntry & {
15831585
organizationId: string;
15841586
};
15851587
export type UpdateOrgEntry = Pick<AuthProviderEntry, "id"> & {
1586-
clientId: string;
1587-
clientSecret: string;
1588+
clientId?: string;
1589+
clientSecret?: string;
15881590
organizationId: string;
15891591
};
15901592
export type UpdateOAuth2Config = Pick<OAuth2Config, "clientId" | "clientSecret">;

components/server/src/api/auth-provider-service-api.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ export class AuthProviderServiceAPI implements ServiceImpl<typeof AuthProviderSe
142142
}
143143
const clientId = request.clientId;
144144
const clientSecret = request.clientSecret;
145-
if (!clientId || typeof clientSecret === "undefined") {
145+
if (!clientId && !clientSecret) {
146146
throw new ConnectError("clientId or clientSecret are required", Code.InvalidArgument);
147147
}
148148

components/server/src/auth/auth-provider-service.spec.db.ts

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ describe("AuthProviderService", async () => {
309309
const oauthProperty: keyof AuthProviderEntry = "oauth";
310310
expect(providers[0]).to.not.haveOwnProperty(oauthProperty);
311311
});
312-
it.only("as regular member, should find org-level providers if no built-in providers present", async () => {
312+
it("as regular member, should find org-level providers if no built-in providers present", async () => {
313313
const member = await userService.createUser({
314314
identity: {
315315
authId: "gh-user-2",
@@ -337,7 +337,7 @@ describe("AuthProviderService", async () => {
337337
const oauthProperty: keyof AuthProviderEntry = "oauth";
338338
expect(providers[0]).to.not.haveOwnProperty(oauthProperty);
339339
});
340-
it.only("as regular member, should find only built-in providers if present", async () => {
340+
it("as regular member, should find only built-in providers if present", async () => {
341341
addBuiltInProvider("localhost");
342342

343343
const member = await userService.createUser({
@@ -359,4 +359,65 @@ describe("AuthProviderService", async () => {
359359
expect(providers[0].host).to.be.equal("localhost");
360360
});
361361
});
362+
363+
describe("updateAuthProvider", async () => {
364+
it("should update user-level provider", async () => {
365+
const created = await service.createAuthProviderOfUser(currentUser.id, newEntry());
366+
const someRandomString = String(Date.now());
367+
const updatedClientId = await service.updateAuthProviderOfUser(currentUser.id, {
368+
id: created.id,
369+
ownerId: currentUser.id,
370+
clientId: someRandomString,
371+
});
372+
expect(updatedClientId.oauth?.clientId).to.be.equal(someRandomString);
373+
expect(updatedClientId.oauthRevision).to.be.not.equal(created.oauthRevision);
374+
375+
const updatedClientSecret = await service.updateAuthProviderOfUser(currentUser.id, {
376+
id: created.id,
377+
ownerId: currentUser.id,
378+
clientSecret: String(Date.now()),
379+
});
380+
expect(updatedClientSecret.oauthRevision).to.be.not.equal(updatedClientId.oauthRevision);
381+
});
382+
it("should fail if permissions do not permit", async () => {
383+
const created = await service.createAuthProviderOfUser(currentUser.id, newEntry());
384+
await expectError(
385+
ErrorCodes.NOT_FOUND,
386+
service.updateAuthProviderOfUser("some-stranger", {
387+
id: created.id,
388+
ownerId: currentUser.id,
389+
clientId: "any",
390+
}),
391+
);
392+
});
393+
it("should update org-level provider", async () => {
394+
const created = await service.createOrgAuthProvider(currentUser.id, newOrgEntry());
395+
const someRandomString = String(Date.now());
396+
const updatedClientId = await service.updateOrgAuthProvider(currentUser.id, {
397+
id: created.id,
398+
organizationId: org.id,
399+
clientId: someRandomString,
400+
});
401+
expect(updatedClientId.oauth?.clientId).to.be.equal(someRandomString);
402+
expect(updatedClientId.oauthRevision).to.be.not.equal(created.oauthRevision);
403+
404+
const updatedClientSecret = await service.updateOrgAuthProvider(currentUser.id, {
405+
id: created.id,
406+
organizationId: org.id,
407+
clientSecret: String(Date.now()),
408+
});
409+
expect(updatedClientSecret.oauthRevision).to.be.not.equal(updatedClientId.oauthRevision);
410+
});
411+
it("should fail if org-permissions do not permit", async () => {
412+
const created = await service.createOrgAuthProvider(currentUser.id, newOrgEntry());
413+
await expectError(
414+
ErrorCodes.NOT_FOUND,
415+
service.updateOrgAuthProvider("some-stranger", {
416+
id: created.id,
417+
organizationId: org.id,
418+
clientId: "any",
419+
}),
420+
);
421+
});
422+
});
362423
});

components/server/src/auth/auth-provider-service.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
*/
66

77
import { injectable, inject } from "inversify";
8-
import { AuthProviderEntry as AuthProviderEntry, AuthProviderInfo, User } from "@gitpod/gitpod-protocol";
8+
import { AuthProviderEntry as AuthProviderEntry, AuthProviderInfo, OAuth2Config, User } from "@gitpod/gitpod-protocol";
99
import { AuthProviderParams } from "./auth-provider";
1010
import { AuthProviderEntryDB, TeamDB } from "@gitpod/gitpod-db/lib";
1111
import { Config } from "../config";
@@ -236,10 +236,10 @@ export class AuthProviderService {
236236
}
237237

238238
// update config on demand
239-
const oauth = {
239+
const oauth: OAuth2Config = {
240240
...existing.oauth,
241-
clientId: entry.clientId,
242-
clientSecret: entry.clientSecret || existing.oauth.clientSecret, // FE may send empty ("") if not changed
241+
clientId: entry.clientId || existing.oauth?.clientId,
242+
clientSecret: entry.clientSecret || existing.oauth?.clientSecret, // FE may send empty ("") if not changed
243243
};
244244
const authProvider: AuthProviderEntry = {
245245
...existing,
@@ -297,18 +297,18 @@ export class AuthProviderService {
297297
}
298298

299299
// update config on demand
300-
const oauth = {
300+
const oauth: OAuth2Config = {
301301
...existing.oauth,
302-
clientId: entry.clientId,
303-
clientSecret: entry.clientSecret || existing.oauth.clientSecret, // FE may send empty ("") if not changed
302+
clientId: entry.clientId || existing.oauth?.clientId,
303+
clientSecret: entry.clientSecret || existing.oauth?.clientSecret, // FE may send empty ("") if not changed
304304
};
305305
const authProvider: AuthProviderEntry = {
306306
...existing,
307307
oauth,
308308
status: "pending",
309309
};
310310

311-
const result = await this.authProviderDB.storeAuthProvider(authProvider as AuthProviderEntry, true);
311+
const result = await this.authProviderDB.storeAuthProvider(authProvider, true);
312312
return AuthProviderEntry.redact(result);
313313
}
314314

0 commit comments

Comments
 (0)