From 8009897e38f3b545088a706a5a6e7df94b0c7b09 Mon Sep 17 00:00:00 2001 From: Sayali Gaikawad Date: Mon, 25 Nov 2024 12:44:35 -0800 Subject: [PATCH] Add github auth config Signed-off-by: Sayali Gaikawad --- lib/compute/oidc-config.ts | 186 +++++++++++++++++-------------- test/compute/oidc-config.test.ts | 54 ++++++++- 2 files changed, 152 insertions(+), 88 deletions(-) diff --git a/lib/compute/oidc-config.ts b/lib/compute/oidc-config.ts index 9bb7fc1b..fa4f578b 100644 --- a/lib/compute/oidc-config.ts +++ b/lib/compute/oidc-config.ts @@ -6,99 +6,115 @@ * compatible open source license. */ -export class OidcConfig { - private static readonly adminRolePermissions: string[] = [ - 'Overall/Administer', - 'Overall/Read', - 'Job/Move', - 'Job/Build', - 'Job/Read', - 'Job/Delete', - 'Job/Create', - 'Job/Discover', - 'Job/Cancel', - 'Job/Configure', - 'Job Config History/DeleteEntry', - 'Job/Workspace', - 'Credentials/Delete', - 'Credentials/ManageDomains', - 'Credentials/Update', - 'Credentials/View', - 'Credentials/Create', - 'Manage ownership/Nodes', - 'Manage ownership/Jobs', - 'Agent/Configure', - 'Agent/Create', - 'Agent/Build', - 'Agent/Provision', - 'Agent/Connect', - 'Agent/Delete', - 'Agent/Disconnect', - 'Run/Replay', - 'Run/Delete', - 'Run/Update', - 'View/Delete', - 'View/Read', - 'View/Create', - 'View/Configure', - 'SCM/Tag', - ]; +export class AuthConfig { + private static readonly adminRolePermissions: string[] = [ + 'Overall/Administer', + 'Overall/Read', + 'Job/Move', + 'Job/Build', + 'Job/Read', + 'Job/Delete', + 'Job/Create', + 'Job/Discover', + 'Job/Cancel', + 'Job/Configure', + 'Job Config History/DeleteEntry', + 'Job/Workspace', + 'Credentials/Delete', + 'Credentials/ManageDomains', + 'Credentials/Update', + 'Credentials/View', + 'Credentials/Create', + 'Manage ownership/Nodes', + 'Manage ownership/Jobs', + 'Agent/Configure', + 'Agent/Create', + 'Agent/Build', + 'Agent/Provision', + 'Agent/Connect', + 'Agent/Delete', + 'Agent/Disconnect', + 'Run/Replay', + 'Run/Delete', + 'Run/Update', + 'View/Delete', + 'View/Read', + 'View/Create', + 'View/Configure', + 'SCM/Tag', + ]; - private static readonly readOnlyRolePermissions: string[] = [ - 'Overall/Read', - 'Job/Read', - ]; + private static readonly readOnlyRolePermissions: string[] = [ + 'Overall/Read', + 'Job/Read', + 'View/Read', + ]; - public static addOidcConfigToJenkinsYaml(yamlObject: any, admins?: string[]): any { - const jenkinsYaml: any = yamlObject; - let adminUsers: string[] = ['admin']; - const readOnlyUsers: string[] = ['anonymous']; + public static addOidcConfigToJenkinsYaml(yamlObject: any, authType: string, admins?: string[]): any { + const jenkinsYaml: any = yamlObject; + let adminUsers: string[] = ['admin']; + const readOnlyUsers: string[] = ['anonymous']; - if (admins) { - adminUsers = adminUsers.concat(admins); - } + if (admins) { + adminUsers = adminUsers.concat(admins); + } - const oidcConfig: { [x: string]: any; } = { - oic: { - clientId: 'clientId', - clientSecret: 'clientSecret', - authorizationServerUrl: 'http://localhost', - wellKnownOpenIDConfigurationUrl: 'wellKnownOpenIDConfigurationUrl', - tokenServerUrl: 'tokenServerUrl', - userInfoServerUrl: 'userInfoServerUrl', - disableSslVerification: false, - userNameField: 'sub', - escapeHatchEnabled: false, - logoutFromOpenidProvider: true, - postLogoutRedirectUrl: '', - scopes: 'openid', - escapeHatchSecret: 'random', - }, - }; - const rolesAndPermissions: { [x: string]: any; } = { - roleBased: { - roles: { - global: [{ - entries: adminUsers.map((user) => ({ user })), - name: 'admin', - pattern: '.*', - permissions: OidcConfig.adminRolePermissions - , - }, - { - entries: readOnlyUsers.map((user) => ({ user })), - name: 'read', - pattern: '.*', - permissions: OidcConfig.readOnlyRolePermissions, - }, + const oidcConfig: { [x: string]: any; } = { + oic: { + clientId: 'clientId', + clientSecret: 'clientSecret', + authorizationServerUrl: 'http://localhost', + wellKnownOpenIDConfigurationUrl: 'wellKnownOpenIDConfigurationUrl', + tokenServerUrl: 'tokenServerUrl', + userInfoServerUrl: 'userInfoServerUrl', + disableSslVerification: false, + userNameField: 'sub', + escapeHatchEnabled: false, + logoutFromOpenidProvider: true, + postLogoutRedirectUrl: '', + scopes: 'openid', + escapeHatchSecret: 'random', + }, + }; + + const githubAuthConfig: { [x: string]: any; } = { + github: { + githubWebUri: 'https://github.com', + githubApiUri: 'https://api.github.com', + clientID: 'clientID', + clientSecret: 'clientSecret', + oauthScopes: 'read:org,user:email', + }, + }; - ], + const rolesAndPermissions: { [x: string]: any; } = { + roleBased: { + roles: { + global: [{ + entries: adminUsers.map((user) => ({ user })), + name: 'admin', + pattern: '.*', + permissions: AuthConfig.adminRolePermissions + , }, + { + entries: readOnlyUsers.map((user) => ({ user })), + name: 'read', + pattern: '.*', + permissions: AuthConfig.readOnlyRolePermissions, + }, + ], }, - }; + }, + }; + + jenkinsYaml.jenkins.authorizationStrategy = rolesAndPermissions; - jenkinsYaml.jenkins.authorizationStrategy = rolesAndPermissions; + if (authType === 'github') { + jenkinsYaml.jenkins.securityRealm = githubAuthConfig; + } else { jenkinsYaml.jenkins.securityRealm = oidcConfig; - return jenkinsYaml; } + return jenkinsYaml; + } } diff --git a/test/compute/oidc-config.test.ts b/test/compute/oidc-config.test.ts index 80207d95..754df0ed 100644 --- a/test/compute/oidc-config.test.ts +++ b/test/compute/oidc-config.test.ts @@ -9,9 +9,9 @@ import { readFileSync } from 'fs'; import { load } from 'js-yaml'; import { JenkinsMainNode } from '../../lib/compute/jenkins-main-node'; -import { OidcConfig } from '../../lib/compute/oidc-config'; +import { AuthConfig } from '../../lib/compute/auth-config'; -describe('JenkinsMainNode Config Elements', () => { +describe('Test authType OIDC', () => { // WHEN const testYaml = 'test/data/jenkins.yaml'; @@ -32,7 +32,7 @@ describe('JenkinsMainNode Config Elements', () => { }; const admins = ['admin1', 'admin2']; const jenkinsYaml = load(readFileSync(JenkinsMainNode.BASE_JENKINS_YAML_PATH, 'utf-8')); - OidcConfig.addOidcConfigToJenkinsYaml(jenkinsYaml, admins); + AuthConfig.addOidcConfigToJenkinsYaml(jenkinsYaml, 'oidc', admins); const yml: any = load(readFileSync(testYaml, 'utf-8')); // THEN @@ -46,3 +46,51 @@ describe('JenkinsMainNode Config Elements', () => { expect(adminRole).toEqual(['admin', 'admin1', 'admin2']); }); }); + +describe('Test authType github', () => { + // WHEN + const testYaml = 'test/data/github_auth.yaml'; + const admins = ['foo', 'bar']; + const jenkinsYaml = load(readFileSync(JenkinsMainNode.BASE_JENKINS_YAML_PATH, 'utf-8')); + AuthConfig.addOidcConfigToJenkinsYaml(jenkinsYaml, 'github', admins); + const yml: any = load(readFileSync(testYaml, 'utf-8')); + const globalRoles = yml.jenkins.authorizationStrategy.roleBased.roles.global; + + const githubAuthConfig: { [x: string]: any; } = { + githubWebUri: 'https://github.com', + githubApiUri: 'https://api.github.com', + clientID: 'clientID', + clientSecret: 'clientSecret', + oauthScopes: 'read:org,user:email', + }; + + // THEN + test('Verify github config', async () => { + const addedGithubConfig = yml.jenkins.securityRealm.github; + expect(addedGithubConfig).toEqual(githubAuthConfig); + }); + + test('Verify roles', async () => { + const roleNames = globalRoles.map((role: any) => role.name); + expect(roleNames).toEqual(['admin', 'read']); + }); + + test('Verify github admins', async () => { + // Find the admin role + const adminRole = globalRoles.find((role: any) => role.name === 'admin'); + + // Check admin users + const adminUsers = adminRole.entries.map((entry: any) => entry.user); + expect(adminUsers).toEqual(['bar', 'foo']); + }); + + test('Verify read only', async () => { + // Find the read role + const readRole = globalRoles.find((role: any) => role.name === 'read'); + expect(readRole).toBeTruthy(); + + // Check read users + const readUsers = readRole.entries.map((entry: any) => entry.user); + expect(readUsers).toEqual(['anonymous']); + }); +});