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

[ID-1462] add OAuth support #163

Merged
merged 36 commits into from
Jul 10, 2024
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
45f590f
wip
pavelefros Dec 19, 2023
60c47da
merge master
pavelefros Dec 20, 2023
a59be53
add OAuth support with device code flow
pavelefros Dec 21, 2023
bce0e91
fix refreshing profile
pavelefros Dec 21, 2023
3f3d5a0
update documentation
pavelefros Dec 21, 2023
42c8e1f
small refactorings
pavelefros Dec 21, 2023
874f0d2
fix format
pavelefros Dec 21, 2023
c6329a2
fix tests
pavelefros Dec 21, 2023
67eac80
add support for OAuth Client Credentials
pavelefros Dec 21, 2023
c9042f8
add action-engine scope
pavelefros Dec 22, 2023
8b4f324
save scopes for client_credentials profile for compatibility
pavelefros Jan 3, 2024
49cbde9
improve error handling
pavelefros Jan 3, 2024
35f2448
Merge branch 'master' into ID-1462-add-OAuth-support
pavelefros Feb 6, 2024
2c88d37
Merge branch 'master' into ID-1462-add-OAuth-support
pavelefros Feb 23, 2024
ccc9d15
update scopes
pavelefros Feb 23, 2024
65660e2
Merge branch 'master' into ID-1462-add-OAuth-support
pavelefros Mar 6, 2024
b9ad39c
Merge branch 'master' into ID-1462-add-OAuth-support
pavelefros Mar 18, 2024
059e84a
use specific scopes for device code and client credentials
pavelefros Mar 19, 2024
2759b5d
auto-detect client authentication method
pavelefros Mar 19, 2024
386d203
fix base url in analysis-bookmarks.manager.ts
pavelefros Mar 19, 2024
857ee85
clean up objective command and related
pavelefros Mar 20, 2024
a4971d4
remove transformation-center scopes
pavelefros Mar 20, 2024
e1d0a47
remove unused widget-sourcemaps command and related
pavelefros Mar 21, 2024
056a4a8
update DOCUMENTATION.md
pavelefros Mar 22, 2024
8b716de
remove datadog dependency and tracing.ts
pavelefros Apr 2, 2024
59207f1
add missing uuid and types
pavelefros Apr 2, 2024
3627448
Revert "add missing uuid and types"
pavelefros Apr 4, 2024
415a8e7
Revert "remove datadog dependency and tracing.ts"
pavelefros Apr 4, 2024
e5dc115
merge master
pavelefros Jun 4, 2024
b266d65
increase minor version
pavelefros Jun 27, 2024
7626d5f
add link to OAuth documentation
pavelefros Jun 27, 2024
edbcae3
add constants
pavelefros Jun 27, 2024
b27d44f
Merge branch 'master' into ID-1462-add-OAuth-support
pavelefros Jun 27, 2024
e668958
fix authorizeProfile with Keys
pavelefros Jul 3, 2024
eab2ec5
backwards compatibility
pavelefros Jul 5, 2024
f89fe2a
fix skillmanager base_url
pavelefros Jul 9, 2024
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
20 changes: 19 additions & 1 deletion DOCUMENTATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,25 @@ your profiles by running the ***content-cli profile list*** command.
| Note: Please do not use blanks in profile names |
|-------------------------------------------------|

#### API Token
#### Profile Types
You can create profiles of two types: using OAuth (Device Code
or Client Credentials) or using API Tokens (Application Key / API Key):

##### OAuth

OAuth supports with two grant types: Device Code & Client Credentials.

With Device Code, creating the profile will trigger an authorization flow
(using the OAuth 2.0 Device code). You will be prompted to follow an authorization
link where you must authorize the **Content CLI** to be able to access the EMS environment
on your behalf.

With Client Credentials, you need to provide the credentials (Client ID, Client Secret) configured for your OAuth client.
You can create and configure an OAuth clients in the `Admin & Settings` section of your EMS account, under `Applications`.
The OAuth client needs to have the following scopes configured: studio, integration.data-pools, action-engine.projects.
After creating an OAuth client, you should assign it the permissions necessary for the respective commands.
pavelefros marked this conversation as resolved.
Show resolved Hide resolved

##### API Token

You can choose between two different options when asked for an API token.
The first option is to use an API key, which identifies the user that created
Expand Down
4 changes: 3 additions & 1 deletion package.json
pavelefros marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,13 @@
"test": "jest"
},
"dependencies": {
"@datadog/datadog-ci": "^0.17.12",
"adm-zip": "^0.4.14",
"axios": "1.6.2",
"commander": "^6.0.0",
"form-data": "4.0.0",
"openid-client": "^5.6.1",
pavelefros marked this conversation as resolved.
Show resolved Hide resolved
"semver": "^7.3.2",
"uuid": "^9.0.1",
"valid-url": "^1.0.9",
"winston": "^3.1.0",
"yaml": "2.2.2"
Expand All @@ -29,6 +30,7 @@
"@types/adm-zip": "^0.4.34",
"@types/jest": "29.5.11",
"@types/node": "20.10.4",
"@types/uuid": "^9.0.8",
"jest": "29.7.0",
"lint-staged": "^9.5.0",
"prettier": "^1.19.1",
Expand Down
15 changes: 0 additions & 15 deletions src/commands/objective.command.ts

This file was deleted.

23 changes: 21 additions & 2 deletions src/commands/profile.command.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { QuestionService } from "../services/question.service";
import { Profile } from "../interfaces/profile.interface";
import { ProfileService } from "../services/profile.service";
import { ProfileValidator } from "../validators/profile.validator";
import { logger } from "../util/logger";
import { FatalError, logger } from "../util/logger";

export class ProfileCommand {
private profileService = new ProfileService();
Expand All @@ -11,8 +11,27 @@ export class ProfileCommand {
const profile: Profile = {} as Profile;
profile.name = await QuestionService.ask("Name of the profile: ");
profile.team = await QuestionService.ask("Your team (please provide the full url): ");
profile.apiToken = await QuestionService.ask("Your api token: ");
const type = await QuestionService.ask("Profile type: OAuth Device Code (1), OAuth Client Credentials (2) or Application Key / API Key (3): " );
switch (type) {
case "1":
profile.type = "Device Code";
break;
case "2":
profile.type = "Client Credentials";
profile.clientId = await QuestionService.ask("Your client id: ");
profile.clientSecret = await QuestionService.ask("Your client secret: ");
break;
case "3":
profile.type = "Key";
profile.apiToken = await QuestionService.ask("Your api token: ");
break;
default:
logger.error(new FatalError("Invalid type"));
break;
}
profile.authenticationType = await ProfileValidator.validateProfile(profile);
await this.profileService.authorizeProfile(profile);

this.profileService.storeProfile(profile);
if (setAsDefault) {
await this.makeDefaultProfile(profile.name);
Expand Down
9 changes: 0 additions & 9 deletions src/commands/widget-sourcemaps.command.ts

This file was deleted.

16 changes: 0 additions & 16 deletions src/content-cli-pull.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { AnalysisCommand } from "./commands/analysis.command";
import { SkillCommand } from "./commands/skill.command";
import { ObjectiveCommand } from "./commands/objective.command";
import { DataPoolCommand } from "./commands/data-pool.command";
import { AssetCommand } from "./commands/asset.command";
import { PackageCommand } from "./commands/package.command";
Expand Down Expand Up @@ -55,20 +54,6 @@ class Pull {
return program;
}

public static objective(program: CommanderStatic): CommanderStatic {
program
.command("objective")
.description("Command to pull an objective")
.option("-p, --profile <profile>", "Profile which you want to use to pull the objective")
.requiredOption("--id <id>", "Id of the objective you want to pull")
.action(async cmd => {
await new ObjectiveCommand().pullObjective(cmd.profile, cmd.id);
process.exit();
});

return program;
}

public static dataPool(program: CommanderStatic): CommanderStatic {
program
.command("data-pool")
Expand Down Expand Up @@ -118,7 +103,6 @@ class Pull {
Pull.analysis(commander);
Pull.analysisBookmarks(commander);
Pull.skill(commander);
Pull.objective(commander);
Pull.dataPool(commander);
Pull.asset(commander);
Pull.package(commander);
Expand Down
14 changes: 0 additions & 14 deletions src/content-cli-push.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { DataPoolCommand } from "./commands/data-pool.command";
import { AssetCommand } from "./commands/asset.command";
import { PackageCommand } from "./commands/package.command";
import { CTPCommand } from "./commands/ctp.command";
import { WidgetSourcemapsCommand } from "./commands/widget-sourcemaps.command";
import { AnalysisBookmarksCommand } from "./commands/analysis-bookmarks.command";
import { execSync } from "child_process";
import { GracefulError, logger } from "./util/logger";
Expand Down Expand Up @@ -134,18 +133,6 @@ class Push {
return program;
}

public static widgetSourcemaps(program: CommanderStatic): CommanderStatic {
program
.command("widget-sourcemaps")
.description("Command to upload sourcemaps to Datadog RUM")
.action(async () => {
await new WidgetSourcemapsCommand().pushSourceMaps();
process.exit();
});

return program;
}

public static dataPool(program: CommanderStatic): CommanderStatic {
program
.command("data-pool")
Expand Down Expand Up @@ -244,7 +231,6 @@ Push.asset(commander);
Push.assets(commander);
Push.package(commander);
Push.packages(commander);
Push.widgetSourcemaps(commander);

commander.parse(process.argv);

Expand Down
22 changes: 0 additions & 22 deletions src/content/factory/objective-manager.factory.ts

This file was deleted.

24 changes: 0 additions & 24 deletions src/content/factory/widget-sourcemaps-manager.factory.ts

This file was deleted.

2 changes: 1 addition & 1 deletion src/content/manager/analysis-bookmarks.manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import * as fs from "fs";
import * as FormData from "form-data";

export class AnalysisBookmarksManager extends BaseManager {
private static BASE_URL = "/process-analytics/api/bookmarks/";
private static BASE_URL = "/process-analytics/api/bookmarks";
private static ANALYSIS_BOOKMARKS_FILE_PREFIX = "studio_analysis_bookmarks_";

private _analysisId: string;
Expand Down
46 changes: 0 additions & 46 deletions src/content/manager/objective.manager.ts

This file was deleted.

69 changes: 0 additions & 69 deletions src/content/manager/widget-sourcemaps.manager.ts
pavelefros marked this conversation as resolved.
Show resolved Hide resolved

This file was deleted.

9 changes: 9 additions & 0 deletions src/interfaces/profile.interface.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
export interface Profile {
name: string;
team: string;
type: ProfileType;
apiToken: string;
authenticationType: AuthenticationType;
clientId?: string;
clientSecret?: string;
scopes?: string[];
clientAuthenticationMethod?: ClientAuthenticationMethod;
refreshToken?: string;
expiresAt?: number;
}

export type AuthenticationType = "Bearer" | "AppKey";
export type ProfileType = "Device Code" | "Client Credentials" | "Key";
export type ClientAuthenticationMethod = "client_secret_basic" | "client_secret_post";
pavelefros marked this conversation as resolved.
Show resolved Hide resolved
// tslint:disable-next-line:variable-name
export const AuthenticationType: { [key: string]: AuthenticationType } = {
BEARER: "Bearer",
Expand Down
2 changes: 0 additions & 2 deletions src/services/http-client-service.v2.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { AuthenticationType, Profile } from "../interfaces/profile.interface";
import { contextService } from "./context.service";
import { FatalError, logger } from "../util/logger";
import {TracingUtils} from "../util/tracing";
import {VersionUtils} from "../util/version";
import axios, {AxiosResponse, RawAxiosRequestHeaders} from "axios";
import * as FormData from "form-data";
Expand Down Expand Up @@ -188,7 +187,6 @@ class HttpClientServiceV2 {
private buildHeaders(profile: Profile, contentType?: string): RawAxiosRequestHeaders {
return {
...this.buildAuthorizationHeaders(profile, contentType),
...TracingUtils.getTracingHeaders(),
"User-Agent": "content-cli v" + VersionUtils.getCurrentCliVersion()
}
}
Expand Down
Loading
Loading