website: add comparison based on vector.dev's site

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens Langhammer 2021-03-18 22:02:04 +01:00
parent e7a8371cbb
commit fe054136b1
10 changed files with 370 additions and 18 deletions

View File

@ -195,9 +195,12 @@ info = openapi.Info(
) )
SchemaView = get_schema_view(info, public=True, permission_classes=(AllowAny,)) SchemaView = get_schema_view(info, public=True, permission_classes=(AllowAny,))
urlpatterns = [ urlpatterns = (
[
path("", SwaggerView.as_view(), name="swagger"), path("", SwaggerView.as_view(), name="swagger"),
] + router.urls + [ ]
+ router.urls
+ [
path( path(
"flows/executor/<slug:flow_slug>/", "flows/executor/<slug:flow_slug>/",
FlowExecutorView.as_view(), FlowExecutorView.as_view(),
@ -208,4 +211,5 @@ urlpatterns = [
SchemaView.without_ui(cache_timeout=0), SchemaView.without_ui(cache_timeout=0),
name="schema-json", name="schema-json",
), ),
] ]
)

View File

@ -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.

View File

@ -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. 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: To build the UI, run these commands:
``` ```

View File

@ -65,8 +65,7 @@ module.exports = {
{ {
docs: { docs: {
sidebarPath: require.resolve("./sidebars.js"), sidebarPath: require.resolve("./sidebars.js"),
editUrl: editUrl: "https://github.com/beryju/authentik/edit/master/website/",
"https://github.com/beryju/authentik/edit/master/website/",
}, },
theme: { theme: {
customCss: require.resolve("./src/css/custom.css"), customCss: require.resolve("./src/css/custom.css"),

View File

@ -7609,6 +7609,15 @@
"resolved": "https://registry.npmjs.org/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz", "resolved": "https://registry.npmjs.org/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz",
"integrity": "sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ==" "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": { "feed": {
"version": "4.2.2", "version": "4.2.2",
"resolved": "https://registry.npmjs.org/feed/-/feed-4.2.2.tgz", "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", "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz",
"integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==" "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": { "react-helmet": {
"version": "6.1.0", "version": "6.1.0",
"resolved": "https://registry.npmjs.org/react-helmet/-/react-helmet-6.1.0.tgz", "resolved": "https://registry.npmjs.org/react-helmet/-/react-helmet-6.1.0.tgz",

View File

@ -18,7 +18,8 @@
"postcss": "^8.2.8", "postcss": "^8.2.8",
"react": "^17.0.1", "react": "^17.0.1",
"react-before-after-slider": "^1.0.4", "react-before-after-slider": "^1.0.4",
"react-dom": "^17.0.1" "react-dom": "^17.0.1",
"react-feather": "^2.0.9"
}, },
"browserslist": { "browserslist": {
"production": [ "production": [

View File

@ -162,7 +162,10 @@ module.exports = {
{ {
type: "category", type: "category",
label: "Development", label: "Development",
items: ["development/local-dev-environment"], items: [
"development/local-dev-environment",
"development/api"
],
}, },
], ],
}; };

149
website/src/comparison.jsx Normal file
View File

@ -0,0 +1,149 @@
import React from "react";
import { Check, X, AlertTriangle } from "react-feather";
function Comparison() {
return (
<section className="">
<div className="container">
<h2 id="correctness">Why authentik?</h2>
<div className="table-responsive">
<table className="comparison">
<thead>
<tr>
<th></th>
<th className="authentik">authentik</th>
<th>Keycloak</th>
<th>Microsoft ADFS</th>
<th>Microsoft Azure AD</th>
<th>Okta</th>
<th>Duo</th>
</tr>
</thead>
<thead className="group">
<tr>
<th>Protocol Support</th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td className="row-label">SAML2</td>
<td className="result passed authentik"><Check></Check></td>
<td className="result passed"><Check></Check></td>
<td className="result passed"><Check></Check></td>
<td className="result passed"><Check></Check></td>
<td className="result passed"><Check></Check></td>
<td className="result passed"><Check></Check></td>
</tr>
<tr>
<td className="row-label">OAuth2 and OIDC</td>
<td className="result passed authentik"><Check></Check></td>
<td className="result passed"><Check></Check></td>
<td className="result passed"><Check></Check></td>
<td className="result passed"><Check></Check></td>
<td className="result passed"><Check></Check></td>
<td className="result passed"><Check></Check></td>
</tr>
</tbody>
<thead className="group">
<tr>
<th>Use-cases</th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td className="row-label">Authentication</td>
<td className="result passed authentik"><Check></Check></td>
<td className="result passed"><Check></Check></td>
<td className="result passed"><Check></Check></td>
<td className="result passed"><Check></Check></td>
<td className="result passed"><Check></Check></td>
<td className="result passed"><Check></Check></td>
</tr>
<tr>
<td className="row-label">Enrollment</td>
<td className="result passed authentik"><Check></Check></td>
<td className="result passed"><X></X></td>
<td className="result failed"><X></X></td>
<td className="result failed"><X></X></td>
<td className="result failed"><X></X></td>
<td className="result passed"><X></X></td>
</tr>
<tr>
<td className="row-label">Self-service</td>
<td className="result passed authentik"><Check></Check></td>
<td className="result passed"><Check></Check></td>
<td className="result passed"><Check></Check></td>
<td className="result passed"><Check></Check></td>
<td className="result passed"><Check></Check></td>
<td className="result passed"><Check></Check></td>
</tr>
</tbody>
<thead className="group">
<tr>
<th>Features</th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td className="row-label">MFA</td>
<td className="result passed authentik"><Check></Check></td>
<td className="result passed"><Check></Check></td>
<td className="result failed"><X></X></td>
<td className="result failed"><Check></Check></td>
<td className="result failed"><Check></Check></td>
<td className="result passed"><Check></Check></td>
</tr>
<tr>
<td className="row-label">Conditional Access</td>
<td className="result passed authentik"><Check></Check></td>
<td className="result passed"><Check></Check></td>
<td className="result passed"><Check></Check></td>
<td className="result warning"><AlertTriangle></AlertTriangle></td>
<td className="result passed"><Check></Check></td>
<td className="result warning"><AlertTriangle></AlertTriangle></td>
</tr>
<tr>
<td className="row-label">Open-source</td>
<td className="result passed authentik"><Check></Check></td>
<td className="result passed"><Check></Check></td>
<td className="result failed"><X></X></td>
<td className="result failed"><X></X></td>
<td className="result failed"><X></X></td>
<td className="result failed"><X></X></td>
</tr>
<tr>
<td className="row-label">Application Proxy</td>
<td className="result passed authentik"><Check></Check></td>
<td className="result warning"><AlertTriangle></AlertTriangle></td>
<td className="result warning"><AlertTriangle></AlertTriangle></td>
<td className="result failed"><X></X></td>
<td className="result failed"><X></X></td>
<td className="result failed"><X></X></td>
</tr>
</tbody>
</table>
</div>
</div>
</section>
);
}
export default Comparison;

View File

@ -35,3 +35,153 @@
.hero_image > img { .hero_image > img {
max-height: 200px; 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;
}
}

View File

@ -6,6 +6,7 @@ import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
import useBaseUrl from "@docusaurus/useBaseUrl"; import useBaseUrl from "@docusaurus/useBaseUrl";
import styles from "./styles.module.css"; import styles from "./styles.module.css";
import BeforeAfterSlider from 'react-before-after-slider' import BeforeAfterSlider from 'react-before-after-slider'
import Comparison from "../comparison";
const features = [ const features = [
{ {
@ -150,6 +151,9 @@ function Home() {
</div> </div>
</div> </div>
</section> </section>
<section>
<Comparison></Comparison>
</section>
</main> </main>
</Layout> </Layout>
); );