core: Tidy contributor onboarding, fix typos. (#12700)

core: Tidy contributor onboarding.

- Fixes typos.
- Fixes stale links.
- Tidies Makefile so that Poetry env is optional for hygiene commands.
- Remove mismatched YAML naming.
- Uses shebang on Python scripts.
- Document semver usage.
- Redirect OpenAPI schema.

Signed-off-by: Teffen Ellis <592134+GirlBossRush@users.noreply.github.com>
This commit is contained in:
Teffen Ellis
2025-03-06 19:34:54 +01:00
committed by GitHub
parent 71344d0b6a
commit cf58c5617a
18 changed files with 113 additions and 87 deletions

View File

@ -1,7 +1,32 @@
akadmin
asgi
assertIn
authentik
authn
crate
docstrings
entra
goauthentik
gunicorn
hass
jwe
jwks
keypair keypair
keypairs keypairs
hass kubernetes
warmup oidc
ontext ontext
openid
passwordless
plex
saml
scim
singed singed
assertIn slo
sso
totp
traefik
# https://github.com/codespell-project/codespell/issues/1224
upToDate
warmup
webauthn

22
.vscode/settings.json vendored
View File

@ -1,26 +1,4 @@
{ {
"cSpell.words": [
"akadmin",
"asgi",
"authentik",
"authn",
"entra",
"goauthentik",
"jwe",
"jwks",
"kubernetes",
"oidc",
"openid",
"passwordless",
"plex",
"saml",
"scim",
"slo",
"sso",
"totp",
"traefik",
"webauthn"
],
"todo-tree.tree.showCountsInTree": true, "todo-tree.tree.showCountsInTree": true,
"todo-tree.tree.showBadges": true, "todo-tree.tree.showBadges": true,
"yaml.customTags": [ "yaml.customTags": [

View File

@ -4,34 +4,17 @@
PWD = $(shell pwd) PWD = $(shell pwd)
UID = $(shell id -u) UID = $(shell id -u)
GID = $(shell id -g) GID = $(shell id -g)
NPM_VERSION = $(shell python -m scripts.npm_version) NPM_VERSION = $(shell poetry run python -m scripts.generate_semver)
PY_SOURCES = authentik tests scripts lifecycle .github PY_SOURCES = authentik tests scripts lifecycle .github
GO_SOURCES = cmd internal
WEB_SOURCES = web/src web/packages
DOCKER_IMAGE ?= "authentik:test" DOCKER_IMAGE ?= "authentik:test"
GEN_API_TS = "gen-ts-api" GEN_API_TS = "gen-ts-api"
GEN_API_PY = "gen-py-api" GEN_API_PY = "gen-py-api"
GEN_API_GO = "gen-go-api" GEN_API_GO = "gen-go-api"
pg_user := $(shell python -m authentik.lib.config postgresql.user 2>/dev/null) pg_user := $(shell poetry run python -m authentik.lib.config postgresql.user 2>/dev/null)
pg_host := $(shell python -m authentik.lib.config postgresql.host 2>/dev/null) pg_host := $(shell poetry run python -m authentik.lib.config postgresql.host 2>/dev/null)
pg_name := $(shell python -m authentik.lib.config postgresql.name 2>/dev/null) pg_name := $(shell poetry run python -m authentik.lib.config postgresql.name 2>/dev/null)
CODESPELL_ARGS = -D - -D .github/codespell-dictionary.txt \
-I .github/codespell-words.txt \
-S 'web/src/locales/**' \
-S 'website/docs/developer-docs/api/reference/**' \
-S '**/node_modules/**' \
-S '**/dist/**' \
$(PY_SOURCES) \
$(GO_SOURCES) \
$(WEB_SOURCES) \
website/src \
website/blog \
website/docs \
website/integrations \
website/src
all: lint-fix lint test gen web ## Lint, build, and test everything all: lint-fix lint test gen web ## Lint, build, and test everything
@ -49,26 +32,26 @@ go-test:
go test -timeout 0 -v -race -cover ./... go test -timeout 0 -v -race -cover ./...
test: ## Run the server tests and produce a coverage report (locally) test: ## Run the server tests and produce a coverage report (locally)
coverage run manage.py test --keepdb authentik poetry run coverage run manage.py test --keepdb authentik
coverage html poetry run coverage html
coverage report poetry run coverage report
lint-fix: lint-codespell ## Lint and automatically fix errors in the python source code. Reports spelling errors. lint-fix: lint-codespell ## Lint and automatically fix errors in the python source code. Reports spelling errors.
black $(PY_SOURCES) poetry run black $(PY_SOURCES)
ruff check --fix $(PY_SOURCES) poetry run ruff check --fix $(PY_SOURCES)
lint-codespell: ## Reports spelling errors. lint-codespell: ## Reports spelling errors.
codespell -w $(CODESPELL_ARGS) poetry run codespell -w
lint: ## Lint the python and golang sources lint: ## Lint the python and golang sources
bandit -r $(PY_SOURCES) -x web/node_modules -x tests/wdio/node_modules -x website/node_modules poetry run bandit -c pyproject.toml -r $(PY_SOURCES)
golangci-lint run -v golangci-lint run -v
core-install: core-install:
poetry install poetry install
migrate: ## Run the Authentik Django server's migrations migrate: ## Run the Authentik Django server's migrations
python -m lifecycle.migrate poetry run python -m lifecycle.migrate
i18n-extract: core-i18n-extract web-i18n-extract ## Extract strings that require translation into files to send to a translation service i18n-extract: core-i18n-extract web-i18n-extract ## Extract strings that require translation into files to send to a translation service
@ -76,7 +59,7 @@ aws-cfn:
cd lifecycle/aws && npm run aws-cfn cd lifecycle/aws && npm run aws-cfn
core-i18n-extract: core-i18n-extract:
ak makemessages \ poetry run ak makemessages \
--add-location file \ --add-location file \
--no-obsolete \ --no-obsolete \
--ignore web \ --ignore web \
@ -107,11 +90,11 @@ gen-build: ## Extract the schema from the database
AUTHENTIK_DEBUG=true \ AUTHENTIK_DEBUG=true \
AUTHENTIK_TENANTS__ENABLED=true \ AUTHENTIK_TENANTS__ENABLED=true \
AUTHENTIK_OUTPOSTS__DISABLE_EMBEDDED_OUTPOST=true \ AUTHENTIK_OUTPOSTS__DISABLE_EMBEDDED_OUTPOST=true \
ak make_blueprint_schema > blueprints/schema.json poetry run ak make_blueprint_schema > blueprints/schema.json
AUTHENTIK_DEBUG=true \ AUTHENTIK_DEBUG=true \
AUTHENTIK_TENANTS__ENABLED=true \ AUTHENTIK_TENANTS__ENABLED=true \
AUTHENTIK_OUTPOSTS__DISABLE_EMBEDDED_OUTPOST=true \ AUTHENTIK_OUTPOSTS__DISABLE_EMBEDDED_OUTPOST=true \
ak spectacular --file schema.yml poetry run ak spectacular --file schema.yml
gen-changelog: ## (Release) generate the changelog based from the commits since the last tag gen-changelog: ## (Release) generate the changelog based from the commits since the last tag
git log --pretty=format:" - %s" $(shell git describe --tags $(shell git rev-list --tags --max-count=1))...$(shell git branch --show-current) | sort > changelog.md git log --pretty=format:" - %s" $(shell git describe --tags $(shell git rev-list --tags --max-count=1))...$(shell git branch --show-current) | sort > changelog.md
@ -190,7 +173,7 @@ gen-client-go: gen-clean-go ## Build and install the authentik API for Golang
rm -rf ./${GEN_API_GO}/config.yaml ./${GEN_API_GO}/templates/ rm -rf ./${GEN_API_GO}/config.yaml ./${GEN_API_GO}/templates/
gen-dev-config: ## Generate a local development config file gen-dev-config: ## Generate a local development config file
python -m scripts.generate_config poetry run scripts/generate_config.py
gen: gen-build gen-client-ts gen: gen-build gen-client-ts
@ -271,21 +254,21 @@ ci--meta-debug:
node --version node --version
ci-black: ci--meta-debug ci-black: ci--meta-debug
black --check $(PY_SOURCES) poetry run black --check $(PY_SOURCES)
ci-ruff: ci--meta-debug ci-ruff: ci--meta-debug
ruff check $(PY_SOURCES) poetry run ruff check $(PY_SOURCES)
ci-codespell: ci--meta-debug ci-codespell: ci--meta-debug
codespell $(CODESPELL_ARGS) -s poetry run codespell -s
ci-bandit: ci--meta-debug ci-bandit: ci--meta-debug
bandit -r $(PY_SOURCES) poetry run bandit -r $(PY_SOURCES)
ci-pending-migrations: ci--meta-debug ci-pending-migrations: ci--meta-debug
ak makemigrations --check poetry run ak makemigrations --check
ci-test: ci--meta-debug ci-test: ci--meta-debug
coverage run manage.py test --keepdb --randomly-seed ${CI_TEST_SEED} authentik poetry run coverage run manage.py test --keepdb --randomly-seed ${CI_TEST_SEED} authentik
coverage report poetry run coverage report
coverage xml poetry run coverage xml

View File

@ -2,7 +2,7 @@ authentik takes security very seriously. We follow the rules of [responsible di
## Independent audits and pentests ## Independent audits and pentests
We are committed to engaging in regular pentesting and security audits of authentik. Defining and adhering to a cadence of external testing ensures a stronger probability that our code base, our features, and our architecture is as secure and non-exploitable as possible. For more details about specfic audits and pentests, refer to "Audits and Certificates" in our [Security documentation](https://docs.goauthentik.io/docs/security). We are committed to engaging in regular pentesting and security audits of authentik. Defining and adhering to a cadence of external testing ensures a stronger probability that our code base, our features, and our architecture is as secure and non-exploitable as possible. For more details about specific audits and pentests, refer to "Audits and Certificates" in our [Security documentation](https://docs.goauthentik.io/docs/security).
## What authentik classifies as a CVE ## What authentik classifies as a CVE

View File

@ -63,7 +63,9 @@ def wait_for_db():
# Sanity check, ensure SECRET_KEY is set before we even check for database connectivity # Sanity check, ensure SECRET_KEY is set before we even check for database connectivity
if CONFIG.get("secret_key") is None or len(CONFIG.get("secret_key")) == 0: if CONFIG.get("secret_key") is None or len(CONFIG.get("secret_key")) == 0:
CONFIG.log("info", "----------------------------------------------------------------------") CONFIG.log("info", "----------------------------------------------------------------------")
CONFIG.log("info", "Secret key missing, check https://goauthentik.io/docs/installation/.") CONFIG.log(
"info", "Secret key missing, check https://docs.goauthentik.io/docs/install-config/"
)
CONFIG.log("info", "----------------------------------------------------------------------") CONFIG.log("info", "----------------------------------------------------------------------")
sysexit(1) sysexit(1)
check_postgres() check_postgres()

View File

@ -4,6 +4,27 @@ version = "2025.2.1"
description = "" description = ""
authors = ["authentik Team <hello@goauthentik.io>"] authors = ["authentik Team <hello@goauthentik.io>"]
[tool.bandit]
exclude_dirs = ["**/node_modules/**"]
[tool.codespell]
skip = [
"**/node_modules",
"**/package-lock.json",
"schema.yml",
"unittest.xml",
"./blueprints/schema.json",
"go.sum",
"locale",
"**/dist",
"**/web/src/locales",
"**/web/xliff",
"./website/build",
"./gen-ts-api",
"*.api.mdx",
]
dictionary = ".github/codespell-dictionary.txt,-"
ignore-words = ".github/codespell-words.txt"
[tool.black] [tool.black]
line-length = 100 line-length = 100
target-version = ['py312'] target-version = ['py312']
@ -123,7 +144,9 @@ kubernetes = "*"
ldap3 = "*" ldap3 = "*"
lxml = "*" lxml = "*"
msgraph-sdk = "*" msgraph-sdk = "*"
opencontainers = { git = "https://github.com/vsoch/oci-python", rev = "20d69d9cc50a0fef31605b46f06da0c94f1ec3cf", extras = ["reggie"] } opencontainers = { git = "https://github.com/vsoch/oci-python", rev = "20d69d9cc50a0fef31605b46f06da0c94f1ec3cf", extras = [
"reggie",
] }
packaging = "*" packaging = "*"
paramiko = "*" paramiko = "*"
psycopg = { extras = ["c"], version = "*" } psycopg = { extras = ["c"], version = "*" }

1
scripts/generate_config.py Normal file → Executable file
View File

@ -1,3 +1,4 @@
#!/usr/bin/env python3
"""Generate config for development""" """Generate config for development"""
from yaml import safe_dump from yaml import safe_dump

15
scripts/generate_semver.py Executable file
View File

@ -0,0 +1,15 @@
#!/usr/bin/env python3
"""
Generates a Semantic Versioning identifier, suffixed with a timestamp.
"""
from time import time
from authentik import __version__ as package_version
"""
See: https://semver.org/#spec-item-9 (Pre-release spec)
"""
pre_release_timestamp = int(time())
print(f"{package_version}-{pre_release_timestamp}")

View File

@ -1,7 +0,0 @@
"""Helper script to generate an NPM Version"""
from time import time
from authentik import __version__
print(f"{__version__}-{int(time())}")

View File

@ -328,7 +328,7 @@ export class ApplicationWizardSubmitStep extends CustomEmitterElement(Applicatio
if (!(this.wizard && app && provider)) { if (!(this.wizard && app && provider)) {
throw new Error("Submit step received uninitialized wizard context"); throw new Error("Submit step received uninitialized wizard context");
} }
// An empty object is truthy, an empty array is falsey. *WAT Javascript*. // An empty object is truthy, an empty array is falsey. *WAT JavaScript*.
const keys = Object.keys(this.wizard.errors); const keys = Object.keys(this.wizard.errors);
return match([this.state, keys]) return match([this.state, keys])
.with(["submitted", P._], () => .with(["submitted", P._], () =>

2
website/.gitignore vendored
View File

@ -24,5 +24,5 @@ yarn-debug.log*
yarn-error.log* yarn-error.log*
static/docker-compose.yml static/docker-compose.yml
static/schema.yaml static/schema.yml
docs/developer-docs/api/reference/** docs/developer-docs/api/reference/**

View File

@ -132,7 +132,7 @@ make web # Formats the frontend code
Now that the backend and frontend have been setup and built, you can start authentik by running the following command in the same directory as your local authentik git repository: Now that the backend and frontend have been setup and built, you can start authentik by running the following command in the same directory as your local authentik git repository:
```shell ```shell
ak server # Starts authentik server poetry run ak server # Starts authentik server
``` ```
And now, authentik should now be accessible at `http://localhost:9000`. And now, authentik should now be accessible at `http://localhost:9000`.

View File

@ -23,7 +23,7 @@ kubectl exec -it deployment/authentik-worker -c worker -- ak create_recovery_key
or, for CLI, run or, for CLI, run
```shell ```shell
ak create_recovery_key 10 akadmin poetry run ak create_recovery_key 10 akadmin
``` ```
This will output a link, that can be used to instantly gain access to authentik as the user specified above. The link is valid for amount of years specified above, in this case, 10 years. This will output a link, that can be used to instantly gain access to authentik as the user specified above. The link is valid for amount of years specified above, in this case, 10 years.

View File

@ -152,7 +152,7 @@ const createConfig = (): Config => {
docsPluginId: "docs", docsPluginId: "docs",
config: { config: {
authentik: { authentik: {
specPath: "static/schema.yaml", specPath: "static/schema.yml",
outputDir: "docs/developer-docs/api/reference/", outputDir: "docs/developer-docs/api/reference/",
hideSendButton: true, hideSendButton: true,
sidebarOptions: { sidebarOptions: {

View File

@ -10,7 +10,7 @@ These instructions apply to all projects in the Frappe Family.
## What is Frappe ## What is Frappe
> Frappe is a full stack, batteries-included, web framework written in Python and Javascript. > Frappe is a full stack, batteries-included, web framework written in Python and JavaScript.
> >
> -- https://frappe.io/ > -- https://frappe.io/

View File

@ -1002,6 +1002,12 @@
status = 302 status = 302
force = true force = true
[[redirects]]
from = "/schema.yaml"
to = "/schema.yml"
status = 302
force = true
[[redirects]] [[redirects]]
from = "/developer-docs/api/api" from = "/developer-docs/api/api"
to = "/docs/developer-docs/api/api" to = "/docs/developer-docs/api/api"

View File

@ -4,8 +4,8 @@
"private": true, "private": true,
"license": "MIT", "license": "MIT",
"scripts": { "scripts": {
"build": "cp ../docker-compose.yml static/docker-compose.yml && cp ../schema.yml static/schema.yaml && docusaurus gen-api-docs all && cross-env NODE_OPTIONS='--max_old_space_size=65536' docusaurus build", "build": "cp ../docker-compose.yml static/docker-compose.yml && cp ../schema.yml static/schema.yml && docusaurus gen-api-docs all && cross-env NODE_OPTIONS='--max_old_space_size=65536' docusaurus build",
"build-bundled": "cp ../schema.yml static/schema.yaml && docusaurus gen-api-docs all && cross-env NODE_OPTIONS='--max_old_space_size=65536' docusaurus build", "build-bundled": "cp ../schema.yml static/schema.yml && docusaurus gen-api-docs all && cross-env NODE_OPTIONS='--max_old_space_size=65536' docusaurus build",
"deploy": "docusaurus deploy", "deploy": "docusaurus deploy",
"docusaurus": "docusaurus", "docusaurus": "docusaurus",
"lint:lockfile": "wireit", "lint:lockfile": "wireit",

View File

@ -124,7 +124,7 @@ fn replace_links(migrate_path: PathBuf, moves: Vec<(PathBuf, PathBuf)>) {
r#move.1.display(), r#move.1.display(),
tmp_file tmp_file
)); ));
// delete file if it didnt already exist // delete file if it didn't already exist
if let Ok(_) = tmp_file { if let Ok(_) = tmp_file {
let _ = remove_file(&r#move.1); let _ = remove_file(&r#move.1);
}; };
@ -223,7 +223,7 @@ fn replace_links(migrate_path: PathBuf, moves: Vec<(PathBuf, PathBuf)>) {
); );
continue; continue;
}; };
// delete file if it didnt already exist // delete file if it didn't already exist
//if let Ok(_) = tmp_file { //if let Ok(_) = tmp_file {
// let _ = remove_file(&absolute_link); // let _ = remove_file(&absolute_link);
//}; //};
@ -275,7 +275,7 @@ fn replace_links(migrate_path: PathBuf, moves: Vec<(PathBuf, PathBuf)>) {
.collect::<PathBuf>(); .collect::<PathBuf>();
let new_link = escapes.join(tmp_absolute_link.iter().collect::<PathBuf>()); let new_link = escapes.join(tmp_absolute_link.iter().collect::<PathBuf>());
// add a . to the begining if it doesnt already start with . or .. // add a . to the beginning if it doesn't already start with . or ..
let new_link = match new_link let new_link = match new_link
.components() .components()
.collect::<Vec<_>>() .collect::<Vec<_>>()