Skip to content

Commit

Permalink
[server] move FGA calls into AuthProviderService (#19017)
Browse files Browse the repository at this point in the history
* [server] move FGA calls into AuthProviderService

* split internal upsert method `updateAuthProvider` into create and update
* refactor: move `getAuthProviders` logic from gitpod-server-impl to auth-provider-service
* adding db tests for auth provider server
* use redacted results in service

* Fix typos

* extract helper functions for scopes

* add more tests

* as regular member, should find org-level providers if no built-in providers present
* as regular member, should find only built-in providers if present

---------

Co-authored-by: Huiwen <[email protected]>
  • Loading branch information
AlexTugarev and mustard-mh authored Nov 10, 2023
1 parent 2e3429a commit b2d5018
Show file tree
Hide file tree
Showing 13 changed files with 768 additions and 193 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ export class DBAuthProviderEntry implements AuthProviderEntry {
@Column()
ownerId: string;

@Column()
@Column({
...TypeORM.UUID_COLUMN_TYPE,
default: "",
transformer: Transformer.MAP_EMPTY_STR_TO_UNDEFINED,
})
organizationId?: string;

@Column("varchar")
Expand Down
27 changes: 19 additions & 8 deletions components/gitpod-protocol/src/gitpod-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,16 +81,31 @@ export interface GitpodServer extends JsonRpcServer<GitpodClient>, AdminServer,
updateLoggedInUser(user: Partial<User>): Promise<User>;
sendPhoneNumberVerificationToken(phoneNumber: string): Promise<{ verificationId: string }>;
verifyPhoneNumberVerificationToken(phoneNumber: string, token: string, verificationId: string): Promise<boolean>;
getAuthProviders(): Promise<AuthProviderInfo[]>;
getOwnAuthProviders(): Promise<AuthProviderEntry[]>;
updateOwnAuthProvider(params: GitpodServer.UpdateOwnAuthProviderParams): Promise<AuthProviderEntry>;
deleteOwnAuthProvider(params: GitpodServer.DeleteOwnAuthProviderParams): Promise<void>;
getConfiguration(): Promise<Configuration>;
getToken(query: GitpodServer.GetTokenSearchOptions): Promise<Token | undefined>;
getGitpodTokenScopes(tokenHash: string): Promise<string[]>;
deleteAccount(): Promise<void>;
getClientRegion(): Promise<string | undefined>;

// Auth Provider API
getAuthProviders(): Promise<AuthProviderInfo[]>;
// user-level
getOwnAuthProviders(): Promise<AuthProviderEntry[]>;
updateOwnAuthProvider(params: GitpodServer.UpdateOwnAuthProviderParams): Promise<AuthProviderEntry>;
deleteOwnAuthProvider(params: GitpodServer.DeleteOwnAuthProviderParams): Promise<void>;
// org-level
createOrgAuthProvider(params: GitpodServer.CreateOrgAuthProviderParams): Promise<AuthProviderEntry>;
updateOrgAuthProvider(params: GitpodServer.UpdateOrgAuthProviderParams): Promise<AuthProviderEntry>;
getOrgAuthProviders(params: GitpodServer.GetOrgAuthProviderParams): Promise<AuthProviderEntry[]>;
deleteOrgAuthProvider(params: GitpodServer.DeleteOrgAuthProviderParams): Promise<void>;
// public-api compatibility
/** @deprecated used for public-api compatibility only */
getAuthProvider(id: string): Promise<AuthProviderEntry>;
/** @deprecated used for public-api compatibility only */
deleteAuthProvider(id: string): Promise<void>;
/** @deprecated used for public-api compatibility only */
updateAuthProvider(id: string, update: AuthProviderEntry.UpdateOAuth2Config): Promise<AuthProviderEntry>;

// Query/retrieve workspaces
getWorkspaces(options: GitpodServer.GetWorkspacesOptions): Promise<WorkspaceInfo[]>;
getWorkspaceOwner(workspaceId: string): Promise<UserInfo | undefined>;
Expand Down Expand Up @@ -167,10 +182,6 @@ export interface GitpodServer extends JsonRpcServer<GitpodClient>, AdminServer,
deleteTeam(teamId: string): Promise<void>;
getOrgSettings(orgId: string): Promise<OrganizationSettings>;
updateOrgSettings(teamId: string, settings: Partial<OrganizationSettings>): Promise<OrganizationSettings>;
createOrgAuthProvider(params: GitpodServer.CreateOrgAuthProviderParams): Promise<AuthProviderEntry>;
updateOrgAuthProvider(params: GitpodServer.UpdateOrgAuthProviderParams): Promise<AuthProviderEntry>;
getOrgAuthProviders(params: GitpodServer.GetOrgAuthProviderParams): Promise<AuthProviderEntry[]>;
deleteOrgAuthProvider(params: GitpodServer.DeleteOrgAuthProviderParams): Promise<void>;

getDefaultWorkspaceImage(params: GetDefaultWorkspaceImageParams): Promise<GetDefaultWorkspaceImageResult>;

Expand Down
2 changes: 1 addition & 1 deletion components/gitpod-protocol/src/protocol.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1529,7 +1529,6 @@ export interface AuthProviderInfo {
readonly ownerId?: string;
readonly organizationId?: string;
readonly verified: boolean;
readonly isReadonly?: boolean;
readonly hiddenOnDashboard?: boolean;
readonly disallowLogin?: boolean;
readonly icon?: string;
Expand Down Expand Up @@ -1588,6 +1587,7 @@ export namespace AuthProviderEntry {
clientSecret: string;
organizationId: string;
};
export type UpdateOAuth2Config = Pick<OAuth2Config, "clientId" | "clientSecret">;
export function redact(entry: AuthProviderEntry): AuthProviderEntry {
return {
...entry,
Expand Down
52 changes: 52 additions & 0 deletions components/server/src/auth/auth-provider-scopes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/**
* Copyright (c) 2023 Gitpod GmbH. All rights reserved.
* Licensed under the GNU Affero General Public License (AGPL).
* See License.AGPL.txt in the project root for license information.
*/

import { AuthProviderEntry } from "@gitpod/gitpod-protocol";
import { GitHubScope } from "../github/scopes";
import { GitLabScope } from "../gitlab/scopes";
import { BitbucketOAuthScopes } from "../bitbucket/bitbucket-oauth-scopes";
import { BitbucketServerOAuthScopes } from "../bitbucket-server/bitbucket-server-oauth-scopes";

export function getRequiredScopes(entry: AuthProviderEntry) {
switch (entry.type) {
case "GitHub":
return {
default: GitHubScope.Requirements.DEFAULT,
publicRepo: GitHubScope.Requirements.PUBLIC_REPO,
privateRepo: GitHubScope.Requirements.PRIVATE_REPO,
};
case "GitLab":
return {
default: GitLabScope.Requirements.DEFAULT,
publicRepo: GitLabScope.Requirements.DEFAULT,
privateRepo: GitLabScope.Requirements.REPO,
};
case "Bitbucket":
return {
default: BitbucketOAuthScopes.Requirements.DEFAULT,
publicRepo: BitbucketOAuthScopes.Requirements.DEFAULT,
privateRepo: BitbucketOAuthScopes.Requirements.DEFAULT,
};
case "BitbucketServer":
return {
default: BitbucketServerOAuthScopes.Requirements.DEFAULT,
publicRepo: BitbucketServerOAuthScopes.Requirements.DEFAULT,
privateRepo: BitbucketServerOAuthScopes.Requirements.DEFAULT,
};
}
}
export function getScopesOfProvider(entry: AuthProviderEntry) {
switch (entry.type) {
case "GitHub":
return GitHubScope.All;
case "GitLab":
return GitLabScope.All;
case "Bitbucket":
return BitbucketOAuthScopes.ALL;
case "BitbucketServer":
return BitbucketServerOAuthScopes.ALL;
}
}
Loading

0 comments on commit b2d5018

Please sign in to comment.