-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3 from ccims/feature/jira_datacenter_token_strategy
Feature/jira datacenter token strategy
- Loading branch information
Showing
8 changed files
with
208 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,4 +4,4 @@ export class OAuthTokenResponseDto { | |
expires_in: number; | ||
refresh_token?: string; | ||
scope: string; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
188 changes: 188 additions & 0 deletions
188
backend/src/strategies/jira-token-datacenter/jira-token-datacenter.service.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,188 @@ | ||
import { HttpException, HttpStatus, Injectable } from "@nestjs/common"; | ||
import { PerformAuthResult, Strategy, StrategyUpdateAction, StrategyVariable } from "../Strategy"; | ||
import { OAuthAuthorizeServerState } from "src/api-oauth/OAuthAuthorizeServerState"; | ||
import { StrategyInstance } from "src/model/postgres/StrategyInstance.entity"; | ||
import { AuthStateServerData } from "../AuthResult"; | ||
import { Schema } from "jtd"; | ||
import { StrategiesService } from "src/model/services/strategies.service"; | ||
import { StrategyInstanceService } from "src/model/services/strategy-instance.service"; | ||
import { UserLoginData } from "src/model/postgres/UserLoginData.entity"; | ||
import { UserLoginDataService } from "src/model/services/user-login-data.service"; | ||
|
||
@Injectable() | ||
export class JiraTokenDatacenterStrategyService extends Strategy { | ||
constructor( | ||
strategiesService: StrategiesService, | ||
strategyInstanceService: StrategyInstanceService, | ||
private readonly loginDataService: UserLoginDataService, | ||
) { | ||
super("jira-token-datacenter", strategyInstanceService, strategiesService, false, true, false, false, false); | ||
} | ||
|
||
override get instanceConfigSchema(): Record<string, Schema> { | ||
return { | ||
imsTemplatedFieldsFilter: { | ||
properties: { | ||
"root-url": { type: "string" }, | ||
}, | ||
}, | ||
}; | ||
} | ||
|
||
override get acceptsVariables(): StrategyVariable[] { | ||
return [ | ||
{ | ||
name: "token", | ||
displayName: "API token", | ||
type: "password", | ||
}, | ||
]; | ||
} | ||
|
||
override get updateActions(): StrategyUpdateAction[] { | ||
return [ | ||
{ | ||
name: "update-token", | ||
displayName: "Update API token", | ||
variables: [ | ||
{ | ||
name: "token", | ||
displayName: "API token", | ||
type: "password", | ||
}, | ||
], | ||
}, | ||
]; | ||
} | ||
|
||
/** | ||
* Chechs the given config is valid for a jira | ||
* | ||
* Needed parameters | ||
* - imsTemplatedFieldsFilter containing: | ||
* - root-url: The URL of the jira root endpoint, must be provided. | ||
* | ||
* @param instanceConfig The instance config for a jira-token-datacenter strategy instance to check | ||
* @returns The extended config if check successful | ||
*/ | ||
protected override checkAndExtendInstanceConfig(instanceConfig: object): object { | ||
const resultingConfig = instanceConfig; | ||
|
||
if (resultingConfig["imsTemplatedFieldsFilter"]) { | ||
const rootUrl = resultingConfig["imsTemplatedFieldsFilter"]["root-url"]; | ||
if (!rootUrl) { | ||
throw new Error("At least Jira URL must be given in imsTemplatedFieldsFilter"); | ||
} | ||
} else { | ||
throw new Error("At least imsTemplatedFieldsFilter must be given"); | ||
} | ||
|
||
return super.checkAndExtendInstanceConfig(instanceConfig); | ||
} | ||
|
||
override async getSyncDataForLoginData( | ||
loginData: UserLoginData, | ||
): Promise<{ token: string | null; [key: string]: any }> { | ||
return { token: loginData.data["apiToken"] ?? null, type: "PAT" }; | ||
} | ||
|
||
override getImsUserTemplatedValuesForLoginData(loginData: UserLoginData): object { | ||
return { | ||
jira_id: loginData.data["jira_id"], | ||
username: loginData.data["username"], | ||
displayName: loginData.data["displayName"], | ||
email: loginData.data["email"], | ||
}; | ||
} | ||
|
||
override getLoginDataDataForImsUserTemplatedFields(imsUser: object): object | Promise<object> { | ||
return { | ||
jira_id: imsUser["jira_id"], | ||
}; | ||
} | ||
|
||
override async getLoginDataDescription(loginData: UserLoginData): Promise<string> { | ||
return loginData.data?.username || loginData.data?.email; | ||
} | ||
|
||
override getCensoredInstanceConfig(instance: StrategyInstance): object { | ||
return { | ||
imsTemplatedFieldsFilter: instance.instanceConfig["imsTemplatedFieldsFilter"], | ||
}; | ||
} | ||
|
||
private async getUserData( | ||
token: string, | ||
strategyInstance: StrategyInstance, | ||
): Promise<{ | ||
jira_id: string; | ||
username: string; | ||
displayName: string; | ||
email?: string; | ||
} | null> { | ||
const response = await fetch( | ||
new URL("/rest/api/2/myself", strategyInstance.instanceConfig["imsTemplatedFieldsFilter"]["root-url"]), | ||
{ | ||
method: "GET", | ||
headers: { | ||
Authorization: `Bearer ${token}`, | ||
Accept: "application/json", | ||
}, | ||
}, | ||
); | ||
|
||
if (!response.ok) { | ||
return null; | ||
} | ||
|
||
const userData = await response.json(); | ||
|
||
return { | ||
jira_id: userData.key, | ||
username: userData.name, | ||
displayName: userData.displayName, | ||
email: userData.emailAddress, | ||
}; | ||
} | ||
|
||
override async performAuth( | ||
strategyInstance: StrategyInstance, | ||
state: (AuthStateServerData & OAuthAuthorizeServerState) | undefined, | ||
req: any, | ||
res: any, | ||
): Promise<PerformAuthResult> { | ||
const token = req.query["token"]; | ||
|
||
const userLoginData = await this.getUserData(token, strategyInstance); | ||
if (userLoginData == null) { | ||
return { result: null, returnedState: {}, info: { message: "Token invalid" } }; | ||
} | ||
|
||
return { | ||
result: { | ||
dataActiveLogin: {}, | ||
dataUserLoginData: userLoginData, | ||
mayRegister: true, | ||
}, | ||
returnedState: {}, | ||
info: {}, | ||
}; | ||
} | ||
|
||
override async handleAction(loginData: UserLoginData, name: string, data: Record<string, any>): Promise<void> { | ||
if (name === "update-token") { | ||
const apiToken = data["token"]; | ||
const userLoginData = await this.getUserData(apiToken, await loginData.strategyInstance); | ||
if (userLoginData == null) { | ||
throw new HttpException("Token invalid", HttpStatus.BAD_REQUEST); | ||
} | ||
if (loginData.data["jira_id"] !== userLoginData.jira_id) { | ||
throw new HttpException("Token does not match the user", HttpStatus.BAD_REQUEST); | ||
} | ||
loginData.data["apiToken"] = apiToken; | ||
this.loginDataService.save(loginData); | ||
} else { | ||
throw new HttpException("Unknown action", HttpStatus.BAD_REQUEST); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters