Skip to content

Commit

Permalink
Merge pull request #535 from Sanofi-IADC/ARM-1276
Browse files Browse the repository at this point in the history
feat: ARM-1276 using reader technical users for Jira Issues APIs
  • Loading branch information
kr1shnadas authored Jul 5, 2023
2 parents 7c210e0 + fbb6f5a commit f7382ad
Show file tree
Hide file tree
Showing 10 changed files with 92 additions and 49 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ jobs:
CPV_CONFLUENCE_BASE_URL: ${{ secrets.CPV_CONFLUENCE_BASE_URL }}
VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
CPV_JIRA_READER_API_USERNAME: ${{ secrets.CPV_JIRA_READER_API_USERNAME }}
CPV_JIRA_READER_API_TOKEN: ${{ secrets.CPV_JIRA_READER_API_TOKEN }}
steps:
- name: Checkout code
uses: actions/checkout@v3
Expand Down
5 changes: 5 additions & 0 deletions src/config/config.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ interface Config {
logging: {
enableLoggerMiddleware: boolean;
};

jiraIssues: {
apiReaderUsername: string;
apiReaderToken: string;
}
}

export default Config;
4 changes: 4 additions & 0 deletions src/config/configuration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,8 @@ export default (): Config => ({
logging: {
enableLoggerMiddleware: process.env.ENABLE_LOGGER_MIDDLEWARE === 'true',
},
jiraIssues: {
apiReaderUsername: process.env.CPV_JIRA_READER_API_USERNAME || '',
apiReaderToken: process.env.CPV_JIRA_READER_API_TOKEN || '',
},
});
4 changes: 4 additions & 0 deletions src/config/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,8 @@ export default (): Config => ({
logging: {
enableLoggerMiddleware: process.env.ENABLE_LOGGER_MIDDLEWARE === 'true',
},
jiraIssues: {
apiReaderUsername: process.env.CPV_JIRA_READER_API_USERNAME,
apiReaderToken: process.env.CPV_JIRA_READER_API_TOKEN,
},
});
89 changes: 47 additions & 42 deletions src/jira/jira.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,18 @@ export class JiraService {

// Default API connection for Jira is the same as for Confluence
constructor(private http: HttpService, private config: ConfigService) {
this.baseUrl = this.config.get('confluence.baseURL');
this.apiUsername = this.config.get('confluence.apiUsername');
this.apiToken = this.config.get('confluence.apiToken');
this.init();
}

private init(component = '') {
if (component !== '' && component === 'jiraIssues') {
this.apiUsername = this.config.get('jiraIssues.apiReaderUsername');
this.apiToken = this.config.get('jiraIssues.apiReaderToken');
} else {
this.baseUrl = this.config.get('confluence.baseURL');
this.apiUsername = this.config.get('confluence.apiUsername');
this.apiToken = this.config.get('confluence.apiToken');
}
}

/**
Expand Down Expand Up @@ -76,6 +85,7 @@ export class JiraService {
fields: string,
startAt = 0,
maxResult = 100,
component = '',
): Promise<any> {
const expand = [
{
Expand All @@ -85,13 +95,18 @@ export class JiraService {
].filter(({ field }) => fields.includes(field))
.map(({ apiExpand }) => apiExpand)
.join(',');
// Load new base URL and credencials if defined a specific connection for Jira as ENV variables
const key = `CPV_JIRA_${server.replace(/\s/, '_')}`;
const baseUrl = process.env[`${key}_BASE_URL`];
if (baseUrl) {
this.baseUrl = baseUrl;
this.apiUsername = process.env[`${key}_API_USERNAME`];
this.apiToken = process.env[`${key}_API_TOKEN`];

if (component !== '') {
this.init(component);
} else {
// Load new base URL and credencials if defined a specific connection for Jira as ENV variables
const key = `CPV_JIRA_${server.replace(/\s/, '_')}`;
const baseUrl = process.env[`${key}_BASE_URL`];
if (baseUrl) {
this.baseUrl = baseUrl;
this.apiUsername = process.env[`${key}_API_USERNAME`];
this.apiToken = process.env[`${key}_API_TOKEN`];
}
}
return firstValueFrom(
this.http.get(
Expand Down Expand Up @@ -122,14 +137,19 @@ export class JiraService {
startAt: number,
maxResults: number,
categoryId,
component = '',
): Promise<AxiosResponse> {
// Load new base URL and credencials if defined a specific connection for Jira as ENV variables
const key = `CPV_JIRA_${server.replace(/\s/, '_')}`;
const baseUrl = process.env[`${key}_BASE_URL`];
if (baseUrl) {
this.baseUrl = baseUrl;
this.apiUsername = process.env[`${key}_API_USERNAME`];
this.apiToken = process.env[`${key}_API_TOKEN`];
if (component !== '') {
this.init(component);
} else {
// Load new base URL and credencials if defined a specific connection for Jira as ENV variables
const key = `CPV_JIRA_${server.replace(/\s/, '_')}`;
const baseUrl = process.env[`${key}_BASE_URL`];
if (baseUrl) {
this.baseUrl = baseUrl;
this.apiUsername = process.env[`${key}_API_USERNAME`];
this.apiToken = process.env[`${key}_API_TOKEN`];
}
}
let params: any = {
startAt,
Expand Down Expand Up @@ -234,11 +254,8 @@ export class JiraService {
* for each issue type screen scheme, a list of the projects that use it
* @return Promise {any}
*/
async findIssueTypeScreenSchemes(projectId: number, isAdmin: boolean): Promise<AxiosResponse> {
if (isAdmin) {
this.apiUsername = process.env.CPV_JIRA_ADMIN_API_USERNAME;
this.apiToken = process.env.CPV_JIRA_ADMIN_API_TOKEN;
}
async findIssueTypeScreenSchemes(projectId: number): Promise<AxiosResponse> {
this.init();
return firstValueFrom(
this.http.get(
`${this.baseUrl}/rest/api/3/issuetypescreenscheme/project?projectId=${projectId}`,
Expand All @@ -263,11 +280,8 @@ export class JiraService {
* @description Returns a paginated list of issue type screen scheme items
* @return Promise {any}
*/
async findIssueTypeScreenSchemeItems(isAdmin: boolean, issueTypeScreenSchemeId: number): Promise<AxiosResponse> {
if (isAdmin) {
this.apiUsername = process.env.CPV_JIRA_ADMIN_API_USERNAME;
this.apiToken = process.env.CPV_JIRA_ADMIN_API_TOKEN;
}
async findIssueTypeScreenSchemeItems(issueTypeScreenSchemeId: number): Promise<AxiosResponse> {
this.init();
return firstValueFrom(
this.http.get(
`${this.baseUrl}/rest/api/3/issuetypescreenscheme/mapping`,
Expand Down Expand Up @@ -296,11 +310,8 @@ export class JiraService {
Only screen schemes used in classic projects are returned.
* @return Promise {any}
*/
async findScreenSchemes(isAdmin: boolean, screenSchemeId: number, maxResults = 100, startAt = 0): Promise<AxiosResponse> {
if (isAdmin) {
this.apiUsername = process.env.CPV_JIRA_ADMIN_API_USERNAME;
this.apiToken = process.env.CPV_JIRA_ADMIN_API_TOKEN;
}
async findScreenSchemes(screenSchemeId: number, maxResults = 100, startAt = 0): Promise<AxiosResponse> {
this.init();
return firstValueFrom(
this.http.get(`${this.baseUrl}/rest/api/3/screenscheme`, {
auth: { username: this.apiUsername, password: this.apiToken },
Expand Down Expand Up @@ -330,11 +341,8 @@ export class JiraService {
* @description Returns the list of tabs for a screen.
* @return Promise {any}
*/
async findScreenTabs(screenId: number, isAdmin: boolean): Promise<AxiosResponse> {
if (isAdmin) {
this.apiUsername = process.env.CPV_JIRA_ADMIN_API_USERNAME;
this.apiToken = process.env.CPV_JIRA_ADMIN_API_TOKEN;
}
async findScreenTabs(screenId: number): Promise<AxiosResponse> {
this.init();
return firstValueFrom(
this.http.get(
`${this.baseUrl}/rest/api/3/screens/${screenId}/tabs`,
Expand All @@ -359,11 +367,8 @@ export class JiraService {
* @description Returns all fields for a screen tab.
* @return Promise {any}
*/
async findScreenTabFields(screenId: number, tabId: number, isAdmin: boolean): Promise<AxiosResponse> {
if (isAdmin) {
this.apiUsername = process.env.CPV_JIRA_ADMIN_API_USERNAME;
this.apiToken = process.env.CPV_JIRA_ADMIN_API_TOKEN;
}
async findScreenTabFields(screenId: number, tabId: number): Promise<AxiosResponse> {
this.init();
return firstValueFrom(
this.http.get(
`${this.baseUrl}/rest/api/3/screens/${screenId}/tabs/${tabId}/fields`,
Expand Down
File renamed without changes.
9 changes: 9 additions & 0 deletions src/proxy-api/dto/SearchProjectIssuesQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,13 @@ export default class SearchProjectIssuesQueryDTO {
@IsInt()
@Type(() => Number)
maxResults: number;

@ApiProperty({
type: String,
description: 'The Component from which this APi is called',
example: 'jiraIssues',
})
@IsOptional()
@IsString()
component: string;
}
9 changes: 9 additions & 0 deletions src/proxy-api/dto/SearchProjectsQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,13 @@ export default class SearchProjectsQueryDTO {
@IsInt()
@Type(() => Number)
categoryId: number;

@ApiProperty({
type: String,
description: 'The Component from which this APi is called',
example: 'jiraIssues',
})
@IsOptional()
@IsString()
component: string;
}
4 changes: 3 additions & 1 deletion src/proxy-api/proxy-api.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
} from './proxy-api.validation.dto';
import { KonviwResults } from './proxy-api.interface';
import SearchProjectIssueTypesWithStatusQueryDTO from './dto/SearchProjectIssueTypesWithStatusQuery';
import GetScreenDetailsDTO from './dto/GetScreenDetails';
import GetScreenDetailsDTO from './dto/GetScreenDetailsQuery';

@ApiTags('proxy-api')
@Controller('api')
Expand Down Expand Up @@ -83,6 +83,7 @@ export class ProxyApiController {
queries.startAt,
queries.maxResults,
queries.categoryId,
queries.component,
);
}

Expand Down Expand Up @@ -119,6 +120,7 @@ export class ProxyApiController {
queries.fields,
queries.startAt,
queries.maxResults,
queries.component,
);
}

Expand Down
15 changes: 9 additions & 6 deletions src/proxy-api/proxy-api.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,13 +153,15 @@ export class ProxyApiService {
startAt: number,
maxResults: number,
categoryId,
component?: string,
): Promise<any> {
const { data }: any = await this.jira.findProjects(
server,
search,
startAt,
maxResults,
categoryId,
component,
);

const parseResults = data.values.map((project: any) => ({
Expand Down Expand Up @@ -240,6 +242,7 @@ export class ProxyApiService {
fields: string,
startAt: number,
maxResults: number,
component?: string,
): Promise<any> {
const {
total, issues,
Expand All @@ -249,6 +252,7 @@ export class ProxyApiService {
fields,
startAt,
maxResults,
component,
);
const parseResults = issues.map((issue: any) => ({
id: issue.id,
Expand Down Expand Up @@ -318,20 +322,19 @@ export class ProxyApiService {
projectId: number,
issueTypeId: number,
): Promise<any> {
const isAdmin = true;
const issueTypeScreenSchemesRes = await this.jira.findIssueTypeScreenSchemes(projectId, isAdmin);
const issueTypeScreenSchemesRes = await this.jira.findIssueTypeScreenSchemes(projectId);
const issueTypeScreenSchemeId = issueTypeScreenSchemesRes.data.values[0]?.issueTypeScreenScheme.id;
if (issueTypeScreenSchemeId) {
const itemsRes = await this.jira.findIssueTypeScreenSchemeItems(isAdmin, issueTypeScreenSchemeId);
const itemsRes = await this.jira.findIssueTypeScreenSchemeItems(issueTypeScreenSchemeId);
const item = itemsRes.data.values.find((value: any) => value.issueTypeId === issueTypeId);
const screenSchemeId = item ? item.screenSchemeId
: (itemsRes.data.values.find((value: any) => value.issueTypeId === 'default').screenSchemeId);
const schemeRes = await this.jira.findScreenSchemes(isAdmin, screenSchemeId);
const schemeRes = await this.jira.findScreenSchemes(screenSchemeId);
const { screens } = schemeRes.data.values[0];
const screenId = screens.view ? screens.view : screens.default;
const tabsRes = await this.jira.findScreenTabs(screenId, isAdmin);
const tabsRes = await this.jira.findScreenTabs(screenId);
const tabId = tabsRes.data[0].id;
const fieldsRes = await this.jira.findScreenTabFields(screenId, tabId, isAdmin);
const fieldsRes = await this.jira.findScreenTabFields(screenId, tabId);
const screenDetails = fieldsRes.data;
return {
screenDetails,
Expand Down

1 comment on commit f7382ad

@vercel
Copy link

@vercel vercel bot commented on f7382ad Jul 5, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

konviw – ./

konviw-git-main-konviw.vercel.app
konviw-six.vercel.app
konviw-konviw.vercel.app

Please sign in to comment.