-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: add template schema validation github action (#4)
- Loading branch information
1 parent
d5ff145
commit 74d76f3
Showing
6 changed files
with
371 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
name: Templates Validation | ||
|
||
on: | ||
pull_request: | ||
types: | ||
- opened | ||
- synchronize | ||
|
||
jobs: | ||
install-cache: | ||
runs-on: ubuntu-latest | ||
name: Install & Cache modules | ||
steps: | ||
- uses: actions/checkout@v3 | ||
- name: Cache node modules | ||
uses: actions/cache@v3 | ||
env: | ||
cache-name: cache-node-modules | ||
with: | ||
path: | | ||
node_modules | ||
key: ${{ runner.os }}-${{ hashFiles('**/package-lock.json') }} | ||
restore-keys: | | ||
${{ runner.os }}-npm- | ||
- uses: actions/setup-node@v3 | ||
with: | ||
node-version: '18.x' | ||
always-auth: true | ||
- name: Install dependencies | ||
if: steps.cache-dependencies.outputs.cache-hit != true | ||
run: npm ci | ||
|
||
lint: | ||
needs: install-cache | ||
name: Lint | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v3 | ||
with: | ||
fetch-depth: 0 | ||
- name: Use node.js | ||
uses: actions/setup-node@v3 | ||
with: | ||
node-version: '18' | ||
- name: Restore Cached Dependencies | ||
uses: actions/cache@v3 | ||
id: cache-dependencies | ||
with: | ||
path: | | ||
node_modules | ||
key: ${{ runner.os }}-${{ hashFiles('**/package-lock.json') }} | ||
restore-keys: | | ||
${{ runner.os }}-npm- | ||
- name: Lint Repo | ||
run: npm run pretty:check:templates | ||
|
||
validate: | ||
needs: lint | ||
name: Validate Schema | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- name: Check Out Repository | ||
uses: actions/checkout@v4 | ||
|
||
- name: Set Up Node.js | ||
uses: actions/setup-node@v3 | ||
with: | ||
node-version: 18 | ||
|
||
- name: Restore Cached Dependencies | ||
uses: actions/cache@v3 | ||
id: cache-dependencies | ||
with: | ||
path: | | ||
node_modules | ||
key: ${{ runner.os }}-${{ hashFiles('**/package-lock.json') }} | ||
restore-keys: | | ||
${{ runner.os }}-npm- | ||
- name: Validate Templates | ||
run: npm run validate:templates |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
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,25 @@ | ||
{ | ||
"name": "opensource-marketplace", | ||
"version": "0.0.1", | ||
"description": "A collection 3rd-party code that's used to manage the open source marketplace contributions.", | ||
"scripts": { | ||
"pretty:check:templates": "prettier --check ./templates", | ||
"validate:templates": "node ./scripts/templates/validate-templates.js" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/auth0/opensource-marketplace.git" | ||
}, | ||
"author": "", | ||
"license": "Apache-2.0", | ||
"bugs": { | ||
"url": "https://github.com/auth0/opensource-marketplace/issues" | ||
}, | ||
"homepage": "https://github.com/auth0/opensource-marketplace#readme", | ||
"devDependencies": { | ||
"js-yaml": "^4.1.0", | ||
"prettier": "^3.0.3", | ||
"zod": "^3.22.4", | ||
"zod-validation-error": "^2.1.0" | ||
} | ||
} |
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,140 @@ | ||
const yamlParser = require('js-yaml'); | ||
const fs = require('fs'); | ||
const path = require('path'); | ||
const { z } = require('zod'); | ||
const { fromZodError } = require('zod-validation-error'); | ||
|
||
// Changes here must be reflected here: | ||
// https://github.com/auth0/managed-marketplace/blob/main/prisma/schema.prisma#L198 | ||
const IntegrationTrigger = [ | ||
'POST_LOGIN', | ||
'CREDENTIALS_EXCHANGE', | ||
'PRE_USER_REGISTRATION', | ||
'POST_USER_REGISTRATION', | ||
'POST_CHANGE_PASSWORD', | ||
'SEND_PHONE_MESSAGE', | ||
'IGA_APPROVAL', | ||
'IGA_CERTIFICATION', | ||
'IGA_FULFILLMENT_ASSIGNMENT', | ||
'IGA_FULFILLMENT_EXECUTION', | ||
'PASSWORD_RESET_POST_CHALLENGE', | ||
]; | ||
|
||
const UseCase = [ | ||
'MULTIFACTOR', | ||
'ACTION_FEATURE', | ||
'ENRICH_PROFILE', | ||
'ACCESS_CONTROL', | ||
]; | ||
|
||
const configValue = z.object({ | ||
label: z.string().min(2), | ||
defaultValue: z.string().min(2), | ||
}); | ||
const moduleValue = z.object({ | ||
name: z.string().min(2), | ||
version: z.string().min(2), | ||
}); | ||
|
||
const TemplateSchema = z | ||
.object({ | ||
id: z.string().uuid(), | ||
name: z.string().min(3), | ||
triggers: z.array(z.enum(IntegrationTrigger)), | ||
useCases: z.array(z.enum(UseCase)), | ||
public: z.boolean().optional(), | ||
published: z.boolean().optional(), | ||
deleted: z.boolean().optional(), | ||
description: z.string().min(3), | ||
version: z.string().optional(), | ||
runtime: z.string().optional(), | ||
secrets: z.array(configValue).optional(), | ||
config: z.array(configValue).optional(), | ||
sourceUrl: z.string().url(), | ||
code: z.string().min(3), | ||
modules: z.array(moduleValue).optional(), | ||
notes: z.string().optional(), | ||
}) | ||
.strict(); | ||
|
||
function templateDirs() { | ||
const dir = path.normalize(`${__dirname}/../../templates`); | ||
|
||
// Read the contents of the directory | ||
const items = fs.readdirSync(dir); | ||
|
||
// Filter out only directories (folders) | ||
return items | ||
.map((item) => `${dir}/${item}`) | ||
.filter((item) => { | ||
return fs.statSync(item).isDirectory(); | ||
}); | ||
} | ||
|
||
const templateToJSON = async (templateDir) => { | ||
const yaml = yamlParser.load( | ||
fs.readFileSync(`${templateDir}/manifest.yaml`, 'utf8') | ||
); | ||
|
||
const code = fs.readFileSync(`${templateDir}/code.js`, 'utf8'); | ||
|
||
return { | ||
...yaml, | ||
code, | ||
}; | ||
}; | ||
|
||
const validateTemplates = async () => { | ||
console.log('\n🗄️ Validating schema for all templates.\n'); | ||
try { | ||
// GET ALL TEMPLATES | ||
let templates; | ||
try { | ||
templates = templateDirs(); | ||
} catch (e) { | ||
throw { | ||
detail: 'failed to load templates', | ||
err: e, | ||
}; | ||
} | ||
|
||
// BUNDLE INTO JSON | ||
for (const templatePath of templates) { | ||
console.log('🗄️ Validating template:', templatePath); | ||
|
||
let template; | ||
try { | ||
template = await templateToJSON(templatePath); | ||
} catch (e) { | ||
throw { | ||
detail: `failed to load template: ${templatePath}`, | ||
err: e, | ||
}; | ||
} | ||
|
||
// VALIDATE JSON | ||
try { | ||
TemplateSchema.parse(template); | ||
} catch (e) { | ||
throw { | ||
detail: `template validation failed, template: ${templatePath}`, | ||
err: fromZodError(e), | ||
}; | ||
} | ||
} | ||
} catch (e) { | ||
console.error( | ||
'⛔️ - There was an error validatong templates:', | ||
e.detail, | ||
'\n\n', | ||
e.err | ||
); | ||
process.exit(1); | ||
} | ||
|
||
console.log('\n✅ Validation complete.\n'); | ||
}; | ||
|
||
(async function () { | ||
await validateTemplates(); | ||
})(); |
36 changes: 36 additions & 0 deletions
36
templates/active-directory-groups-PASSWORD_RESET_POST_CHALLENGE/code.js
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,36 @@ | ||
/** | ||
* Handler that will be called during the execution of a Password Reset / Post Challenge Flow. | ||
* | ||
* --- AUTH0 ACTIONS TEMPLATE https://github.com/auth0/os-marketplace/blob/main/templates/active-directory-groups-PASSWORD_RESET_POST_CHALLENGE --- | ||
* | ||
* @param {Event} event - Details about the post challenge request. | ||
* @param {PasswordResetPostChallengeAPI} api - Interface whose methods can be used to change the behavior of the post challenge flow. | ||
*/ | ||
exports.onExecutePostChallenge = async (event, api) => { | ||
// ensure that the allowed group is configured | ||
const groupAllowed = event.secrets.ALLOWED_GROUP; | ||
if (!groupAllowed) { | ||
return api.access.deny('Invalid configuration'); | ||
} | ||
|
||
// get the users groups | ||
let groups = event.user.groups || []; | ||
if (!Array.isArray(groups)) { | ||
groups = [groups]; | ||
} | ||
|
||
// if the allowed group is not one of the users, deny access | ||
if (!groups.includes(groupAllowed)) { | ||
return api.access.deny('Access denied'); | ||
} | ||
}; | ||
|
||
/** | ||
* Handler that will be invoked when this action is resuming after an external redirect. If your | ||
* onExecutePostChallenge function does not perform a redirect, this function can be safely ignored. | ||
* | ||
* @param {Event} event - Details about the user and the context in which they are logging in. | ||
* @param {PasswordResetPostChallengeAPI} api - Interface whose methods can be used to change the behavior of the post challenge flow. | ||
*/ | ||
// exports.onContinuePostChallenge = async (event, api) => { | ||
// }; |
15 changes: 15 additions & 0 deletions
15
templates/active-directory-groups-PASSWORD_RESET_POST_CHALLENGE/manifest.yaml
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,15 @@ | ||
id: 'c9fa1544-b8bd-4211-950e-3c6ba2a946f4' | ||
name: 'Check if a user belongs to an active directory group.' | ||
description: 'Check if a user belongs to an AD group and if not, deny access.' | ||
public: true | ||
triggers: | ||
- 'PASSWORD_RESET_POST_CHALLENGE' | ||
runtime: 'node18' | ||
modules: [] | ||
sourceUrl: 'https://github.com/auth0/os-marketplace/blob/main/templates/active-directory-groups-PASSWORD_RESET_POST_CHALLENGE' | ||
notes: | | ||
**Secrets** | ||
* `ALLOWED_GROUP` - the name of the allowed group. | ||
useCases: | ||
- 'ACCESS_CONTROL' |