diff --git a/authentik/api/v2/urls.py b/authentik/api/v2/urls.py index fea8a58c6..a3fbf390b 100644 --- a/authentik/api/v2/urls.py +++ b/authentik/api/v2/urls.py @@ -195,17 +195,21 @@ info = openapi.Info( ) SchemaView = get_schema_view(info, public=True, permission_classes=(AllowAny,)) -urlpatterns = [ - path("", SwaggerView.as_view(), name="swagger"), -] + router.urls + [ - path( - "flows/executor//", - FlowExecutorView.as_view(), - name="flow-executor", - ), - re_path( - r"^swagger(?P\.json|\.yaml)$", - SchemaView.without_ui(cache_timeout=0), - name="schema-json", - ), -] +urlpatterns = ( + [ + path("", SwaggerView.as_view(), name="swagger"), + ] + + router.urls + + [ + path( + "flows/executor//", + FlowExecutorView.as_view(), + name="flow-executor", + ), + re_path( + r"^swagger(?P\.json|\.yaml)$", + SchemaView.without_ui(cache_timeout=0), + name="schema-json", + ), + ] +) diff --git a/website/docs/development/api.md b/website/docs/development/api.md new file mode 100644 index 000000000..6255991db --- /dev/null +++ b/website/docs/development/api.md @@ -0,0 +1,11 @@ +--- +title: API +--- + +Starting with 2021.3.5, every authentik instance has a built-in API browser, which can be accessed at https://authentik.company/api/v2beta/. + +To generate an API client, you can use the Swagger schema at https://authentik.company/api/v2beta/swagger.json. + +While testing, the API requests are authenticated by your browser session. To send an API request from outside the browser, you need to set an `Authorization` header. + +The value needs to be set to the base64-encoded token key. diff --git a/website/docs/development/local-dev-environment.md b/website/docs/development/local-dev-environment.md index a4c85fb80..ca2770605 100644 --- a/website/docs/development/local-dev-environment.md +++ b/website/docs/development/local-dev-environment.md @@ -31,6 +31,20 @@ Most functions and classes have type-hints and docstrings, so it is recommended By default, no transpiled bundle of the frontend is included. To build the UI, you need Node 12 or newer. +The Frontend also uses a generated API client to talk with the backend. To generate this client, you can use the [openapitools/openapi-generator-cli](https://github.com/OpenAPITools/openapi-generator) CLI tool. + +If you want to generate the client without installing anything, run this command: + +```shell +docker run \ + --rm -v $(pwd):/local \ + openapitools/openapi-generator-cli generate \ + -i /local/swagger.yaml \ + -g typescript-fetch \ + -o /local/web/api \ + --additional-properties=typescriptThreePlus=true,supportsES6=true,npmName=authentik-api,npmVersion=1.0.0 +``` + To build the UI, run these commands: ``` diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js index 9fb2cb974..4daf541ad 100644 --- a/website/docusaurus.config.js +++ b/website/docusaurus.config.js @@ -65,8 +65,7 @@ module.exports = { { docs: { sidebarPath: require.resolve("./sidebars.js"), - editUrl: - "https://github.com/beryju/authentik/edit/master/website/", + editUrl: "https://github.com/beryju/authentik/edit/master/website/", }, theme: { customCss: require.resolve("./src/css/custom.css"), diff --git a/website/package-lock.json b/website/package-lock.json index e18d1a5fa..040a7b870 100644 --- a/website/package-lock.json +++ b/website/package-lock.json @@ -7609,6 +7609,15 @@ "resolved": "https://registry.npmjs.org/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz", "integrity": "sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ==" }, + "feather-icons": { + "version": "4.28.0", + "resolved": "https://registry.npmjs.org/feather-icons/-/feather-icons-4.28.0.tgz", + "integrity": "sha512-gRdqKESXRBUZn6Nl0VBq2wPHKRJgZz7yblrrc2lYsS6odkNFDnA4bqvrlEVRUPjE1tFax+0TdbJKZ31ziJuzjg==", + "requires": { + "classnames": "^2.2.5", + "core-js": "^3.1.3" + } + }, "feed": { "version": "4.2.2", "resolved": "https://registry.npmjs.org/feed/-/feed-4.2.2.tgz", @@ -14843,6 +14852,14 @@ "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz", "integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==" }, + "react-feather": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/react-feather/-/react-feather-2.0.9.tgz", + "integrity": "sha512-yMfCGRkZdXwIs23Zw/zIWCJO3m3tlaUvtHiXlW+3FH7cIT6fiK1iJ7RJWugXq7Fso8ZaQyUm92/GOOHXvkiVUw==", + "requires": { + "prop-types": "^15.7.2" + } + }, "react-helmet": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/react-helmet/-/react-helmet-6.1.0.tgz", diff --git a/website/package.json b/website/package.json index b772c824e..204db0380 100644 --- a/website/package.json +++ b/website/package.json @@ -18,7 +18,8 @@ "postcss": "^8.2.8", "react": "^17.0.1", "react-before-after-slider": "^1.0.4", - "react-dom": "^17.0.1" + "react-dom": "^17.0.1", + "react-feather": "^2.0.9" }, "browserslist": { "production": [ diff --git a/website/sidebars.js b/website/sidebars.js index 7d70df6d3..1198838d1 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -162,7 +162,10 @@ module.exports = { { type: "category", label: "Development", - items: ["development/local-dev-environment"], + items: [ + "development/local-dev-environment", + "development/api" + ], }, ], }; diff --git a/website/src/comparison.jsx b/website/src/comparison.jsx new file mode 100644 index 000000000..bf29b935d --- /dev/null +++ b/website/src/comparison.jsx @@ -0,0 +1,149 @@ +import React from "react"; +import { Check, X, AlertTriangle } from "react-feather"; + +function Comparison() { + return ( +
+
+

Why authentik?

+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
authentikKeycloakMicrosoft ADFSMicrosoft Azure ADOktaDuo
Protocol Support
SAML2
OAuth2 and OIDC
Use-cases
Authentication
Enrollment
Self-service
Features
MFA
Conditional Access
Open-source
Application Proxy
+
+
+
+ ); +} + +export default Comparison; diff --git a/website/src/css/custom.css b/website/src/css/custom.css index a4c288aa8..60748373b 100644 --- a/website/src/css/custom.css +++ b/website/src/css/custom.css @@ -35,3 +35,153 @@ .hero_image > img { max-height: 200px; } + + +table { + display: table; +} + +.table-responsive { + overflow-x: auto; +} +/** +* comparison +* +* Comparison table used in both the performance and correctness tables. +*/ + +table.comparison { + width: 100%; +} + +table.comparison [title], +table.comparison [title] { + text-decoration: underline; + text-decoration-style: dotted; +} + +table.comparison th, +table.comparison td, +table.comparison tr { + border: 0px none; + white-space: nowrap; +} + +table.comparison th { + padding-left: 0; + padding-right: 0; +} + +table.comparison tr th.authentik { + color: var(--ifm-color-primary); +} + +table.comparison thead.group tr { + border-bottom: 1px; + border-bottom-color: var(--ifm-table-head-color); + border-bottom-style: solid; +} + +table.comparison thead.group th:first-child { + text-align: left; + font-weight: 800; +} + +table.comparison tr td { + border-left: 10px solid transparent; + min-width: 90px; + text-align: center; +} + +table.comparison tr td:first-child { + font-weight: bold; + padding-left: 0; + text-align: left; + white-space: nowrap; + width: 25%; +} + +table.comparison tr td.description { + font-weight: normal; + min-width: 250px; + padding-top: 0; + vertical-align: top; + white-space: normal; +} + +table.comparison tr td.description .label { + color: var(--ifm-heading-color); + font-weight: bold; +} + +table.comparison tr td.description .text { + color: var(--ifm-color-emphasis-600); +} + +table.comparison tr td.description .links { + font-size: 0.9em; + margin-top: var(--ifm-spacing-vertical); +} + +table.comparison tr td.result { + background-color: var(--ifm-panel-background-color); +} + +table.comparison tr td.result.failed { + color: var(--ifm-color-danger); +} + +table.comparison tr td.result.lost { + background: var(--ifm-color-emphasis-1000); + color: transparent; +} + +table.comparison tr td.result.not-applicable { + background: var(--ifm-color-emphasis-1000); + color: rgba(var(--ifm-background-color-rgb), 0.5); +} + +table.comparison tr td.result.passed { + color: var(--ifm-color-success); +} + +table.comparison tr td.result.warning { + color: var(--ifm-color-warning); +} + +table.comparison tr td.result.passed.authentik { + background: var(--ifm-color-primary); + color: var(--ifm-background-color); +} + +table.comparison tr td.bar { + padding: 0; + vertical-align: bottom; +} + +table.comparison tr td.bar .place { + font-size: 0.9em; +} + +table.comparison tr td.bar .measurement { + font-weight: bold; +} + +table.comparison tr td.bar .bar { + background: var(--ifm-color-emphasis-1000); + margin: 0 auto; +} + +table.comparison tr td.bar.authentik { + color: var(--ifm-color-primary); +} + +table.comparison tr td.bar.authentik .bar { + background: var(--ifm-color-primary); +} + +@media (max-width: 996px) { + table.comparison td.description { + display: none; + } +} diff --git a/website/src/pages/index.jsx b/website/src/pages/index.jsx index c4d05813b..a47b74063 100644 --- a/website/src/pages/index.jsx +++ b/website/src/pages/index.jsx @@ -6,6 +6,7 @@ import useDocusaurusContext from "@docusaurus/useDocusaurusContext"; import useBaseUrl from "@docusaurus/useBaseUrl"; import styles from "./styles.module.css"; import BeforeAfterSlider from 'react-before-after-slider' +import Comparison from "../comparison"; const features = [ { @@ -150,6 +151,9 @@ function Home() { +
+ +
);